Pelatihan dan penyesuaian hyperparameter model PyTorch di Cloud AI Platform

1. Ringkasan

Di lab ini, Anda akan mengikuti alur kerja pelatihan ML lengkap di Google Cloud, menggunakan PyTorch untuk membangun model. Dari lingkungan Cloud AI Platform Notebooks, Anda akan mempelajari cara memaketkan tugas pelatihan untuk menjalankannya di Pelatihan AI Platform dengan penyesuaian hyperparameter.

Yang Anda pelajari

Anda akan mempelajari cara:

  • Membuat instance AI Platform Notebooks
  • Membuat model PyTorch
  • Latih model Anda dengan penyesuaian hyperparameter pada Pelatihan AI Platform

Total biaya untuk menjalankan lab ini di Google Cloud adalah sekitar $1.

2. Menyiapkan lingkungan Anda

Anda memerlukan project Google Cloud Platform dengan penagihan yang diaktifkan untuk menjalankan codelab ini. Untuk membuat project, ikuti petunjuk di sini.

Langkah 1: Aktifkan Cloud AI Platform Models API

Buka bagian AI Platform Models di Cloud Console Anda, lalu klik Enable jika belum diaktifkan.

d0d38662851c6af3.png

Langkah 2: Aktifkan Compute Engine API

Buka Compute Engine dan pilih Aktifkan jika belum diaktifkan. Anda akan memerlukan ini untuk membuat instance notebook.

Langkah 3: Membuat instance AI Platform Notebooks

Buka bagian AI Platform Notebooks di Konsol Cloud Anda, lalu klik New Instance. Kemudian, pilih jenis instance PyTorch terbaru (tanpa GPU):

892b7588f940d145.pngS

Gunakan opsi default atau beri nama khusus jika Anda mau, lalu klik Buat. Setelah instance dibuat, pilih Open JupyterLab:

63d2cf44801c2df5.png

Selanjutnya, buka instance Notebook Python 3 dari peluncur:

de4c86c6c7f9438f.png

Anda sudah siap untuk memulai!

Langkah 5: Impor paket Python

Di sel pertama notebook Anda, tambahkan impor berikut dan jalankan sel. Anda dapat menjalankannya dengan menekan tombol panah kanan di menu atas atau menekan command-enter:

import datetime
import numpy as np
import os
import pandas as pd
import time

Anda akan melihat bahwa kita tidak mengimpor PyTorch di sini. Hal ini karena kita sedang menjalankan tugas pelatihan pada Pelatihan AI Platform, bukan dari instance Notebook kita.

3. Membuat paket untuk tugas pelatihan

Untuk menjalankan tugas pelatihan tentang Pelatihan AI Platform, kita memerlukan kode pelatihan yang dikemas secara lokal di instance Notebooks, dan bucket Cloud Storage untuk menyimpan aset tugas. Pertama, kita akan membuat bucket penyimpanan. Anda dapat melewati langkah ini jika sudah memilikinya.

Langkah 1: Buat bucket Cloud Storage untuk model kita

Pertama-tama, mari kita tentukan beberapa variabel lingkungan yang akan kita gunakan pada seluruh codelab ini. Isi nilai di bawah ini dengan nama project Google Cloud Anda dan nama bucket Cloud Storage yang ingin Anda buat (harus unik secara global):

# Update these to your own GCP project, model, and version names
GCP_PROJECT = 'your-gcp-project'
BOCKET_URL = 'gs://storage_bucket_name'

Sekarang kita siap membuat bucket penyimpanan, yang akan kita tunjuk saat memulai tugas pelatihan.

Jalankan perintah gsutil ini dari dalam notebook Anda untuk membuat bucket:

!gsutil mb $BUCKET_URL

Langkah 2: Buat file awal untuk paket Python

Untuk menjalankan tugas pelatihan di AI Platform, kita harus mengonfigurasi kode sebagai paket Python. Ini terdiri dari file setup.py dalam direktori utama kita yang menentukan dependensi paket eksternal, subdirektori dengan nama paket (di sini kita menyebutnya trainer/), dan file __init__.py kosong dalam subdirektori ini.

Pertama, mari kita tulis file {i>setup.py<i}. Kita menggunakan keajaiban %%writefile iPython untuk menyimpan file ke instance kita. Di sini kita telah menentukan 3 library eksternal yang akan kita gunakan dalam kode pelatihan: PyTorch, Scikit-learn, dan Pandas:

%%writefile setup.py
from setuptools import find_packages
from setuptools import setup

REQUIRED_PACKAGES = ['torch>=1.5', 'scikit-learn>=0.20', 'pandas>=1.0']

