執行 Agent Platform Neural Architecture Search 工作來搜尋最佳模型之前,請先定義代理任務。Stage1-search 使用的模型訓練規模遠小於完整模型訓練,通常會在兩小時內完成。這種表示法稱為「代理任務」,可大幅降低搜尋成本。搜尋期間的每項試驗都會使用 Proxy 任務設定訓練模型。
以下各節說明套用代理任務設計時涉及的事項:
- 建立代理任務的方法。
- 良好代理任務的條件。
- 如何使用三種代理任務設計工具找出最佳代理任務,在降低搜尋成本的同時維持搜尋品質。
建立 Proxy 任務的方法
建立 Proxy 任務有三種常見方法,包括:
- 減少訓練步數。
- 使用子樣本訓練資料集。
- 使用縮減模型。
減少訓練步數
建立代理任務最簡單的方法,就是減少訓練器的訓練步驟數量,並根據這項部分訓練將分數回報給控制器。
使用子樣本訓練資料集
本節說明如何使用子樣本訓練資料集,進行架構搜尋和增強政策搜尋。
架構搜尋
在架構搜尋期間,您可以使用子樣本訓練資料集建立代理任務。不過,進行向下取樣時,請遵循下列準則:
- 隨機重組 shard 之間的資料。
- 如果訓練資料不平衡,請進行子樣本處理,平衡資料。
使用自動擴增功能搜尋擴增政策
如果您只執行一般架構搜尋,而非僅執行擴增搜尋,請略過本節。使用自動擴增功能搜尋擴增政策。建議您對訓練資料進行子取樣,並執行完整訓練,而不是減少訓練步驟數量。執行完整訓練並大量增強資料,可讓分數更穩定。此外,請使用精簡的訓練資料,降低搜尋成本。
以縮減模型為基礎的代理任務
您也可以縮減模型 (相較於基準模型),建立代理任務。如要將區塊設計搜尋與縮放搜尋分開,這個方法也相當實用。
不過,如果縮減模型並想使用延遲時間限制,請為縮減的模型設定更嚴格的延遲時間限制。提示:您可以縮減基準模型並測量延遲時間,設定更嚴格的延遲時間限制。
與原始基準模型相比,縮減後的模型也可以減少擴增和正規化的數量。
縮減模型範例
如果是以圖片訓練的電腦視覺任務,縮減模型規模有三種常見方法:
- 減少模型寬度:通道數量。
- 減少模型深度:層數和區塊重複次數。
- 稍微縮減訓練圖片大小 (以免消除特徵),或在工作允許的情況下裁剪訓練圖片。
建議閱讀:EfficientNet 論文,深入瞭解如何針對電腦視覺任務調整模型。此外,也會說明這三種資源調度方式之間的關係。
Spinenet 搜尋是另一個與 Agent Platform Neural Architecture Search 搭配使用的模型縮放範例。在第 1 階段搜尋中,會縮減通道數量和圖片大小。
根據組合建立 Proxy 任務
這些方法各自獨立,可以不同程度地結合,建立代理任務。
良好代理任務的條件
代理任務必須符合特定要求,才能向控制器提供穩定的獎勵,並維持搜尋品質。
第 1 階段搜尋與第 2 階段完整訓練之間的排名相關性
使用代理任務進行 Agent Platform 神經架構搜尋時,一項關鍵假設是,如果模型 A 在第 1 階段代理任務訓練中的表現優於模型 B,則模型 A 在第 2 階段完整訓練中的表現也會優於模型 B。如要驗證這項假設,您必須評估搜尋空間中約 10 到 20 個模型的第 1 階段搜尋和第 2 階段完整訓練獎勵之間的排名相關性。這些模型稱為關聯候選模型。
下圖顯示相關性不佳的範例 (相關性分數 = -0.03),因此這項 Proxy 任務不適合用於搜尋:

圖中的每個點都代表一個相關性候選模型。x 軸代表模型的第 2 階段完整訓練分數,y 軸則代表相同模型的第 1 階段代理任務分數。觀察最高點。這個模型提供最高的代理任務分數 (y 軸),但在第 2 階段完整訓練 (x 軸) 期間,表現不如其他模型。相較之下,下圖顯示良好關聯性的範例 (關聯性分數 = 0.67),因此這項 Proxy 任務很適合用於搜尋:

如果搜尋涉及延遲時間限制,請一併確認延遲時間值是否具有良好關聯性。
請注意,相關性候選模型的獎勵範圍良好,且獎勵範圍的取樣也相當合理。否則無法評估排名相關性。舉例來說,如果所有相關性候選模型的第 1 階段獎勵都集中在兩個值:0.9 和 0.1,則無法提供足夠的取樣變異。
變異數檢查
代理任務的另一項要求是,在不進行任何變更的情況下,對同一個模型重複執行多次時,準確率或延遲分數不應有大幅變化。如果發生這種情況,就會將雜訊訊號傳回控制器。我們提供測量這項差異的工具。
範例可減少訓練期間的巨大差異。其中一種方法是使用 cosine decay 做為學習率排程。下圖比較三種學習率策略:

