Progettazione attività proxy

Prima di eseguire un job di Neural Architecture Search (NAS) per cercare un modello ottimale, definisci l'attività proxy. Stage1-search utilizza una rappresentazione molto più piccola dell'addestramento di un modello completo, che in genere termina entro due ore. Questa rappresentazione è chiamata attività proxy e riduce in modo significativo il costo di ricerca. Ogni prova durante la ricerca addestra un modello utilizzando le impostazioni dell'attività proxy.

Le seguenti sezioni descrivono gli elementi coinvolti nell'applicazione della progettazione delle attività proxy:

  • Approccio alla creazione di un'attività proxy.
  • Requisiti per un'attività proxy valida.
  • Come utilizzare i tre strumenti di progettazione delle attività proxy per trovare l'attività proxy ottimale, che riduca i costi di ricerca e ne preserva la qualità.

Approccio alla creazione di un'attività proxy

Esistono tre approcci comuni per creare un'attività proxy, che includono quanto segue:

  • Usa meno passaggi di addestramento.
  • Utilizza un set di dati di addestramento sottocampionato.
  • Utilizza un modello ridimensionato.

Usa meno passaggi di addestramento

Il modo più semplice di creare un'attività proxy è ridurre il numero di passaggi di addestramento per il formatore e segnalare un punteggio al controller in base a questo addestramento parziale.

Usa un set di dati di addestramento sottocampionato

Questa sezione descrive l'utilizzo di un set di dati di addestramento sottocampionati sia per una ricerca dell'architettura che per una ricerca dei criteri di aumento.

Un'attività proxy può essere creata utilizzando un set di dati di addestramento sottocampionati durante la ricerca dell'architettura. Tuttavia, per il sottocampionamento segui queste linee guida:

  • Esegui lo shuffling dei dati in modo casuale tra gli shard.
  • Se i dati di addestramento non sono bilanciati, utilizza un sottocampionamento per bilanciarli.

Salta questa sezione se non esegui una ricerca solo per l'aumento e solo la ricerca ad architettura normale. Utilizza l'incremento automatico per cercare i criteri di aumento. È preferibile eseguire un sottocampionamento dei dati di addestramento ed eseguire un addestramento completo anziché ridurre il numero di passaggi di addestramento. Un allenamento completo con aumento intensivo mantiene i punteggi più stabili. Inoltre, utilizza i dati di addestramento ridotti per mantenere più bassi i costi di ricerca.

Attività proxy basata su un modello di scale down

Puoi anche fare lo scale down del modello rispetto al modello di base per creare un'attività proxy. Questo può essere utile anche quando vuoi separare block-design-search dalla scalabilità-search.

Tuttavia, quando fai fare lo scale down del modello e vuoi utilizzare un vincolo di latenza, utilizza un vincolo di latenza più stretto per il modello con lo scale down. Suggerimento: puoi fare lo scale down del modello di riferimento e misurare la sua latenza per impostare questo vincolo di latenza più stringente.

Per il modello ridimensionato, puoi anche ridurre la quantità di aumento e regolarizzazione rispetto al modello di riferimento originale.

Esempi di modello in scala ridotta

Per le attività di visione artificiale in cui esegui l'addestramento sulle immagini, esistono tre modi comuni per fare lo scale down di un modello:

  • Ridurre la larghezza del modello: esistono diversi canali.
  • Ridurre la profondità del modello: una serie di livelli e blocchi di ripetizioni.
  • Ridurre leggermente le dimensioni delle immagini di addestramento (in modo che non eliminino le caratteristiche) o ritagliare le immagini di addestramento, se consentito dall'attività.

Lettura suggerita: l'articolo su EfficientNet fornisce insight preziosi sulla scalabilità dei modelli per le attività di visione artificiale. Spiega inoltre come tutte e tre le modalità di scalabilità siano correlate tra loro.

La ricerca Spinenet è un altro esempio di scalabilità dei modelli utilizzato con Neural Architecture Search (NAS). Per la ricerca fase 1, riduce il numero di canali e le dimensioni delle immagini.

Attività proxy basata su una combinazione