setup(
    name='trainer',
    version='0.1',
    install_requires=REQUIRED_PACKAGES,
    packages=find_packages(),
    include_package_data=True,
    description='My training application package.'
)

Selanjutnya, mari buat direktori trainer/ dan file init.py kosong di dalamnya. Python menggunakan file ini untuk mengenali bahwa ini adalah sebuah paket:

!mkdir trainer
!touch trainer/__init__.py

Sekarang kita siap untuk mulai membuat tugas pelatihan.

4. Melihat pratinjau set data

Fokus lab ini adalah alat untuk melatih model di sini, tetapi mari kita lihat sekilas set data yang akan kita gunakan untuk melatih model agar dapat dipahami. Kita akan menggunakan set data kelahiran yang tersedia di BigQuery. Ini berisi data kelahiran dari Amerika Serikat selama beberapa dekade. Kita akan menggunakan beberapa kolom dari {i>dataset<i} itu untuk memprediksi berat lahir bayi. Set data asli cukup besar, dan kami akan menggunakan subset yang telah kami sediakan untuk Anda di bucket Cloud Storage.

Langkah 1: Mendownload set data kelahiran BigQuery

Mari download versi set data yang telah disediakan untuk Anda di Cloud Storage ke DataFrame Pandas dan lihat pratinjaunya.

natality = pd.read_csv('https://storage.googleapis.com/ml-design-patterns/natality.csv')
natality.head()

{i>Dataset<i} ini berisi kurang dari 100.000 baris. Kami akan menggunakan 5 fitur untuk memprediksi berat lahir bayi: usia ibu dan ayah, minggu kehamilan, pertambahan berat ibu dalam pound, dan jenis kelamin bayi direpresentasikan sebagai boolean.

5. Menentukan tugas pelatihan dengan penyesuaian hyperparameter

Kita akan menulis skrip pelatihan kita ke file bernama model.py dalam subdirektori trainer/ yang kita buat sebelumnya. Tugas pelatihan kita akan berjalan pada Pelatihan AI Platform, dan tugas ini juga akan menggunakan layanan penyesuaian hyperparameter AI Platform untuk menemukan hyperparameter yang optimal untuk model kita yang menggunakan pengoptimalan Bayesian.

Langkah 1: Buat skrip pelatihan

Pertama, mari kita buat file Python dengan skrip pelatihan kita. Kemudian kita akan membedah apa yang terjadi di dalamnya. Menjalankan perintah %%writefile ini akan menulis kode model ke file Python lokal:

%%writefile trainer/model.py
import argparse
import hypertune
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim

from sklearn.utils import shuffle
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import normalize

def get_args():
    """Argument parser.
    Returns:
        Dictionary of arguments.
    """
    parser = argparse.ArgumentParser(description='PyTorch MNIST')
    parser.add_argument('--job-dir',  # handled automatically by AI Platform
                        help='GCS location to write checkpoints and export ' \
                             'models')
    parser.add_argument('--lr',  # Specified in the config file
                        type=float,
                        default=0.01,
                        help='learning rate (default: 0.01)')
    parser.add_argument('--momentum',  # Specified in the config file
                        type=float,
                        default=0.5,
                        help='SGD momentum (default: 0.5)')
    parser.add_argument('--hidden-layer-size',  # Specified in the config file
                        type=int,
                        default=8,
                        help='hidden layer size')
    args = parser.parse_args()
    return args