最底部的圖表對應的是固定學習率。如果分數在訓練結束時大幅波動,那麼減少訓練步數的選擇只要稍有變化,最終的代理任務獎勵就會大幅改變。如要讓代理任務獎勵更穩定,建議使用餘弦學習率衰減,如最高圖表中的對應驗證分數所示。請注意,最高圖表在訓練結束時會變得更平滑。中間的圖表顯示與逐步學習率衰減對應的分數。這種方法比固定速率好,但仍不如餘弦衰減平滑,且需要手動調整。
學習率排程如下所示:

其他平滑化
如果您使用大量增強,驗證曲線可能不會隨著餘弦衰減而變得足夠平滑。如果大量使用擴增技術,表示訓練資料不足。在這種情況下,不建議使用 Agent Platform Neural Architecture Search,建議改用擴增搜尋。
如果問題並非由大量擴增造成,且您已嘗試餘弦衰減,但仍想進一步提高平滑度,請使用 TensorFlow-2 的指數移動平均,或 PyTorch 的隨機加權平均。如需使用 TensorFlow 2 指數移動平均最佳化器的範例,請參閱這個程式碼指標;如需 PyTorch 的隨機加權平均範例,請參閱這個範例。
如果試驗的準確率/週期圖表如下所示:

則可套用上述平滑技術 (例如隨機加權平均或指數移動平均),取得更一致的圖表,例如:

記憶體不足 (OOM) 和學習率相關錯誤
架構搜尋空間可生成比基準大得多的模型。您可能已調整基準模型的批次大小,但如果搜尋期間取樣較大的模型,這項設定可能會失敗,導致 OOM 錯誤。在這種情況下,您需要縮減批次大小。
另一種錯誤是 NaN (非數字) 錯誤。建議您降低初始學習率,或加入梯度限幅。
如tutorial-2 所述,如果超過 20% 的搜尋空間模型傳回無效分數,則不會執行完整搜尋。我們的代理任務設計工具提供評估失敗率的方法。
Proxy 任務設計工具
前幾節說明瞭代理任務設計原則。本節提供三種代理任務設計工具,可根據不同的設計方法,自動找出符合所有需求的最佳代理任務。
必要程式碼變更
您必須先稍微修改訓練器程式碼,才能在疊代過程中與 Proxy 工作設計工具互動。tf_vision/train_lib.py 顯示範例。您必須先匯入我們的程式庫:
from google.cloud.visionsolutions.nas.proxy_task import proxy_task_utils
在訓練迴圈開始訓練週期之前,請檢查是否需要提早停止訓練,因為 Proxy 任務設計工具會要求您使用我們的程式庫:
if proxy_task_utils.get_stop_training(
model_dir,
end_training_cycle_step=<last-training-step-idx done so far>,
total_training_steps=<total-training-steps>):
break
訓練迴圈中的每個訓練週期完成後,更新新的準確率分數、訓練週期開始和結束步驟、訓練週期時間 (以秒為單位),以及訓練步驟總數。
proxy_task_utils.update_trial_training_accuracy_metric(
model_dir=model_dir,
accuracy=<latest accuracy value>,
begin_training_cycle_step=<beginning training step for this cycle>,
end_training_cycle_step=<end training step for this cycle>,
training_cycle_time_in_secs=<training cycle time (excluding validation)>,
total_training_steps=<total-training-steps>)
請注意,訓練循環時間不應包含驗證分數評估時間。請確認訓練器會頻繁計算驗證分數 (評估頻率),以便取得足夠的驗證曲線樣本。如果您使用延遲時間限制,請在計算延遲時間後更新延遲時間指標:
proxy_task_utils.update_trial_training_latency_metric(
model_dir=model_dir,
latency=<measured_latency>)
模型選取工具需要載入先前的檢查點,才能進行後續疊代。如要啟用重複使用先前檢查點的功能,請在訓練器中新增旗標,如 tf_vision/cloud_search_main.py 所示:
parser.add_argument(
"--retrain_use_search_job_checkpoint",
type=cloud_nas_utils.str_2_bool,
default=False,
help="True to use previous NAS search job checkpoint."
)
訓練模型前,請先載入這個檢查點:
if FLAGS.retrain_use_search_job_checkpoint:
prev_checkpoint_dir = cloud_nas_utils.get_retrain_search_job_model_dir(
retrain_search_job_trials=FLAGS.retrain_search_job_trials,
retrain_search_job_dir=FLAGS.retrain_search_job_dir)
logging.info("Setting checkpoint to %s.", prev_checkpoint_dir)
# Now set your checkpoint using 'prev_checkpoint_dir'.
您也需要與訓練器回報的準確度和延遲值相對應的 metric-id。如果訓練器獎勵 (有時是準確度和延遲時間的組合) 與準確度不同,請務必使用訓練器的 other_metrics 回報僅限準確度的指標。舉例來說,以下範例顯示預先建構的訓練器回報的準確率和延遲時間指標:

變異數評估
修改訓練器程式碼後,第一步是評估訓練器的變異數。如要評估變異數,請修改基準訓練設定,調整下列項目:
- 減少訓練步驟,只使用一或兩個 GPU 執行約一小時。我們需要一小部分完整訓練樣本。
- 使用餘弦衰減學習率,並將其步數設為與這些減少的步數相同,使學習率在接近結束時幾乎為零。
變異數測量工具會從搜尋空間中取樣一個模型,確保這個模型可以開始訓練,而不會產生 OOM 或 NAN 錯誤,然後使用您的設定執行這個模型的五個副本約一小時,然後回報訓練分數變異數和流暢度。執行這項工具的總費用,約等於以您的設定執行五個模型約一小時。
執行下列指令,啟動變異數測量工作 (您需要服務帳戶):
DATE="$(date '+%Y%m%d_%H%M%S')"
project_id=<your project-id>
# You can choose any unique docker id below.
trainer_docker_id=${USER}_trainer_${DATE}
trainer_docker_file=<path to your trainer dockerfile>
region=<your job region such as 'us-central1'>
search_space_module=<path to your search space module>
accelerator_type="NVIDIA_TESLA_V100"
num_gpus=2
# Your bucket should be for your project and in the same region as the job.
root_output_dir=<gs://your-bucket>
####### Variance measurement related parameters ######
proxy_task_variance_measurement_docker_id=${USER}_variance_measurement_${DATE}
# Use the service account that you set-up for your project.
service_account=<your service account>
job_name=<your job name>
############################################################
python3 vertex_nas_cli.py build \
--project_id=${project_id} \
--region=${region} \
--trainer_docker_id=${trainer_docker_id} \
--trainer_docker_file=${trainer_docker_file} \
--proxy_task_variance_measurement_docker_id=${proxy_task_variance_measurement_docker_id}
# The command below passes 'dummy' arguments for the training docker.
# You need to modify them for your own docker.
python3 vertex_nas_cli.py measure_proxy_task_variance \
--proxy_task_variance_measurement_docker_id=${proxy_task_variance_measurement_docker_id} \
--project_id=${project_id} \
--service_account=${service_account} \
--region=${region} \
--trainer_docker_id=${trainer_docker_id} \
--job_name=${job_name} \
--search_space_module=${search_space_module} \
--accelerator_type=${accelerator_type} \
--num_gpus=${num_gpus} \
--root_output_dir=${root_output_dir} \
--search_docker_flags \
dummy_trainer_flag1="dummy_trainer_val"
啟動這項變異數測量工作後,您會取得工作連結。工作名稱開頭應為前置字串 Variance_Measurement。工作 UI 範例如下:

variance_measurement_dir 會包含所有輸出內容,您可以點選「View logs」(查看記錄) 連結來查看記錄。這項工作預設會使用雲端中的一個 CPU,在背景中以自訂工作的形式執行,然後啟動及管理子 NAS 工作。

在「NAS」NAS工作下方,您會看到名為 Find_workable_model_<your job name> 的工作。這項工作會對搜尋空間進行取樣,找出不會產生任何錯誤的模型。找到這類模型後,變異數測量工作會啟動另一個 NAS 工作 <your job name>,並根據您先前設定的訓練步驟數量,執行這個模型的五個副本。這些模型訓練完成後,變異數測量工作會測量分數變異數和流暢度,並在記錄中回報:

如果變異數偏高,可以探索這裡列出的技術。
選取模型
確認訓練器沒有高變異數後,請按照下列步驟操作:
- 找出約 10 個相關性候選模型
- 計算完整訓練分數,做為稍後計算不同代理任務選項的代理任務關聯分數時的參考。
我們的工具會自動且有效率地找出這些相關性候選模型,並確保這些模型在準確度和延遲時間方面都有良好的分數分布,以便為日後的相關性運算奠定良好基礎。為此,工具會執行下列操作:
- 從搜尋空間隨機取樣
N_begin個模型。在本範例中,假設N_begin = 30。訓練時間為完整訓練時間的 1/30。 - 拒絕 30 個模型中的 5 個,因為這些模型不會增加準確率和延遲時間的分佈。下圖為範例。遭拒的模型會顯示為紅點:

- 訓練所選的 25 個模型,訓練時間為完整訓練時間的 1/25,然後根據目前的分數再剔除 5 個模型。請注意,25 個模型的訓練會從先前的查核點繼續。
- 重複這項程序,直到只剩下
N個分布良好的模型。 - 訓練最後
N個模型,直到完成。
N_begin 的預設設定為 30,可在 proxy_task/proxy_task_model_selection_lib_constants.py 檔案中找到 START_NUM_MODELS。N 的預設設定為 10,可在 proxy_task/proxy_task_model_selection_lib_constants.py 檔案中找到 FINAL_NUM_MODELS。
這項模型選取程序的額外費用計算方式如下:
= (30*1/30 + 25*1/25 + 20*1/20 + 15*1/15 + 10*(remaining-training-time-fraction)) * full-training-time
= (4 + 10*(0.81)) * full-training-time
~= 12 * full-training-time
不過,請保持在 N=10 設定以上。Proxy 任務搜尋工具稍後會同時執行這些 N 模型。因此,請確保您有足夠的 GPU 配額。舉例來說,如果 Proxy 任務使用兩個 GPU 處理一個模型,則配額至少應為 2*N 個 GPU。
模型選取工作應使用與第 2 階段完整訓練工作相同的資料集分區,並使用相同的訓練器設定進行基準完整訓練。
現在可以執行下列指令,啟動模型選取工作 (需要服務帳戶):
DATE="$(date '+%Y%m%d_%H%M%S')"
project_id=<your project-id>
# You can choose any unique docker id below.
trainer_docker_id=${USER}_trainer_${DATE}
trainer_docker_file=<path to your trainer dockerfile>
latency_calculator_docker_id=${USER}_model_selection_${DATE}
latency_calculator_docker_file=${USER}_latency_${DATE}
region=<your job region such as 'us-central1'>
search_space_module=<path to your search space module>
accelerator_type="NVIDIA_TESLA_V100"
num_gpus=2
# Your bucket should be for your project and in the same region as the job.
root_output_dir=<gs://your-bucket>
# Your latency computation device.
target_device_type="CPU"
####### Proxy task model-selection related parameters ######
proxy_task_model_selection_docker_id=${USER}_model_selection_${DATE}
# Use the service account that you set-up for your project.
service_account=<your service account>
job_name=<your job name>
# The value below depends on your accelerator quota. By default
# the model-selection job runs 30 trials. However, depending on
# your quota, you can choose to only run 10 trials in parallel at a time.
# However, lowering this number can increase the overall runtime for the job.
max_parallel_nas_trial=<num parallel trials>
# The value below is the 'metric-id' corresponding to the accuracy ONLY
# metric reported by your trainer. Note that this metric may
# be different from the 'reward'.
accuracy_metric_id=<set accuracy metric id used by your trainer>
latency_metric_id=<set latency metric id used by your trainer>
############################################################
python3 vertex_nas_cli.py build \
--project_id=${project_id} \
--region=${region} \
--trainer_docker_id=${trainer_docker_id} \
--trainer_docker_file=${trainer_docker_file} \
--latency_calculator_docker_id=${latency_calculator_docker_id} \
--latency_calculator_docker_file=${latency_calculator_docker_file} \
--proxy_task_model_selection_docker_id=${proxy_task_model_selection_docker_id}
# The command below passes 'dummy' arguments for trainer-docker
# and latency-docker. You need to modify them for your own docker.
python3 vertex_nas_cli.py select_proxy_task_models \
--service_account=${service_account} \
--proxy_task_model_selection_docker_id=${proxy_task_model_selection_docker_id} \
--project_id=${project_id} \
--region=${region} \
--trainer_docker_id=${trainer_docker_id} \
--job_name=${job_name} \
--max_parallel_nas_trial=${max_parallel_nas_trial} \
--accuracy_metric_id=${accuracy_metric_id} \
--latency_metric_id=${latency_metric_id} \
--search_space_module=${search_space_module} \
--accelerator_type=${accelerator_type} \
--num_gpus=${num_gpus} \
--root_output_dir=${root_output_dir} \
--latency_calculator_docker_id=${latency_calculator_docker_id} \
--latency_docker_flags \
dummy_latency_flag1="dummy_latency_val" \
--target_device_type=${target_device_type} \
--search_docker_flags \
dummy_trainer_flag1="dummy_trainer_val"
啟動這項模型選取控制器工作後,您會收到工作連結。工作名稱開頭為前置字串 Model_Selection_。工作 UI 範例如下:

model_selection_dir 包含所有輸出內容。按一下「View logs」連結即可查看記錄。根據預設,這項模型選取控制器工作會使用 Google Cloud 的一個 CPU,在背景中以自訂工作的形式執行,然後為模型選取的每個疊代啟動及管理子 NAS 工作。