Gli approcci funzionano in modo indipendente e possono essere combinati in diversi gradi per creare un'attività proxy.

Requisiti per un'attività proxy valida

Un'attività proxy deve soddisfare determinati requisiti prima di poter restituire un premio stabile al controller e mantenere la qualità della ricerca.

Correlazione per ranking tra la ricerca della fase 1 e la fase 2 della formazione completa

Quando utilizzi un'attività proxy per Neural Architecture Search, un'ipotesi chiave per una ricerca riuscita è che se il modello A ha prestazioni migliori del modello B durante l'addestramento dell'attività proxy della fase 1, il modello A avrà un rendimento migliore del modello B per l'addestramento completo della fase 2. Per convalidare questa ipotesi, devi valutare la correlazione di ranking tra la ricerca di fase 1 e i premi di addestramento completo di fase 2 su circa 10-20 modelli nel tuo spazio di ricerca. Questi modelli prendono il nome di correlazione-candidati-modelli.

La figura seguente mostra un esempio di correlazione scadente (punteggio-correlazione = -0,03), il che rende questa attività proxy un candidato errato per una ricerca:

Correlazione scadente.

Ogni punto del grafico rappresenta un modello di correlazione-candidato. L'asse x rappresenta i punteggi dell'addestramento completo della fase 2 per i modelli, mentre l'asse y rappresenta i punteggi delle attività proxy della fase 1 per gli stessi modelli. Osserva il punto più alto. Questo modello ha ottenuto il punteggio più alto per l'attività proxy (asse y), ma ha prestazioni scarse durante l'addestramento completo della fase 2 (asse x) rispetto ad altri modelli. Al contrario, la figura seguente mostra un esempio di una buona correlazione (punteggio-correlazione = 0,67) che rende questa attività proxy una buona candidata per una ricerca:

Buona correlazione.

Se la ricerca prevede un vincolo di latenza, verifica anche una buona correlazione per i valori di latenza.

Tieni presente che le ricompense dei modelli di correlazione-candidati hanno una buona gamma e un buon campionamento dell'intervallo di premi. In caso contrario, non puoi valutare la correlazione di ranking. Ad esempio, se tutte le ricompense di livello 1 dei modelli di correlazione-candidati sono incentrate su soli due valori: 0,9 e 0,1, non si ottiene una variazione di campionamento sufficiente.

Controllo della variazione

Un altro requisito di un'attività proxy è che non deve avere una grande variazione nell'accuratezza o nel punteggio di latenza se ripetuta più volte per lo stesso modello senza alcuna modifica. In questo caso, viene restituito un segnale rumoroso al controller. È disponibile uno strumento per misurare questa varianza.

Vengono forniti esempi per mitigare una grande variazione durante l'addestramento. Un modo è utilizzare cosine decay come pianificazione del tasso di apprendimento. Il seguente diagramma mette a confronto tre strategie relative al tasso di apprendimento:

Punteggi con tassi di apprendimento diversi.

Il grafico più basso corrisponde a un tasso di apprendimento costante. Quando il punteggio salta alla fine della formazione, una piccola modifica nella scelta del numero ridotto di passaggi di addestramento può causare un grande cambiamento nel premio finale per il compito proxy. Per rendere più stabile il premio dell'attività proxy, è meglio utilizzare un decadimento del tasso di apprendimento coseno come mostrato dai punteggi di convalida corrispondenti nel grafico più alto. Nota che la trama più alta diventa più fluida verso la fine dell'addestramento. Il grafico centrale mostra il punteggio corrispondente al decadimento del tasso di apprendimento graduale. È migliore della velocità costante, ma non è uniforme come il decadimento coseno e richiede inoltre l'ottimizzazione manuale.

Di seguito sono riportate le pianificazioni del tasso di apprendimento:

Percentuali di apprendimento.

Perfezionamento aggiuntivo

Se utilizzi l'aumento intensivo, la curva di convalida potrebbe non diventare sufficientemente uniforme con il decadimento coseno. L'uso di un aumento intensivo indica la mancanza di dati di addestramento. In questo caso, l'utilizzo di Neural Architecture Search non è consigliato e ti consigliamo di utilizzare invece augmentation-search.