def train_model(args):
    # Get the data
    natality = pd.read_csv('https://storage.googleapis.com/ml-design-patterns/natality.csv')
    natality = natality.dropna()
    natality = shuffle(natality, random_state = 2)
    natality.head()

    natality_labels = natality['weight_pounds']
    natality = natality.drop(columns=['weight_pounds'])


    train_size = int(len(natality) * 0.8)
    traindata_natality = natality[:train_size]
    trainlabels_natality = natality_labels[:train_size]

    testdata_natality = natality[train_size:]
    testlabels_natality = natality_labels[train_size:]

    # Normalize and convert to PT tensors
    normalized_train = normalize(np.array(traindata_natality.values), axis=0)
    normalized_test = normalize(np.array(testdata_natality.values), axis=0)

    train_x = torch.Tensor(normalized_train)
    train_y = torch.Tensor(np.array(trainlabels_natality))

    test_x = torch.Tensor(normalized_test)
    test_y = torch.Tensor(np.array(testlabels_natality))

    # Define our data loaders
    train_dataset = torch.utils.data.TensorDataset(train_x, train_y)
    train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True)

    test_dataset = torch.utils.data.TensorDataset(test_x, test_y)
    test_dataloader = torch.utils.data.DataLoader(test_dataset, batch_size=128, shuffle=False)

    # Define the model, while tuning the size of our hidden layer
    model = nn.Sequential(nn.Linear(len(train_x[0]), args.hidden_layer_size),
                          nn.ReLU(),
                          nn.Linear(args.hidden_layer_size, 1))
    criterion = nn.MSELoss()

    # Tune hyperparameters in our optimizer
    optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)
    epochs = 20
    for e in range(epochs):
        for batch_id, (data, label) in enumerate(train_dataloader):
            optimizer.zero_grad()
            y_pred = model(data)
            label = label.view(-1,1)
            loss = criterion(y_pred, label)
            
            loss.backward()
            optimizer.step()


    val_mse = 0
    num_batches = 0
    # Evaluate accuracy on our test set
    with torch.no_grad():
        for i, (data, label) in enumerate(test_dataloader):
            num_batches += 1
            y_pred = model(data)
            mse = criterion(y_pred, label.view(-1,1))
            val_mse += mse.item()


    avg_val_mse = (val_mse / num_batches)

    # Report the metric we're optimizing for to AI Platform's HyperTune service
    # In this example, we're mimizing error on our test set
    hpt = hypertune.HyperTune()
    hpt.report_hyperparameter_tuning_metric(
        hyperparameter_metric_tag='val_mse',
        metric_value=avg_val_mse,
        global_step=epochs        
    )

def main():
    args = get_args()
    print('in main', args)
    train_model(args)

if __name__ == '__main__':
    main()

Tugas pelatihan terdiri dari dua fungsi di mana sebagian besar pekerjaan terjadi.

  • get_args(): Tindakan ini mengurai argumen command line yang akan kita teruskan saat membuat tugas pelatihan, bersama dengan hyperparameter yang kita inginkan untuk dioptimalkan oleh AI Platform. Dalam contoh ini, daftar argumen hanya menyertakan hyperparameter yang akan kita optimalkan, yaitu kecepatan pemelajaran model, momentum, dan jumlah neuron di lapisan tersembunyi.
  • train_model(): Di sini, kita mendownload data ke DataFrame Pandas, menormalkannya, mengonversinya menjadi PyTorch Tensor, lalu menentukan model. Untuk membangun model, kita menggunakan PyTorch nn.Sequential API, yang memungkinkan kita menentukan model sebagai stack lapisan:
model = nn.Sequential(nn.Linear(len(train_x[0]), args.hidden_layer_size),
                      nn.ReLU(),
                      nn.Linear(args.hidden_layer_size, 1))

Perhatikan bahwa, alih-alih melakukan hardcode ukuran lapisan tersembunyi model, kita membuat hyperparameter yang akan disesuaikan oleh AI Platform untuk kita. Informasi selengkapnya akan dibahas di bagian berikutnya.

Langkah 2: Menggunakan layanan penyesuaian hyperparameter AI Platform

Daripada mencoba nilai hyperparameter yang berbeda dan melatih ulang model secara manual setiap kali, kita akan menggunakan layanan pengoptimalan hyperparameter Cloud AI Platform. Jika kita menyiapkan tugas pelatihan dengan argumen hyperparameter, AI Platform akan menggunakan pengoptimalan Bayesian untuk menemukan nilai ideal untuk hyperparameter yang kita tentukan.

Dalam penyesuaian hyperparameter, satu uji coba terdiri dari satu proses pelatihan model kami dengan kombinasi nilai hyperparameter yang spesifik. Bergantung pada jumlah uji coba yang kami jalankan, AI Platform akan menggunakan hasil uji coba yang telah selesai untuk mengoptimalkan hyperparameter yang dipilihnya untuk hyperparameter pada masa mendatang. Untuk mengonfigurasi penyesuaian hyperparameter, kita harus meneruskan file konfigurasi saat memulai tugas pelatihan dengan beberapa data pada setiap hyperparameter yang kita optimalkan.

Selanjutnya, buat file konfigurasi tersebut secara lokal:

%%writefile config.yaml
trainingInput:
  hyperparameters:
    goal: MINIMIZE
    maxTrials: 10
    maxParallelTrials: 5
    hyperparameterMetricTag: val_mse
    enableTrialEarlyStopping: TRUE
    params:
    - parameterName: lr
      type: DOUBLE
      minValue: 0.0001
      maxValue: 0.1
      scaleType: UNIT_LINEAR_SCALE
    - parameterName: momentum
      type: DOUBLE
      minValue: 0.0
      maxValue: 1.0
      scaleType: UNIT_LINEAR_SCALE
    - parameterName: hidden-layer-size
      type: INTEGER
      minValue: 8
      maxValue: 32
      scaleType: UNIT_LINEAR_SCALE