每個子項 NAS 工作都有名稱,例如 <your_job_name>_iter_3 (疊代 0 除外)。一次只會執行一個疊代。每次疊代時,模型數量 (試驗次數) 都會減少,訓練時間則會增加。在每個疊代結束時,每個 NAS 工作都會儲存 gs://<job-output-dir>/search/filtered_trial_scores.png 檔案,以視覺化方式顯示在這個疊代中遭拒的模型。您也可以執行下列指令:
gcloud storage cat gs://<path to 'model_selection_dir'>/MODEL_SELECTION_STATE.json
其中會顯示模型選取控制器工作的疊代和目前狀態摘要、工作名稱,以及每個疊代的連結:
{
"start_num_models": 30,
"final_num_models": 10,
"num_models_to_remove_per_iter": 5,
"accuracy_metric_id": "top_1_accuracy_without_latency",
"latency_metric_id": "latency_milli_seconds",
"iterations": [
{
"num_trials": 30,
"trials_to_retrain": [
"27",
"16",
...,
"14"
],
"search_job_name": "projects/123456/locations/europe-west4/nasJobs/2111217356469436416",
"search_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/2111217356469436416/cpu?project=my-project",
"latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/6909239809479278592",
"latency_calculator_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/6909239809479278592/cpu?project=my-project",
"desired_training_step_pct": 2.0
},
...,
{
"num_trials": 15,
"trials_to_retrain": [
"14",
...,
"5"
],
"search_job_name": "projects/123456/locations/europe-west4/nasJobs/7045544066951413760",
"search_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/7045544066951413760/cpu?project=my-project",
"latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/2790768318993137664",
"latency_calculator_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/2790768318993137664/cpu?project=my-project",
"desired_training_step_pct": 28.57936507936508
},
{
"num_trials": 10,
"trials_to_retrain": [],
"search_job_name": "projects/123456/locations/europe-west4/nasJobs/2742864796394192896",
"search_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/2742864796394192896/cpu?project=my-project",
"latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/1490864099985195008",
"latency_calculator_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/1490864099985195008/cpu?project=my-project",
"desired_training_step_pct": 101.0
}
]
}
最後一個疊代作業會產生最終數量的參考模型,且分數分布良好。這些模型和分數會用於下一個步驟的代理任務搜尋。如果參考模型的最終準確率和延遲分數範圍,看起來比現有基準模型更好或接近,就能初步判斷搜尋空間。如果最終準確度和延遲時間分數範圍明顯低於基準,請重新檢查搜尋空間。
請注意,如果第一次疊代中超過 20% 的試驗失敗,請取消模型選取工作,並找出失敗的根本原因。這可能是搜尋空間或批次大小和學習率設定有問題。
使用地端部署延遲裝置選取模型
如要使用地端部署延遲時間裝置選取模型,請執行 select_proxy_task_models 指令,但不使用延遲時間 Docker 和 latency-docker 旗標,因為您不想在 Google Cloud上啟動延遲時間 Docker。接著,使用教學課程 4 中所述的 run_latency_calculator_local 指令,啟動地端部署延遲時間計算工具工作。請改為傳遞
--search_job_id--controller_job_id 旗標,並附上
執行
select_proxy_task_models 指令後取得的數值模型選取工作 ID。
正在繼續執行模型選取控制器工作
在下列情況下,您必須繼續模型選取控制器工作:
- 父項模型選取控制器工作終止 (罕見情況)。
- 您不小心取消模型選取控制器工作。
首先,如果子項 NAS 疊代工作 (「NAS」分頁) 已在執行,請勿取消。接著,如要繼續執行父項模型選取控制器工作,請像之前一樣執行 select_proxy_task_models 指令,但這次要傳遞 --previous_model_selection_dir 旗標,並將其設為先前模型選取控制器工作的輸出目錄。恢復的模型選取控制器工作會從目錄載入先前的狀態,並像之前一樣繼續運作。
Proxy 任務搜尋
找出相關性候選模型及其完整訓練分數後,下一步是使用這些模型評估不同代理任務選擇的相關性分數,並選擇最佳代理任務。我們的代理任務搜尋工具可自動尋找代理任務,並提供下列功能:
- 最低的 NAS 搜尋成本。
- 提供代理任務搜尋空間定義後,達到最低相關性要求門檻。
請注意,尋找最佳代理任務時,有三個常見的維度,包括:
- 減少訓練步數。
- 減少訓練資料量。
- 縮小模型。
您可以對這些維度進行取樣,建立離散代理任務搜尋空間,如下所示:

上述百分比僅為約略建議和範例。在實務上,您可以選擇任何離散選項。請注意,我們並未在上述搜尋空間中加入訓練步驟維度。這是因為 Proxy 任務搜尋工具會根據 Proxy 任務選擇,找出最佳訓練步驟。假設代理任務選擇 [50% training data, 25% model scale]。將訓練步數設為與完整基準訓練相同的數量。評估這項代理任務時,代理任務搜尋工具會啟動關聯候選模型的訓練、監控目前的準確率分數,並持續計算排名關聯分數 (使用參考模型的過去完整訓練分數):