Se l'aumento intensivo non è la causa e hai già provato il decadimento coseno, ma vuoi comunque ottenere una maggiore fluidità, utilizza la media mobile esponenziale per TensorFlow-2 o la media ponderata stocastica per PyTorch. Fai riferimento a questo puntatore di codice per un esempio di utilizzo dell'ottimizzatore di media mobile esponenziale con TensorFlow 2 e a questo esempio di media ponderata stocastica per PyTorch.

Se i grafici di accuratezza/epoca per le prove hanno il seguente aspetto:

Grafico accuratezza/epoca senza applicazione del perfezionamento

puoi applicare le tecniche di livellamento menzionate sopra (come la media ponderata stocastica o l'uso della media mobile esponenziale) per ottenere un grafico più coerente come:

Grafico accurata/epoca con levigatura applicata

Errori relativi all'esaurimento della memoria e al tasso di apprendimento

Lo spazio di ricerca dell'architettura può generare modelli molto più grandi della base di riferimento. Potresti aver ottimizzato le dimensioni del batch per il tuo modello di riferimento, ma questa impostazione potrebbe non riuscire quando i modelli più grandi vengono campionati durante la ricerca, generando errori OOM. In questo caso, devi ridurre le dimensioni del batch.

L'altro tipo di errore visualizzato è un errore NaN (non un numero). Dovresti ridurre il tasso di apprendimento iniziale o aggiungere il ritaglio dei gradienti.

Come menzionato nel tutorial-2, se più del 20% dei modelli dello spazio di ricerca restituisce punteggi non validi, non esegui la ricerca completa. I nostri strumenti di progettazione per le attività proxy forniscono un modo per valutare la percentuale di errori.

Strumenti di progettazione per le attività proxy

Le sezioni precedenti descrivono i principi della progettazione di attività proxy. Questa sezione fornisce tre strumenti di progettazione per le attività proxy che consentono di trovare automaticamente l'attività proxy ottimale in base ai diversi approcci di progettazione e che soddisfa tutti i requisiti.

Modifiche al codice obbligatorie

Prima devi modificare leggermente il codice del trainer in modo che possa interagire con gli strumenti di progettazione per l'attività proxy durante un processo iterativo. Il campo tf_vision/train_lib.py mostra un esempio. Devi prima importare la nostra libreria:

from google.cloud.visionsolutions.nas.proxy_task import proxy_task_utils

Prima che inizi un ciclo di addestramento nel tuo ciclo di addestramento, verifica se devi interrompere l'addestramento perché lo strumento di progettazione per l'attività proxy richiede che tu utilizzi la nostra libreria:

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

Al termine di ogni ciclo di addestramento nel loop di addestramento, aggiorna il nuovo punteggio di accuratezza, le fasi di inizio e fine del ciclo di addestramento, il tempo del ciclo di addestramento in secondi e il totale dei passaggi di addestramento.

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>)

Tieni presente che il tempo del ciclo di addestramento non deve includere il tempo per la valutazione del punteggio di convalida. Assicurati che il trainer calcoli spesso i punteggi di convalida (frequenza-valutazione) in modo da avere un campionamento sufficiente della curva di convalida. Se utilizzi un vincolo di latenza, aggiorna la metrica di latenza dopo aver calcolato la latenza:

proxy_task_utils.update_trial_training_latency_metric(
          model_dir=model_dir,
          latency=<measured_latency>)

Lo strumento di selezione dei modelli richiede il caricamento del checkpoint precedente per l'iterazione successiva. Per attivare il riutilizzo di un checkpoint precedente, aggiungi un flag all'istruttore come mostrato in 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."
  )

Carica questo checkpoint prima di addestrare il modello:

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'.

È anche necessario il metric-id corrispondente ai valori di accuratezza e latenza segnalati dal formatore. Se la ricompensa del formatore (che a volte è una combinazione di accuratezza e latenza) è diversa dalla precisione, assicurati di segnalare anche la metrica solo per la precisione utilizzando other_metrics del tuo formatore. Ad esempio, l'esempio seguente mostra le metriche solo per accuratezza e latenza segnalate dal nostro addestratore predefinito:

Metriche di selezione del modello

Misurazione della varianza

Dopo aver modificato il codice del formatore, il primo passaggio è misurare la varianza per il formatore. Per la misurazione della varianza, modifica la configurazione dell'addestramento di base per quanto segue:

  • ridurre i passaggi di addestramento, in modo che l'esecuzione sia solo di circa un'ora con una o due GPU. Abbiamo bisogno di un piccolo campione di addestramento completo.
  • utilizzare il tasso di apprendimento sul decadimento coseno e impostare i passaggi in modo che corrispondano a quelli ridotti, in modo che il tasso di apprendimento diventi quasi zero verso la fine.

Lo strumento di misurazione della varianza campiona un modello dallo spazio di ricerca, garantisce che il modello possa iniziare l'addestramento senza restituire errori OOM o NAN, esegue cinque copie del modello con le tue impostazioni per circa un'ora e poi segnala la variazione e l'omogeneità del punteggio di addestramento. Il costo totale dell'esecuzione di questo strumento è approssimativamente uguale all'esecuzione di cinque modelli con le tue impostazioni per circa un'ora.

Avvia il job di misurazione della varianza eseguendo questo comando (è necessario un account di servizio):

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"

Una volta avviato questo job di misurazione della varianza, riceverai un link al job. Il nome job deve iniziare con il prefisso Variance_Measurement. Di seguito è mostrato un esempio di UI del job:

Job di misurazione della variazione

variance_measurement_dir conterrà tutti gli output e potrai controllare i log facendo clic sul link Visualizza log. Questo job utilizza per impostazione predefinita una CPU sul cloud per l'esecuzione in background come job personalizzato, quindi avvia e gestisce job NAS secondari.

Job personalizzati e nas

In Job NAS, vedrai un job denominato Find_workable_model_<your job name>. Questo job campionerà il tuo spazio di ricerca per trovare un modello, che non genera alcun errore. Una volta trovato un modello di questo tipo, il job di misurazione della varianza avvia un altro job NAS <your job name>, che esegue cinque copie del modello per il numero di passaggi di addestramento impostato in precedenza. Una volta completato l'addestramento per questi modelli, il job di misurazione della varianza misura la varianza e l'andamento del punteggio e riporta queste informazioni nei propri log:

Log di misurazione della variazione

Se la varianza è elevata, puoi esplorare le tecniche elencate qui.

Selezione del modello

Dopo aver verificato che il tuo trainer non presenti una varianza elevata, i passaggi successivi sono:

  • per trovare circa 10 modelli-candidati-correlazione
  • calcolano i punteggi di addestramento completi che serviranno da riferimento quando calcolerai i punteggi di correlazione delle attività proxy per le diverse opzioni delle attività proxy in un secondo momento.

Il nostro strumento individua automaticamente ed in modo efficiente questi modelli di correlazione-candidato e garantisce che abbiano una buona distribuzione dei punteggi sia per l'accuratezza che per la latenza, in modo che il calcolo della correlazione futuro abbia una buona base. A questo scopo, lo strumento svolge le seguenti operazioni:

  • Campiona in modo casuale N_begin modelli dal tuo spazio di ricerca. Per questo esempio, supponiamo che N_begin = 30. Lo strumento li addestra per 1/30 del tempo pieno di addestramento.
  • Rifiutare 5 modelli su 30, che non migliorano la distribuzione di accuratezza e latenza. La figura che segue mostra questo esempio. I modelli rifiutati vengono mostrati con punti rossi:

Esempio di selezione del modello

  • Addestra i 25 modelli selezionati per 1/25 del tempo di addestramento completo e poi rifiuta altri cinque modelli in base ai punteggi ottenuti finora. Tieni presente che l'addestramento dei 25 modelli prosegue dal checkpoint precedente.
  • Ripeti questo processo finché non restano solo N modelli con una buona distribuzione.
  • Addestra fino al completamento questi ultimi N modelli.