Untuk setiap hyperparameter, kita menentukan jenis, rentang nilai yang ingin ditelusuri, dan skala untuk meningkatkan nilai di berbagai uji coba.

Di awal tugas, kita juga menentukan metrik yang akan kita optimalkan. Perhatikan bahwa di akhir fungsi train_model() di atas, kami melaporkan metrik ini ke AI Platform setiap kali uji coba selesai. Di sini kita meminimalkan error kuadrat rata-rata model, dan kita ingin menggunakan hyperparameter yang menghasilkan error kuadrat rata-rata terendah untuk model kita. Nama metrik ini (val_mse) cocok dengan nama yang kami gunakan untuk melaporkannya saat memanggil report_hyperparameter_tuning_metric() di akhir uji coba.

6. Menjalankan tugas pelatihan di AI Platform

Di bagian ini, kita akan memulai tugas pelatihan model dengan penyesuaian hyperparameter pada AI Platform.

Langkah 1: Menentukan beberapa variabel lingkungan

Pertama-tama, mari kita tentukan beberapa variabel lingkungan yang akan kita gunakan untuk memulai tugas pelatihan. Jika Anda ingin menjalankan tugas di region yang berbeda, perbarui variabel REGION di bawah:

MAIN_TRAINER_MODULE = "trainer.model"
TRAIN_DIR = os.getcwd() + '/trainer'
JOB_DIR = BUCKET_URL + '/output'
REGION = "us-central1"

Setiap tugas pelatihan di AI Platform harus memiliki nama unik. Jalankan perintah berikut guna menentukan variabel untuk nama tugas Anda menggunakan stempel waktu:

timestamp = str(datetime.datetime.now().time())
JOB_NAME = 'caip_training_' + str(int(time.time()))

Langkah 2: Mulai tugas pelatihan

Kita akan membuat tugas pelatihan menggunakan gcloud, yaitu Google Cloud CLI. Kita dapat menjalankan perintah ini langsung di notebook, dengan merujuk pada variabel yang ditentukan di atas:

!gcloud ai-platform jobs submit training $JOB_NAME \
        --scale-tier basic \
        --package-path $TRAIN_DIR \
        --module-name $MAIN_TRAINER_MODULE \
        --job-dir $JOB_DIR \
        --region $REGION \
        --runtime-version 2.1 \
        --python-version 3.7 \
        --config config.yaml

Jika tugas Anda dibuat dengan benar, buka bagian Tugas pada konsol AI Platform untuk memantau log-nya.

Langkah 3: Pantau tugas Anda

Setelah berada di bagian {i>Jobs<i} pada konsol, klik pekerjaan yang baru saja Anda mulai untuk melihat detailnya:

c184167641bb7ed7.png

Saat uji coba putaran pertama dimulai, Anda akan melihat nilai hyperparameter yang dipilih untuk setiap uji coba:

787c053ef9110e6b.pngS

Setelah uji coba selesai, nilai metrik pengoptimalan yang dihasilkan (dalam kasus ini val_mse) akan dicatat di sini. Tugas akan memerlukan waktu 15-20 menit untuk dijalankan, dan dasbor akan terlihat seperti ini ketika tugas selesai (nilai persisnya akan bervariasi):

47ef6b9b4ecb532c.pngS

Untuk men-debug potensi masalah dan memantau tugas Anda secara lebih mendetail, klik View Logs dari halaman detail tugas:

18c32dcd36351930.pngS

Setiap pernyataan print() dalam kode pelatihan model Anda akan muncul di sini. Jika Anda mengalami masalah, coba tambahkan lebih banyak pernyataan cetak dan mulai tugas pelatihan baru.

Setelah tugas pelatihan Anda selesai, temukan hyperparameter yang menghasilkan val_mse terendah. Anda dapat menggunakannya untuk melatih dan mengekspor versi akhir model, atau menggunakannya sebagai panduan untuk memulai tugas pelatihan lainnya dengan uji coba penyesuaian hyperparameter tambahan.

7. Pembersihan

Jika ingin terus menggunakan notebook ini, sebaiknya nonaktifkan saat tidak digunakan. Dari UI Notebooks di Konsol Cloud, pilih notebook, lalu pilih Stop:

879147427150b6c7.png

Jika ingin menghapus semua resource yang telah dibuat di lab ini, cukup hapus instance notebook, bukan menghentikannya.

Dengan menggunakan menu Navigasi di Konsol Cloud, jelajahi Penyimpanan dan hapus kedua bucket yang Anda buat untuk menyimpan aset model.