因此,一旦取得所需的關聯性 (例如 0.65),代理任務搜尋工具就會停止代理任務訓練,或者如果超出搜尋成本配額 (例如每個代理任務 3 小時限制),也會提早停止。因此,您不需要明確搜尋訓練步驟。Proxy 任務搜尋工具會將離散搜尋空間中的每個 Proxy 任務視為網格搜尋進行評估,並提供最佳選項。
以下是 proxy_task/proxy_task_search_spaces.py 檔案中定義的 MnasNet 代理任務搜尋空間定義範例 mnasnet_proxy_task_config_generator,示範如何定義自己的搜尋空間:
# MNasnet training-data size choices.
MNASNET_TRAINING_DATA_PCT_LIST = [25, 50, 75, 95]
# Training data path regex pattern.
_TRAINING_DATA_PATH_REGEX = r"gs://.*/.*"
def update_mnasnet_proxy_training_data(
baseline_docker_args_map: Dict[str, Any],
training_data_pct: int) -> Optional[Dict[str, Any]]:
"""Updates MNasnet baseline docker to use a certain training_data_pct."""
proxy_task_docker_args_map = copy.deepcopy(baseline_docker_args_map)
# Imagenet training data path looks like:
# gs://<path to imagenet data>/train-00[0-7]??-of-01024.
if not re.match(_TRAINING_DATA_PATH_REGEX,
baseline_docker_args_map["training_data_path"]):
raise ValueError(
"Training data path %s does not match the desired pattern." %
baseline_docker_args_map["training_data_path"])
root_path, _ = baseline_docker_args_map["training_data_path"].rsplit("/", 1)
if training_data_% == 25:
proxy_task_docker_args_map["training_data_path"] = os.path.join(
root_path, "train-00[0-1][0-4]?-of-01024*")
elif training_data_% == 50:
proxy_task_docker_args_map["training_data_path"] = os.path.join(
root_path, "train-00[0-4]??-of-01024*")
elif training_data_% == 75:
proxy_task_docker_args_map["training_data_path"] = os.path.join(
root_path, "train-00[0-6][0-4]?-of-01024*")
elif training_data_% == 95:
proxy_task_docker_args_map["training_data_path"] = os.path.join(
root_path, "train-00[0-8][0-4]?-of-01024*")
else:
logging.warning("Mnasnet training_data_% %d is not supported.",
training_data_pct)
return None
proxy_task_docker_args_map["validation_data_path"] = os.path.join(
root_path, "train-009[0-4]?-of-01024")
return proxy_task_docker_args_map
def mnasnet_proxy_task_config_generator(
baseline_docker_args_map: Dict[str, Any]
) -> List[proxy_task_utils.ProxyTaskConfig]:
"""Returns a list of proxy-task configs to be evaluated for MNasnet.
Args:
baseline_docker_args_map: A set of baseline training-docker arguments in
the form of a dictionary of {'key', val}. The different proxy-task
configs to try can be built by modifying this baseline.
Returns:
A list of proxy-task configs to be evaluated for this
proxy-task search space.
"""
proxy_task_config_list = []
# NOTE: Will not search over model-scale for MNasnet.
for training_data_% in MNASNET_TRAINING_DATA_PCT_LIST:
proxy_task_docker_args_map = update_mnasnet_proxy_training_data(
baseline_docker_args_map=baseline_docker_args_map,
training_data_pct=training_data_pct)
if not proxy_task_docker_args_map:
continue
proxy_task_name = "mnasnet_proxy_training_data_pct_{}".format(
training_data_pct)
proxy_task_config_list.append(
proxy_task_utils.ProxyTaskConfig(
name=proxy_task_name, docker_args_map=proxy_task_docker_args_map))
return proxy_task_config_list
在這個範例中,我們建立了一個簡單的搜尋空間,訓練資料百分比為 25、50、75 和 95 (請注意,100% 訓練資料不會用於 stage1-search)。mnasnet_proxy_task_config_generator 函式會採用訓練 Docker 引數的一般基準範本,然後針對每個所需的 Proxy 任務訓練資料大小修改這些引數。接著,系統會傳回 proxy-task-config 清單,並由 proxy-task 搜尋工具依相同順序逐一處理。每個 Proxy 工作設定都有 name 和 docker_args_map,這是 Proxy 工作 Docker 引數的鍵/值對應。
您可以根據自己的需求,自由實作自己的搜尋空間定義,並設計自己的代理任務搜尋空間,甚至可以超過減少訓練資料或減少模型規模的兩個維度。不過,我們不建議明確搜尋訓練步驟,因為這會浪費重複的運算資源。讓 Proxy 任務搜尋工具為您處理這個維度。
第一次搜尋代理任務時,可以嘗試只減少訓練資料 (就像 MnasNet 範例一樣),並略過縮減模型規模,因為模型縮放可能會涉及 image-size、num-filters 或 num-blocks 的多個參數。在多數情況下,減少訓練資料 (以及減少訓練步驟的「隱含」搜尋) 就足以找出合適的代理任務。
將訓練步數設為完整基準訓練使用的步數。第 2 階段完整訓練和第 1 階段代理任務訓練的設定有所不同。如果是 Proxy 任務,請將 batch-size 設為比完整基準訓練設定更低的值,只使用 2 個或 4 個 GPU。一般來說,完整訓練會使用 4 個、8 個或更多 GPU,但 Proxy 工作只會使用 2 個或 4 個 GPU。另一個差異是訓練和驗證分割。以下範例說明 MnasNet 設定的變更,從第 2 階段完整訓練的 4 個 GPU,變更為 2 個 GPU 和不同的驗證分割,用於 Proxy 任務搜尋:

執行下列指令,啟動 Proxy 任務搜尋控制器工作 (需要服務帳戶):
DATE="$(date '+%Y%m%d_%H%M%S')"
project_id=<your project-id>
# You can choose any unique docker id below.
trainer_docker_id=${USER}_trainer_${DATE}
trainer_docker_file=<path to your trainer dockerfile>
latency_calculator_docker_id=${USER}_model_selection_${DATE}
latency_calculator_docker_file=${USER}_latency_${DATE}
region=<your job region such as 'us-central1'>
search_space_module=<path to your NAS job search space module>
accelerator_type="NVIDIA_TESLA_V100"
num_gpus=2
# Your bucket should be for your project and in the same region as the job.
root_output_dir=<gs://your-bucket>
# Your latency computation device.
target_device_type="CPU"
####### Proxy task search related parameters ######
proxy_task_search_controller_docker_id=${USER}_proxy_task_search_${DATE}
job_name=<your job name>
# Path to your proxy task search space definition. For ex:
# 'proxy_task.proxy_task_search_spaces.mnasnet_proxy_task_config_generator'
proxy_task_config_generator_module=<path to your proxy task config generator module>
# The previous model-slection job provides the candidate-correlation-models
# and their scores.
proxy_task_model_selection_job_id=<Numeric job id of your previous model-selection>
# During proxy-task search, the proxy-task training is stopped
# when the following correlation score is achieved.
desired_accuracy_correlation=0.65
# During proxy-task search, the proxy-task training is stopped
# if the runtime exceeds this limit: 4 hrs.
training_time_hrs_limit=4
# The proxy-task is marked a good candidate only if the latency
# correlation is also above the required threshold.
# Note: This won't be used if you do not have a latency job.
desired_latency_correlation=0.65
# Early stop a proxy-task evaluation if you already have a better candidate.
# If False, evaluate all proxy-taask candidates.
early_stop_proxy_task_if_not_best=False
# Use the service account that you set-up for your project.
service_account=<your service account>
###################################################
python3 vertex_nas_cli.py build \
--project_id=${project_id} \
--region=${region} \
--trainer_docker_id=${trainer_docker_id} \
--trainer_docker_file=${trainer_docker_file} \
--latency_calculator_docker_id=${latency_calculator_docker_id} \
--latency_calculator_docker_file=${latency_calculator_docker_file} \
--proxy_task_search_controller_docker_id=${proxy_task_search_controller_docker_id}
# The command below passes 'dummy' arguments for trainer-docker
# and latency-docker. You need to modify them for your own docker.
python3 vertex_nas_cli.py search_proxy_task \
--service_account=${service_account} \
--proxy_task_search_controller_docker_id=${proxy_task_search_controller_docker_id} \
--proxy_task_config_generator_module=${proxy_task_config_generator_module} \
--proxy_task_model_selection_job_id=${proxy_task_model_selection_job_id} \
--proxy_task_model_selection_job_region=${region} \
--desired_accuracy_correlation={$desired_accuracy_correlation}\
--training_time_hrs_limit=${training_time_hrs_limit} \
--desired_latency_correlation=${desired_latency_correlation} \
--early_stop_proxy_task_if_not_best=${early_stop_proxy_task_if_not_best} \
--project_id=${project_id} \
--region=${region} \
--trainer_docker_id=${trainer_docker_id} \
--job_name=${job_name} \
--search_space_module=${search_space_module} \
--accelerator_type=${accelerator_type} \
--num_gpus=${num_gpus} \
--root_output_dir=${root_output_dir} \
--latency_calculator_docker_id=${latency_calculator_docker_id} \
--latency_docker_flags \
dummy_latency_flag1="dummy_latency_val" \
--target_device_type=${target_device_type} \
--search_docker_flags \
dummy_trainer_flag1="dummy_trainer_val"
啟動這項 Proxy 任務搜尋控制器工作後,您會收到工作連結。工作名稱開頭為前置字串 Search_controller_。工作 UI 範例如下:

search_controller_dir 會包含所有輸出內容,您可以點選「View logs」連結查看記錄。根據預設,這項工作會使用雲端中的一個 CPU,在背景中以自訂工作的形式執行,然後啟動並管理每個 Proxy 工作評估的子 NAS 工作。