L'impostazione predefinita per N_begin è 30 e si trova come START_NUM_MODELS nel file proxy_task/proxy_task_model_selection_lib_constants.py. L'impostazione predefinita per N è 10 e si trova come FINAL_NUM_MODELS nel file proxy_task/proxy_task_model_selection_lib_constants.py.

Il costo aggiuntivo di questo processo di selezione del modello viene calcolato come segue:

= (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

Tuttavia, rimani al di sopra dell'impostazione N=10. Lo strumento di ricerca per le attività proxy esegue in seguito questi N modelli in parallelo. Assicurati quindi di disporre di una quota GPU sufficiente. Ad esempio, se l'attività proxy utilizza due GPU per un modello, la quota dovrebbe essere di almeno 2*N GPU.

Per il job di selezione dei modelli, utilizza la stessa partizione del set di dati del job di addestramento completo fase 2 e la stessa configurazione di addestramento per l'addestramento completo di riferimento.

Ora è tutto pronto per avviare il job di selezione del modello eseguendo il comando seguente (è necessario un account di servizio):

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"

Una volta avviato questo job del controller di selezione del modello, viene ricevuto un link al job. Il nome job inizia con il prefisso Model_Selection_. Di seguito è mostrato un esempio di UI del job:

Job di selezione modello

model_selection_dir contiene tutti gli output. Controlla i log facendo clic sul link View logs. Per impostazione predefinita, questo job del controller di selezione dei modelli utilizza una CPU su Google Cloud da eseguire in background come job personalizzato, quindi avvia e gestisce job NAS secondari per ogni iterazione della selezione del modello.

Job personalizzati e nas

Ogni job NAS secondario ha un nome come <your_job_name>_iter_3 (tranne l'iterazione 0). Viene eseguita una sola iterazione alla volta. A ogni iterazione, il numero di modelli (numero di prove) si riduce e la durata dell'addestramento aumenta. Al termine di ogni iterazione, ogni job NAS salva il file gs://<job-output-dir>/search/filtered_trial_scores.png, che mostra visivamente quali modelli sono stati rifiutati in questa iterazione. Puoi anche eseguire questo comando:

gsutil cat gs://<path to 'model_selection_dir'>/MODEL_SELECTION_STATE.json

che mostra un riepilogo delle iterazioni e dello stato attuale del job del controller di selezione del modello, il nome del job e i link per ogni iterazione:

{
  "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": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/locations/europe-west4/training/2111217356469436416/cpu?project=my-project",
      "latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/6909239809479278592",
      "latency_calculator_job_link": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/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": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/locations/europe-west4/training/7045544066951413760/cpu?project=my-project",
      "latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/2790768318993137664",
      "latency_calculator_job_link": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/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": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/locations/europe-west4/training/2742864796394192896/cpu?project=my-project",
      "latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/1490864099985195008",
      "latency_calculator_job_link": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/locations/europe-west4/training/1490864099985195008/cpu?project=my-project",
      "desired_training_step_pct": 101.0
    }
  ]
}

L'ultima iterazione contiene il numero finale di modelli di riferimento con una buona distribuzione del punteggio. Questi modelli e i relativi punteggi vengono utilizzati per la ricerca delle attività proxy. Se l'intervallo di punteggio di accuratezza e latenza finale per i modelli di riferimento sembra migliore o simile al modello di riferimento esistente, il che fornisce un'indicazione precoce valida sul tuo spazio di ricerca. Se l'intervallo del punteggio di latenza e di accuratezza finale è notevolmente inferiore alla base di riferimento, riesamina lo spazio di ricerca.

Tieni presente che, se oltre il 20% delle prove nella prima iterazione ha esito negativo, annulla il job di selezione del modello e identifica la causa principale degli errori. Potrebbe trattarsi di un problema legato allo spazio di ricerca o alle impostazioni relative a dimensioni del batch e tasso di apprendimento.

Utilizzo di un dispositivo di latenza on-premise per la selezione del modello

