在機器學習專案中,將訓練程式碼佈署到短暫的基礎設施上,Python 套件和容器化是兩種常見的選擇。Python 套件易於安裝和維護,能與 Vertex Training 等平台提供的機器和框架最佳化容器良好整合。容器化則提供更高的靈活性,適用於需要自定義環境或使用特定依賴項的場景,例如舊版軟體或專有元件。選擇哪種方案取決於專案需求,效率優先則選擇 Python 套件,靈活性優先則選擇容器化。對於分散式訓練, TensorFlow 提供了 OneDeviceStrategy、MirroredStrategy、MultiWorkerMirroredStrategy 和 TPUStrategy 等策略,可根據硬體組態選擇合適的策略。文章也提供了一個利用 Python 錯誤處理機制,動態建立分佈策略的程式碼範例。
訓練程式碼的佈署:Python 套件還是容器?
在短暫的基礎設施上執行訓練程式碼時,將程式碼封裝成 Python 套件或容器化是兩種常見的方法。兩者都能實作自動化安裝和佈署,但各自有不同的優缺點。
為何選擇 Python 套件或容器?
將訓練程式碼放入 Python 套件的主要目的是為了便於在短暫的基礎設施上安裝。由於無法登入這些機器並互動式安裝軟體套件,因此需要自動化安裝訓練軟體。Python 套件提供了這種能力。
另一種捕捉依賴關係的方法是將訓練程式碼容器化。容器是一個輕量級的軟體包,包含了執行應用程式所需的一切,除了 Python 程式碼外,還包括 Python 安裝本身、所需的系統工具和系統函式庫,以及所有設定(如組態檔案、身份驗證金鑰和環境變數)。
由於 Vertex Training 接受 Python 模組和容器映像,因此可以透過構建包含訓練程式碼以及所需 Python 和 TensorFlow 版本的容器映像來捕捉 Python 和 TensorFlow 的依賴關係。在容器中,還可以安裝程式碼所需的所有額外套件。為了簡化容器建立過程,TensorFlow 提供了一個基礎容器映像。
選擇 Python 套件還是容器?
使用 Python 套件進行訓練可以幫助更好地組織程式碼,促進重用和可維護性。此外,如果向 Vertex Training 提供 Python 套件,它將在機器和框架最佳化的容器上安裝該套件,這是構建自己的容器所難以做到的。
另一方面,使用容器進行訓練更加靈活。例如,在需要使用舊版或不受支援的執行時版本,或需要安裝專有軟體元件(如內部系統的資料函式庫聯結器)的專案中,容器是一個好的選擇。
因此,選擇取決於您更看重什麼:效率(在這種情況下,您會選擇 Python 套件)還是靈活性(在這種情況下,您會選擇容器)。
分散式訓練策略
在訓練程式碼中,應建立 OneDeviceStrategy:
strategy = tf.distribute.OneDeviceStrategy('/cpu:0')
使用 gcloud 命令啟動訓練作業,可以輕鬆地將模型訓練納入指令碼中,從 Cloud Functions 呼叫訓練作業,或使用 Cloud Scheduler 排程訓練作業。
多 GPU 上的執行
要在具有一個、兩個、四個或更多 GPU 的單台機器上執行,可以在 YAML 組態檔案中新增如下片段:
workerPoolSpecs:
machineSpec:
machineType: n1-standard-4
acceleratorType: NVIDIA_TESLA_T4
acceleratorCount: 2
replicaCount: 1
然後像之前一樣啟動 gcloud 命令,確保在 --config 中指定此組態檔案。
在訓練程式碼中,應建立 MirroredStrategy 例項。
多 GPU 分佈
要在多個工作機上執行,每個工作機具有多個 GPU,組態 YAML 檔案應包括類別似於以下的行:
workerPoolSpecs:
- machineSpec:
machineType: n1-standard-4
acceleratorType: NVIDIA_TESLA_T4
acceleratorCount: 1
- machineSpec:
machineType: n1-standard-4
acceleratorType: NVIDIA_TESLA_T4
acceleratorCount: 1
replicaCount: 1
請記住,如果使用多個工作機,則應透過宣告將被視為一個 epoch 的訓練示例數量來使用虛擬 epoch。還需要進行洗牌。GitHub 上的 serverlessml 中的程式碼示例同時做了這兩件事。
在訓練程式碼中,應建立 MultiWorkerMirroredStrategy 例項。
TPU 分佈
要在 Cloud TPU 上執行,組態檔案 YAML 看起來像這樣(選擇在您閱讀本文時最合適的 TPU 版本):
workerPoolSpecs:
- machineSpec:
machineType: n1-standard-4
acceleratorType: TPU_V2
acceleratorCount: 8
在訓練程式碼中,應建立 TPUStrategy 例項。
您可以使用 Python 的錯誤處理機制建立一個樣板方法,用於建立適合硬體組態的分佈策略:
def create_strategy():
try:
# detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver().connect()
return tf.distribute.experimental.TPUStrategy(tpu)
except ValueError:
# detect GPUs
return tf.distribute.MirroredStrategy()
超引數調優
在建立 ML 模型的過程中,我們做出了許多任意的選擇:隱藏節點的數量、批次大小、學習率、L1/L2 正則化的數量等。可能的組合總數非常龐大,因此最好採用最佳化方法,指定預算(例如,“嘗試 30 種組合”),並讓超引數最佳化技術選擇最佳設定。
完全託管的超引數訓練服務提供了一組引數值給訓練程式,訓練程式然後訓練模型並報告效能指標(準確率、損失等)。因此,超引數調優服務要求我們:
- 指定要調優的引數集、搜尋空間(每個引數可以採用的值範圍,例如學習率必須在 0.0001 和 0.1 之間)和搜尋預算。
- 將給定的引陣列合納入訓練程式。
- 報告使用該引陣列合時的模型效能。
超引數調優的重要性
超引數調優是機器學習模型開發中的一個重要步驟。透過最佳化超引數,可以顯著提高模型的效能。Vertex AI 提供了完全託管的超引數調優服務,使得調優過程變得更加簡單和高效。
超引數調校在Vertex AI上的應用
在這一部分,我們將討論如何在Vertex AI上進行超引數調校,以此作為相關運作的例項。
定義搜尋空間
我們在提供給Vertex AI的YAML組態檔案中定義搜尋空間。舉例來說:
displayName: "FlowersHpTuningJob"
maxTrialCount: 50
parallelTrialCount: 2
studySpec:
metrics:
- metricId: accuracy
goal: MAXIMIZE
parameters:
- parameterId: l2
scaleType: UNIT_LINEAR_SCALE
doubleValueSpec:
minValue: 0
maxValue: 0.2
- parameterId: batch_size
scaleType: SCALE_TYPE_UNSPECIFIED
discreteValueSpec:
values:
- 16
- 32
- 64
algorithm: ALGORITHM_UNSPECIFIED
在此YAML檔案中,我們指定了(請嘗試找到對應的行):
- 目標是最大化訓練器報告的準確度
- 總預算是50次試驗,每次同時進行2次
- 若試驗看起來不太可能比已經看到的結果更好,則提前停止試驗
- 兩個引數:
l2和batch_size- 可能的L2正則化強度(介於0和0.2之間)
- 批次大小,可以是16、32或64
- 演算法型別,若未指定則使用貝葉斯最佳化
組態檔案解讀:
該組態檔案定義了超引數調校的目標、預算、引數範圍以及使用的演算法。透過這種方式,Vertex AI能夠自動搜尋最佳的超引陣列合。
使用引數值
Vertex AI將呼叫我們的訓練器,並將特定的l2和batch_size值作為命令列引數傳遞。因此,我們確保使用argparse列出它們:
parser.add_argument(
'--l2',
help='L2 regularization', default=0., type=float)
parser.add_argument(
'--batch_size',
help='Number of records in a batch', default=32, type=int)
我們必須將這些值納入訓練程式中。例如,我們將使用批次大小如下:
train_dataset = create_preproc_dataset(
'gs://...' + opts['pattern'],
IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS
).batch(opts['batch_size'])
程式碼解說:
這段程式碼展示瞭如何使用命令列引數來控制訓練過程中的超引數,例如L2正則化和批次大小。
回報準確度
在我們使用提供的超引數訓練模型之後,我們需要向超引數調校服務回報結果。我們回報的內容是在YAML檔案中指定的超引數度量標籤:
hpt = hypertune.HyperTune()
accuracy = ...
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag='accuracy',
metric_value=accuracy,
global_step=nepochs)
回報機制:
這段程式碼展示瞭如何向超引數調校服務回報模型的準確度,以便進行後續的最佳化。
結果與分析
提交作業後,超引數調校被啟動,並同時進行50次試驗,每次2次。這些試驗的超引數是使用貝葉斯最佳化方法選擇的。每次試驗完成後,最佳化器會決定輸入空間的哪個部分需要進一步探索,並啟動新的試驗。
結果呈現:
結果顯示在網頁控制檯上(見圖7-6)。根據調校結果,最高的準確度(0.89)是在以下設定下獲得的:l2=0、batch_size=64、num_hidden=24、with_color_distort=0、crop_ratio=0.70706。
繼續調校
檢視這些結果時,值得注意的是,num_hidden和batch_size的最佳值是我們嘗試過的最高值。鑒於此,繼續超引數調校過程並探索更高的值可能是個好主意。同時,我們可以透過使crop_ratio成為一組離散值來減少其搜尋空間(0.70706應該只是0.7)。
繼續調校的策略:
這次,我們不需要貝葉斯最佳化。我們只是希望超引數服務進行45種可能組合的網格搜尋(這也是預算)。
佈署模型
現在我們已經有了一個訓練好的模型,讓我們將其佈署以進行線上預測。TensorFlow SavedModel格式受到TensorFlow Serving的支援。有一個TensorFlow Serving的Docker容器可供您佈署在容器協調系統中,如Google Kubernetes Engine、Google Cloud Run、Amazon Elastic Kubernetes Service、AWS Lambda、Azure Kubernetes Service,或在本地使用Kubernetes。TensorFlow Serving的託管版本在多個雲端平台上都可用。
佈署策略:
這部分內容闡述瞭如何將訓練好的模型佈署到生產環境中,以提供線上預測服務。透過使用TensorFlow Serving,我們可以方便地在不同的環境中佈署模型。
模型品質與持續評估
在前面的章節中,我們已經涵蓋了視覺模型的設計與實作。本章將探討監控與評估的重要主題。除了從一開始就擁有高品質的模型外,我們還需要維持其品質。為了確保最佳的運作狀態,透過監控取得洞察、計算指標、瞭解模型的品質以及持續評估其效能是非常重要的。
監控
我們已經在數百萬張圖片上訓練了模型,並且對其品質感到滿意。將其佈署到雲端後,我們就可以坐下來,放鬆地等待它永遠做出優秀的預測… 對嗎?錯!就像我們不會讓小孩獨自管理自己一樣,我們也不想讓我們的模型在外界無人監管。持續監控其品質(使用準確率等指標)和運算效能(每秒查詢次數、延遲等)是非常重要的,尤其是在不斷地使用新資料重新訓練模型時,這些新資料可能會包含分佈變化、錯誤等問題,而我們需要意識到這些問題。
TensorBoard
很多機器學習從業者在訓練模型時往往不會考慮所有的細節。他們提交訓練任務,然後偶爾檢查一下,直到任務完成。接著,他們使用訓練好的模型進行預測,以檢視其效能。如果訓練任務只需要幾分鐘,這似乎不是什麼大問題。然而,許多電腦視覺專案,尤其是那些包含數百萬張圖片的資料集,訓練任務可能需要數天或數週。如果訓練初期出了問題,而我們直到訓練完成或嘗試使用模型進行預測時才發現,那就太糟糕了。
TensorFlow 提供了一個名為 TensorBoard 的優秀監控工具,可以幫助我們避免這種情況。TensorBoard 是一個互動式儀錶板(見圖 8-1),顯示在模型訓練和評估期間儲存的摘要資訊。可以用它作為已執行實驗的歷史記錄,用於比較不同版本的模型或程式碼,以及分析訓練任務。
TensorBoard 的主要功能
TensorBoard 允許我們監控損失曲線,以確保模型訓練仍在進展中,並且沒有停止改進。我們還可以顯示和互動其他評估指標,例如準確率、精確率或 AUC。例如,我們可以對多個序列進行篩選、平滑和異常值移除,並且可以放大和縮小。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title 訓練程式碼佈署Python套件與容器化策略
package "Docker 架構" {
actor "開發者" as dev
package "Docker Engine" {
component [Docker Daemon] as daemon
component [Docker CLI] as cli
component [REST API] as api
}
package "容器運行時" {
component [containerd] as containerd
component [runc] as runc
}
package "儲存" {
database [Images] as images
database [Volumes] as volumes
database [Networks] as networks
}
cloud "Registry" as registry
}
dev --> cli : 命令操作
cli --> api : API 呼叫
api --> daemon : 處理請求
daemon --> containerd : 容器管理
containerd --> runc : 執行容器
daemon --> images : 映像檔管理
daemon --> registry : 拉取/推送
daemon --> volumes : 資料持久化
daemon --> networks : 網路配置
@enduml
此圖示展示了使用 TensorBoard 進行模型訓練監控的流程。
使用 TensorBoard 的好處
透過使用 TensorBoard,我們可以及時發現訓練過程中的問題,並進行調整,從而提高模型的品質和效能。這對於大型電腦視覺專案尤其重要,因為它們通常需要大量的計算資源和時間。
內容解密:
本章節主要闡述了模型監控與持續評估的重要性,以及如何利用TensorBoard進行有效的模型監控。TensorBoard作為一個互動式儀錶板,能夠顯示模型訓練過程中的各種指標,有助於及時發現並解決問題,從而提升模型的整體品質與效能。持續的監控與評估是確保模型長期穩定運作的關鍵步驟。
下一步
在下一章中,我們將探討如何改進模型的服務體驗,包括如何讓模型直接接受圖片檔案內容等。
TensorBoard 的強大監控功能:模型品質與訓練過程的最佳化
TensorBoard 是一個強大的視覺化工具,能夠幫助我們深入瞭解模型的訓練過程、權重分佈、以及其他重要的模型指標。本文將探討如何使用 TensorBoard 來監控模型的訓練過程,並提供一些實用的技巧來最佳化模型的效能。
權重直方圖:瞭解模型的訓練狀態
在 TensorBoard 中,我們可以使用直方圖來監控權重的分佈。權重的分佈可以告訴我們模型的訓練狀態是否正常。理想情況下,權重的分佈應該趨近於高斯分佈。如果權重的分佈出現了偏差,例如趨近於零或非常大的值,那麼可能表示模型存在某些問題。
權重分佈不佳的解決方案
如果權重的分佈不佳,我們可以嘗試以下幾種方法來改善:
- 將輸入值從 [0, 1] 縮放到 [-1, 1],以避免權重趨近於零。
- 在中間層新增批次正規化(Batch Normalization),以穩定權重的分佈。
- 新增正規化(Regularization)或增加資料集的大小,以避免過度擬合。
- 嘗試不同的初始化方法,以改善權重的初始分佈。
裝置組態:瞭解模型的計算資源使用情況
TensorBoard 可以顯示 TensorFlow 模型圖的視覺化,讓我們瞭解模型的計算資源使用情況。透過裝置組態檢視,我們可以看到哪些節點被分配到哪些裝置上,並且可以檢查 TPU 的相容性。
資料視覺化:瞭解模型的訓練資料
TensorBoard 可以顯示特定型別的資料,例如影像或音訊。透過影像視覺化,我們可以瞭解模型的生成影像是否合理。對於分類別問題,TensorBoard 還可以顯示混淆矩陣(Confusion Matrix),讓我們瞭解模型的分類別效能。
訓練事件:監控模型的訓練過程
我們可以將 TensorBoard 的回呼函式新增到模型中,以監控模型的訓練過程。透過設定 log_dir、histogram_freq、write_graph 等引數,我們可以控制 TensorBoard 的輸出內容。
tensorboard_callback = tf.keras.callbacks.TensorBoard(
log_dir='logs',
histogram_freq=0,
write_graph=True,
write_images=False,
update_freq='epoch',
profile_batch=2,
embeddings_freq=0,
embeddings_metadata=None
)
設定 TensorBoard 的回呼函式
在模型訓練過程中,我們可以將 TensorBoard 的回呼函式新增到 model.fit() 中,以監控模型的訓練過程。
history = model.fit(
train_dataset,
epochs=10,
batch_size=1,
validation_data=validation_dataset,
callbacks=[tensorboard_callback]
)
啟動 TensorBoard
要啟動 TensorBoard,我們可以在終端機中執行以下指令:
tensorboard --logdir=<path_to_your_logs>
這樣就可以在瀏覽器中檢視 TensorBoard 的視覺化結果。