每個 Proxy 工作 NAS 工作都有名稱,例如 ProxyTask_<your-job-name>_<proxy-task-name>,其中 <proxy-task-name> 是 Proxy 工作設定產生器模組為每個 Proxy 工作提供的名稱。一次只能執行一項代理任務評估。您也可以執行下列指令:
gcloud storage cat gs://<path to 'search_controller_dir'>/SEARCH_CONTROLLER_STATE.json
這個指令會顯示所有 Proxy 任務評估的摘要,以及搜尋控制器工作的目前狀態、工作名稱和各項評估的連結:
{
"proxy_tasks_map": {
"mnasnet_proxy_training_data_pct_25": {
"proxy_task_stats": {
"training_steps": [
1249,
2499,
...,
18749
],
"accuracy_correlation_over_step": [
-0.06666666666666667,
-0.6,
...,
0.7857142857142856
],
"accuracy_correlation_p_value_over_step": [
0.8618005952380953,
0.016666115520282188,
...,
0.005505952380952381
],
"median_accuracy_over_step": [
0.011478611268103123,
0.04956454783678055,
...,
0.32932570576667786
],
"median_training_time_hrs_over_step": [
0.11611097933475001,
0.22913257125276987,
...,
1.6682701704073444
],
"latency_correlation": 0.9555555555555554,
"latency_correlation_p_value": 5.5114638447971785e-06,
"stopping_state": "Met desired correlation",
"posted_stop_trials_message": true,
"final_training_time_in_hours": 1.6675102778428197,
"final_training_steps": 18512
},
"proxy_task_name": "mnasnet_proxy_training_data_pct_25",
"search_job_name": "projects/123456/locations/europe-west4/nasJobs/4173661476642357248",
"search_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/4173661476642357248/cpu?project=my-project",
"latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/8785347495069745152",
"latency_calculator_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/8785347495069745152/cpu?project=my-project"
},
...,
"mnasnet_proxy_training_data_pct_95": {
"proxy_task_stats": {
"training_steps": [
1249,
...,
18749
],
"accuracy_correlation_over_step": [
-0.3333333333333333,
...,
0.7857142857142856,
-5.0
],
"accuracy_correlation_p_value_over_step": [
0.21637345679012346,
...,
0.005505952380952381,
-5.0
],
"median_accuracy_over_step": [
0.01120645459741354,
...,
0.38238024711608887,
-1.0
],
"median_training_time_hrs_over_step": [
0.11385884770307843,
...,
1.5466042930547819,
-1.0
],
"latency_correlation": 0.9555555555555554,
"latency_correlation_p_value": 5.5114638447971785e-06,
"stopping_state": "Met desired correlation",
"posted_stop_trials_message": true,
"final_training_time_in_hours": 1.533235285929564,
"final_training_steps": 17108
},
"proxy_task_name": "mnasnet_proxy_training_data_pct_95",
"search_job_name": "projects/123456/locations/europe-west4/nasJobs/2341822328209408000",
"search_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/2341822328209408000/cpu?project=my-project",
"latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/7575005095213924352",
"latency_calculator_job_link": "https://console.cloud.google.com/agent-platform/locations/europe-west4/training/7575005095213924352/cpu?project=my-project"
}
},
"best_proxy_task_name": "mnasnet_proxy_training_data_pct_75"
}
proxy_tasks_map 會儲存每項代理任務評估的輸出內容,best_proxy_task_name 則會記錄搜尋的最佳代理任務。每個代理任務項目都有額外資料,例如 proxy_task_stats,記錄準確度相關性的進度、p 值、中位數準確度,以及訓練步驟的中位數訓練時間。此外,系統也會記錄延遲時間相關的關聯性 (如適用),以及停止這項工作的原因 (例如超過訓練時間限制) 和停止時的訓練步驟。您也可以執行下列指令,將 search_controller_dir 的內容複製到本機資料夾,以圖表形式查看這些統計資料:
gcloud storage cp gs://<path to 'search_controller_dir'>/* /your/local/dir
並檢查圖表圖片。舉例來說,下圖顯示最佳代理任務的準確度關聯性與訓練時間:

搜尋完成後,您已找到最佳的 Proxy 任務設定,接下來必須執行下列操作:
- 將訓練步數設為勝出代理任務的
final_training_steps。 - 將餘弦衰減步數設為與
final_training_steps相同,讓學習率在接近結束時幾乎為零。 - [選用] 在訓練結束時進行一次驗證分數評估,可節省多次評估的費用。
使用地端部署延遲時間裝置進行 Proxy 任務搜尋
如要使用地端部署延遲時間裝置進行 Proxy 工作搜尋,請執行 search_proxy_task 指令,但不使用延遲時間 Docker 和 latency-docker 旗標,因為您不想在 Google Cloud上啟動延遲時間 Docker。接著,使用教學課程 4 中所述的 run_latency_calculator_local 指令,啟動地端部署延遲時間計算工具工作。請改為傳遞
--search_job_id--controller_job_id 旗標,並附上
執行
search_proxy_task 指令後取得的 proxy-task-search 工作 ID 數字。
正在繼續執行 Proxy 任務搜尋控制器工作
在下列情況下,您必須繼續 Proxy 工作搜尋控制器工作:
- 父項 Proxy 工作搜尋控制器工作終止 (罕見情況)。
- 您不小心取消了 Proxy 任務搜尋控制器工作。
- 您想在日後 (甚至多天後) 擴充 Proxy 任務搜尋空間。
首先,如果子項 NAS 疊代工作 (「NAS」分頁) 已在執行,請勿取消。接著,如要繼續執行父項 Proxy 工作搜尋控制器工作,請像之前一樣執行 search_proxy_task 指令,但這次要傳遞 --previous_proxy_task_search_dir 旗標,並將其設為先前 Proxy 工作搜尋控制器工作的輸出目錄。恢復的 Proxy 工作搜尋控制器工作會從目錄載入先前的狀態,並繼續像之前一樣運作。
最終檢查
代理任務的最後兩項檢查包括獎勵範圍,以及儲存資料以供搜尋後分析。
獎勵範圍
回報給控制器的獎勵應介於 [1e-3, 10] 之間。如果不是,您可以人為調整獎勵,以達到這個目標。
儲存資料,以便在搜尋後進行分析
Proxy 任務程式碼應將任何其他指標和資料儲存至 Cloud Storage 位置,以便日後分析搜尋空間。Agent Platform Neural Architecture Search 最多只能記錄五個浮點 other_metrics。任何其他指標都應儲存至 Cloud Storage 位置,以便日後分析。