Per utilizzare il dispositivo di latenza on-premise per la selezione del modello, esegui il comando select_proxy_task_models senza i flag di latenza e Docker, perché non vuoi avviare il docker di latenza su Google Cloud. Quindi, utilizza il comando run_latency_calculator_local descritto in Tutorial 4 per avviare il job del Calcolatore della latenza on-premise. Anziché passare il flag --search_job_id, passa il flag --controller_job_id con l'ID job numerico di selezione del modello che ottieni dopo aver eseguito il comando select_proxy_task_models.

Ripresa del job del controller di selezione del modello

Le seguenti situazioni richiedono di riprendere il job del controller di selezione dei modelli:

  • Il job del controller di selezione del modello padre si spegne (caso raro).
  • Annulla inavvertitamente il job del controller di selezione del modello.

Innanzitutto, non annullare il job di iterazione NAS secondario (scheda NAS) se è già in esecuzione. Quindi, per riprendere il job del controller di selezione del modello padre, esegui il comando select_proxy_task_models come prima, ma questa volta supera il flag --previous_model_selection_dir e impostalo sulla directory di output del job del controller di selezione del modello precedente. Il job del controller di selezione dei modelli ripristinato carica il suo stato precedente dalla directory e continua a funzionare come prima.

Dopo aver trovato i modelli di correlazione-candidato e i loro punteggi completi per l'addestramento, il passaggio successivo è utilizzarli per valutare i punteggi di correlazione per le diverse scelte di attività proxy e scegliere l'attività proxy ottimale. Il nostro strumento di ricerca per le attività proxy può trovare automaticamente un'attività proxy che offre quanto segue:

  • Il costo di ricerca NAS più basso.
  • Soddisfa una soglia minima del requisito di correlazione dopo aver fornito una definizione di spazio di ricerca per attività proxy.

Ricorda che esistono tre dimensioni comuni per cercare un'attività proxy ottimale, tra cui:

  • Riduzione del numero di passaggi di addestramento.
  • Quantità ridotta di dati di addestramento.
  • Scalabilità del modello ridotta.

Puoi creare uno spazio di ricerca per attività proxy discreto campionando queste dimensioni come mostrato qui:

Griglia dello spazio di ricerca delle attività proxy

I valori percentuali riportati sopra sono impostati solo come suggerimento e esempio approssimativi. In pratica, puoi scegliere qualsiasi opzione discreta. Tieni presente che non abbiamo incluso la dimensione relativa ai passaggi di addestramento nello spazio di ricerca riportato sopra. Questo perché lo strumento di ricerca per attività proxy determina il passaggio di addestramento ottimale in base all'attività proxy scelta. Prendi in considerazione un'attività proxy scelta come [50% training data, 25% model scale]. Imposta il numero di passaggi di addestramento sulla stessa quantità utilizzata per l'addestramento di base completo. Durante la valutazione di questa attività proxy, lo strumento di ricerca delle attività proxy avvia l'addestramento per i modelli di correlazione-candidato, monitora i punteggi di accuratezza attuali e calcola continuamente il punteggio di correlazione tra ranking (utilizzando i punteggi di addestramento completo precedenti per i modelli di riferimento):

Correlazione e passaggi di addestramento

Di conseguenza, lo strumento di ricerca per l'attività proxy può interrompere l'addestramento dell'attività proxy una volta ottenuta la correlazione desiderata (ad esempio 0,65) o può interrompersi anche in anticipo se viene superata la quota del costo di ricerca (ad esempio il limite di 3 ore per attività proxy). Pertanto, non dovrai eseguire ricerche esplicite nei passaggi di addestramento. Lo strumento di ricerca delle attività proxy valuta ogni attività proxy dal tuo spazio di ricerca discreto come ricerca a griglia e offre l'opzione migliore.

Di seguito è riportato un MnasNetesempio di definizione dello spazio di ricerca per attività proxy mnasnet_proxy_task_config_generator, definito in un file proxy_task/proxy_task_search_spaces.py, che illustra come è possibile definire il proprio spazio di ricerca:

# 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

In questo esempio, creiamo uno spazio di ricerca semplice su percentuale di dati di addestramento 25, 50, 75 e 95. Tieni presente che il 100% dei dati di addestramento non viene utilizzato per la ricerca fase1. La funzione mnasnet_proxy_task_config_generator utilizza un modello di riferimento comune per gli argomenti Docker di addestramento, quindi modifica questi argomenti per ogni dimensione dei dati di addestramento per le attività proxy desiderate. Quindi, restituisce un elenco di proxy-task-config che viene successivamente elaborato dallo strumento di ricerca proxy-task una alla volta nello stesso ordine. Ogni configurazione di attività proxy ha un name e un docker_args_map, che è una mappa chiave-valore per gli argomenti docker proxy-task.

Sei libero di implementare la tua definizione dello spazio di ricerca in base alle tue esigenze e di progettare i tuoi spazi di ricerca delle attività proxy anche per più delle due dimensioni dei dati di addestramento ridotti o della riduzione della scalabilità dei modelli. Tuttavia, non è consigliabile eseguire una ricerca esplicita nei passaggi di addestramento perché questo comporta sprechi di calcolo ripetuto. Consenti allo strumento di ricerca proxy-task di gestire questa dimensione per te.

Per la tua prima ricerca di attività proxy, puoi provare a ridurre solo i dati di addestramento (come nell'esempio MnasNet) e saltare la scalabilità del modello ridotta perché può includere più parametri su image-size, num-filters o num-blocks. Nella maggior parte dei casi, la riduzione dei dati di addestramento (e la ricerca implicita rispetto ai passaggi di addestramento ridotti) è sufficiente per trovare un'attività proxy valida.

Imposta il numero di passaggi di addestramento sul numero usato nell'addestramento completo di riferimento. Esistono differenze tra le configurazioni di addestramento per l'addestramento completo della fase 2 e quelle dell'addestramento del proxy per la fase 1. Per l'attività proxy, devi ridurre il batch-size rispetto alla configurazione di addestramento di riferimento per utilizzare solo 2 GPU o 4 GPU. In genere, l'addestramento completo utilizza 4 GPU, 8 GPU o più, ma l'attività proxy utilizza solo 2 GPU o 4 GPU. Un'altra differenza è la suddivisione di addestramento e convalida. Ecco un esempio di modifiche alla configurazione MnasNet che passa da 4 GPU per l'addestramento completo di fase 2 a 2 GPU e a una suddivisione di convalida diversa per la ricerca di attività proxy:

Configurazione attività proxy

Avvia il job del controller di ricerca proxy-task eseguendo questo comando (è necessario un account di servizio):

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"

Dopo aver avviato questo job del controller di ricerca con attività proxy, viene ricevuto un link al job. Il nome del job inizia con il prefisso Search_controller_. Di seguito è mostrato un esempio di UI del job:

Job di ricerca attività proxy

search_controller_dir conterrà tutti gli output e potrai controllare i log facendo clic sul link View logs. Questo job utilizza per impostazione predefinita una CPU sul cloud per l'esecuzione in background come job personalizzato, quindi avvia e gestisce i job NAS secondari per ogni valutazione delle attività proxy.

Job personalizzati e nas

Ogni job NAS per un'attività proxy ha un nome, ad esempio ProxyTask_<your-job-name>_<proxy-task-name>, dove <proxy-task-name> è quello fornito dal modulo del generatore di configurazione proxy-task per ogni attività proxy. Viene eseguita una sola valutazione di attività proxy alla volta. Puoi anche eseguire questo comando:

gsutil cat gs://<path to 'search_controller_dir'>/SEARCH_CONTROLLER_STATE.json

Questo comando mostra un riepilogo di tutte le valutazioni delle attività proxy e lo stato attuale del job del controller di ricerca, del nome del job e dei link per ogni valutazione:

{
  "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": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/locations/europe-west4/training/4173661476642357248/cpu?project=my-project",
      "latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/8785347495069745152",
      "latency_calculator_job_link": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/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": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/locations/europe-west4/training/2341822328209408000/cpu?project=my-project",
      "latency_calculator_job_name": "projects/123456/locations/europe-west4/customJobs/7575005095213924352",
      "latency_calculator_job_link": "http://console.cloud.go888ogle.com.fqhub.com/vertex-ai/locations/europe-west4/training/7575005095213924352/cpu?project=my-project"
    }
  },
  "best_proxy_task_name": "mnasnet_proxy_training_data_pct_75"
}

L'proxy_tasks_map archivia l'output per ogni valutazione dell'attività proxy e best_proxy_task_name registra l'attività proxy migliore per la ricerca. Ogni voce dell'attività proxy contiene dati aggiuntivi, come proxy_task_stats, che registra l'avanzamento della correlazione di accuratezza, i relativi valori p, l'accuratezza mediana e il tempo di addestramento medio nei passaggi di addestramento. Registra inoltre la correlazione correlata alla latenza, se applicabile, e registra il motivo per l'interruzione di questo job (ad esempio il superamento del limite del tempo di addestramento) e la fase di addestramento in cui si interrompe. Puoi anche visualizzare queste statistiche come grafici copiando i contenuti di search_controller_dir nella cartella locale eseguendo questo comando:

gsutil -m cp gs://<path to 'search_controller_dir'>/* /your/local/dir

e ispezionare le immagini della trama. Ad esempio, il grafico seguente mostra la correlazione di accuratezza con il tempo di addestramento per l'attività proxy migliore:

Correlazione di accuratezza e tempo di addestramento

La ricerca è stata completata e hai trovato la configurazione migliore per le attività proxy, devi fare quanto segue:

  • Imposta il numero di passaggi di addestramento sul valore final_training_steps dell'attività proxy vincente.
  • Imposta i passi di decadimento coseno come final_training_steps in modo che il tasso di apprendimento diventi quasi zero verso la fine.
  • [Facoltativo] Esegui una valutazione del punteggio di convalida alla fine del corso, in modo da risparmiare più costi di valutazione.

Per utilizzare un dispositivo di latenza on-premise per la ricerca di attività proxy, esegui il comando search_proxy_task senza i flag del docker di latenza e del Docker di latenza, in quanto non vuoi avviare il Docker di latenza su Google Cloud. Quindi, utilizza il comando run_latency_calculator_local descritto in Tutorial 4 per avviare il job del Calcolatore della latenza on-premise. Anziché passare il flag --search_job_id, passa il flag --controller_job_id con l'ID job numerico proxy-task-search che ottieni dopo aver eseguito il comando search_proxy_task.

Le seguenti situazioni richiedono di riprendere il job del controller di ricerca per l'attività proxy:

  • Il job del controller di ricerca dell'attività proxy principale non è più disponibile (caso raro).
  • Annulla inavvertitamente il job del controller di ricerca per l'attività proxy.
  • Vuoi estendere lo spazio di ricerca dell'attività proxy in un secondo momento (anche dopo molti giorni).

Innanzitutto, non annullare il job di iterazione NAS secondario (scheda NAS) se è già in esecuzione. Quindi, per riprendere il job del controller di ricerca proxy-task principale, esegui il comando search_proxy_task come prima, ma questa volta supera il flag --previous_proxy_task_search_dir e impostalo sulla directory di output del job del controller di ricerca proxy-task precedente. Il job del controller di ricerca con attività proxy ripristinato carica il suo stato precedente dalla directory e continua a funzionare come prima.

Controlli finali

Due controlli finali dell'attività proxy includono l'intervallo di premi e il salvataggio dei dati per l'analisi post-ricerca.

Intervallo di premi

Il premio segnalato al controller deve essere compreso nell'intervallo [1e-3, 10]. Se non è così, puoi scalare artificialmente il premio per raggiungere questo obiettivo.

Salvare i dati per l'analisi post-ricerca

Il codice dell'attività del proxy dovrebbe salvare eventuali metriche e dati aggiuntivi nella posizione di spazio di archiviazione sul cloud, il che potrebbe essere utile per analizzare lo spazio di ricerca in un secondo momento. La nostra piattaforma Neural Architecture Search supporta solo fino a cinque other_metrics in virgola mobile. Eventuali metriche aggiuntive dovrebbero essere salvate nella posizione di spazio di archiviazione sul cloud per analisi successive.