Google Cloud를 사용하여 와이드 앤 딥 모델 조정

TensorFlow.org에서 보기 Google Colab에서 실행 GitHub에서 보기 노트북 다운로드 캐글 로고캐글에서 실행

이 예에서는 CloudTuner와 Google Cloud를 사용하여 와이드, 딥, 크로스 네트워크를 통한 구조화된 데이터 학습 에 도입된 조정 가능한 모델을 기반으로 와이드 앤 딥 모델을 조정합니다. 이 예에서는 CAIIS Dogfood Day 의 데이터 세트를 사용합니다.

필수 모듈 가져오기

import datetime
import uuid

import numpy as np
import pandas as pd
import tensorflow as tf
import os
import sys
import subprocess

from tensorflow.keras import datasets, layers, models
from sklearn.model_selection import train_test_split

# Install the latest version of tensorflow_cloud and other required packages.
if os.environ.get("TF_KERAS_RUNNING_REMOTELY", True):
    subprocess.run(
        ['python3', '-m', 'pip', 'install', 'tensorflow-cloud', '-q'])
    subprocess.run(
        ['python3', '-m', 'pip', 'install', 'google-cloud-storage', '-q'])
    subprocess.run(
        ['python3', '-m', 'pip', 'install', 'fsspec', '-q'])
    subprocess.run(
        ['python3', '-m', 'pip', 'install', 'gcsfs', '-q'])

import tensorflow_cloud as tfc
print(tfc.__version__)
0.1.15
tf.version.VERSION
'2.6.0'

프로젝트 구성

프로젝트 매개변수 설정. Google Cloud 특정 매개변수에 대한 자세한 내용은 Google Cloud 프로젝트 설정 지침을 참조하세요.

# Set Google Cloud Specific parameters

# TODO: Please set GCP_PROJECT_ID to your own Google Cloud project ID.
GCP_PROJECT_ID = 'YOUR_PROJECT_ID' 

# TODO: Change the Service Account Name to your own Service Account
SERVICE_ACCOUNT_NAME = 'YOUR_SERVICE_ACCOUNT_NAME'
SERVICE_ACCOUNT = f'{SERVICE_ACCOUNT_NAME}@{GCP_PROJECT_ID}.iam.gserviceaccount.com'

# TODO: set GCS_BUCKET to your own Google Cloud Storage (GCS) bucket.
GCS_BUCKET = 'YOUR_GCS_BUCKET_NAME'

# DO NOT CHANGE: Currently only the 'us-central1' region is supported.
REGION = 'us-central1'
# Set Tuning Specific parameters

# OPTIONAL: You can change the job name to any string.
JOB_NAME = 'wide_and_deep'

# OPTIONAL: Set Number of concurrent tuning jobs that you would like to run.
NUM_JOBS = 5

# TODO: Set the study ID for this run. Study_ID can be any unique string.
# Reusing the same Study_ID will cause the Tuner to continue tuning the
# Same Study parameters. This can be used to continue on a terminated job,
# or load stats from a previous study.
STUDY_NUMBER = '00001'
STUDY_ID = f'{GCP_PROJECT_ID}_{JOB_NAME}_{STUDY_NUMBER}'

# Setting location were training logs and checkpoints will be stored
GCS_BASE_PATH = f'gs://{GCS_BUCKET}/{JOB_NAME}/{STUDY_ID}'
TENSORBOARD_LOGS_DIR = os.path.join(GCS_BASE_PATH,"logs")

Google Cloud 프로젝트를 사용하기 위해 노트북 인증

Kaggle Notebooks의 경우 아래 셀을 실행하기 전에 "추가 기능"->"Google Cloud SDK"를 클릭하세요.

# Using tfc.remote() to ensure this code only runs in notebook
if not tfc.remote():

    # Authentication for Kaggle Notebooks
    if "kaggle_secrets" in sys.modules:
        from kaggle_secrets import UserSecretsClient
        UserSecretsClient().set_gcloud_credentials(project=GCP_PROJECT_ID)

    # Authentication for Colab Notebooks
    if "google.colab" in sys.modules:
        from google.colab import auth
        auth.authenticate_user()
        os.environ["GOOGLE_CLOUD_PROJECT"] = GCP_PROJECT_ID

데이터 로드

원시 데이터를 읽고 분할하여 데이터 세트를 훈련하고 테스트합니다. 이 단계에서는 학습 중에 액세스할 수 있도록 데이터 세트를 GCS 버킷에 복사해야 합니다. 이 예에서는 https://www.kaggle.com/c/caiis-dogfood-day-2020 의 데이터 세트를 사용합니다.

이렇게 하려면 다음 명령을 실행하여 데이터 세트를 다운로드하고 GCS 버킷에 복사하거나 Kaggle UI 로 데이터 세트를 수동으로 다운로드하고 train.csv 파일을 GCS 버킷 vi GCS UI 에 업로드할 수 있습니다.

# Download the dataset
kaggle competitions download -c caiis-dogfood-day-2020

# Copy the training file to your bucket
gsutil cp ./caiis-dogfood-day-2020/train.csv $GCS_BASE_PATH/caiis-dogfood-day-2020/train.csv
train_URL = f'{GCS_BASE_PATH}/caiis-dogfood-day-2020/train.csv'
data = pd.read_csv(train_URL)
train, test = train_test_split(data, test_size=0.1)
# A utility method to create a tf.data dataset from a Pandas Dataframe
def df_to_dataset(df, shuffle=True, batch_size=32):
  df = df.copy()
  labels = df.pop('target')
  ds = tf.data.Dataset.from_tensor_slices((dict(df), labels))
  if shuffle:
    ds = ds.shuffle(buffer_size=len(df))
  ds = ds.batch(batch_size)
  return ds
sm_batch_size = 1000  # A small batch size is used for demonstration purposes
train_ds = df_to_dataset(train, batch_size=sm_batch_size)
test_ds = df_to_dataset(test, shuffle=False, batch_size=sm_batch_size)

데이터 전처리

범주형 및 숫자형 입력 데이터에 대한 전처리 레이어 설정 레이어 전처리에 대한 자세한 내용은 레이어 전처리 작업을 참조하세요.

from tensorflow.keras.layers.experimental import preprocessing

def create_model_inputs():
    inputs ={}
    for name, column in data.items():
        if name in ('id','target'):
            continue
        dtype = column.dtype
        if dtype == object:
            dtype = tf.string
        else:
            dtype = tf.float32

        inputs[name] = tf.keras.Input(shape=(1,), name=name, dtype=dtype)

    return inputs
#Preprocessing the numeric inputs, and running them through a normalization layer.
def preprocess_numeric_inputs(inputs):

    numeric_inputs = {name:input for name,input in inputs.items()
                      if input.dtype==tf.float32}

    x = layers.Concatenate()(list(numeric_inputs.values()))
    norm = preprocessing.Normalization()
    norm.adapt(np.array(data[numeric_inputs.keys()]))
    numeric_inputs = norm(x)
    return numeric_inputs
# Preprocessing the categorical inputs.
def preprocess_categorical_inputs(inputs):
    categorical_inputs = []
    for name, input in inputs.items():
        if input.dtype == tf.float32:
            continue

        lookup = preprocessing.StringLookup(vocabulary=np.unique(data[name]))
        one_hot = preprocessing.CategoryEncoding(max_tokens=lookup.vocab_size())

        x = lookup(input)
        x = one_hot(x)
        categorical_inputs.append(x)

    return layers.concatenate(categorical_inputs)

모델 아키텍처 및 하이퍼파라미터 정의

이 섹션에서는 Keras Tuner 하이퍼 매개변수 와 모델 구축 기능을 사용하여 튜닝 매개변수를 정의합니다. 모델 구축 함수는 hp.Int('units', min_value=32, max_value=512, step=32)(특정 범위의 정수)와 같은 하이퍼파라미터를 샘플링할 수 있는 인수 hp를 사용합니다.

import kerastuner

# Configure the search space
HPS = kerastuner.engine.hyperparameters.HyperParameters()
HPS.Float('learning_rate', min_value=1e-4, max_value=1e-2, sampling='log')

HPS.Int('num_layers', min_value=2, max_value=5)
for i in range(5):
    HPS.Float('dropout_rate_' + str(i), min_value=0.0, max_value=0.3, step=0.1)
    HPS.Choice('num_units_' + str(i), [32, 64, 128, 256])
from tensorflow.keras import layers
from tensorflow.keras.optimizers import Adam


def create_wide_and_deep_model(hp):

    inputs = create_model_inputs()
    wide = preprocess_categorical_inputs(inputs)
    wide = layers.BatchNormalization()(wide)

    deep = preprocess_numeric_inputs(inputs)
    for i in range(hp.get('num_layers')):
        deep = layers.Dense(hp.get('num_units_' + str(i)))(deep)
        deep = layers.BatchNormalization()(deep)
        deep = layers.ReLU()(deep)
        deep = layers.Dropout(hp.get('dropout_rate_' + str(i)))(deep)

    both = layers.concatenate([wide, deep])
    outputs = layers.Dense(1, activation='sigmoid')(both)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    metrics = [
        tf.keras.metrics.Precision(name='precision'),
        tf.keras.metrics.Recall(name='recall'),
        'accuracy',
        'mse'
    ]

    model.compile(
        optimizer=Adam(lr=hp.get('learning_rate')),
        loss='binary_crossentropy',
        metrics=metrics)
    return model

CloudTuner 구성

이 섹션에서는 원격 및 로컬 실행을 위해 클라우드 튜너를 구성합니다. 둘의 가장 큰 차이점은 유통 전략이다.

from tensorflow_cloud import CloudTuner

distribution_strategy = None
if not tfc.remote():
    # Using MirroredStrategy to use a single instance with multiple GPUs
    # during remote execution while using no strategy for local.
    distribution_strategy = tf.distribute.MirroredStrategy()

tuner = CloudTuner(
    create_wide_and_deep_model,
    project_id=GCP_PROJECT_ID,
    project_name=JOB_NAME,
    region=REGION,
    objective='accuracy',
    hyperparameters=HPS,
    max_trials=100,
    directory=GCS_BASE_PATH,
    study_id=STUDY_ID,
    overwrite=True,
    distribution_strategy=distribution_strategy)
# Configure Tensorboard logs
callbacks=[
    tf.keras.callbacks.TensorBoard(log_dir=TENSORBOARD_LOGS_DIR)]

# Setting to run tuning remotely, you can run tuner locally to validate it works first.
if tfc.remote():
    tuner.search(train_ds, epochs=20, validation_data=test_ds, callbacks=callbacks)

# You can uncomment the code below to run the tuner.search() locally to validate
# everything works before submitting the job to Cloud. Stop the job manually
# after one epoch.

# else:
#     tuner.search(train_ds, epochs=1, validation_data=test_ds, callbacks=callbacks)

원격 훈련 시작

이 단계에서는 원격 실행을 위해 이 노트북의 코드를 준비하고 NUM_JOBS개의 병렬 실행을 원격으로 시작하여 모델을 교육합니다. 작업이 제출되면 다음 단계로 이동하여 Tensorboard를 통해 작업 진행 상황을 모니터링할 수 있습니다.

tfc.run_cloudtuner(
    distribution_strategy='auto',
    docker_config=tfc.DockerConfig(
        image_build_bucket=GCS_BUCKET
        ),
    chief_config=tfc.MachineConfig(
        cpu_cores=16,
        memory=60,
    ),
    job_labels={'job': JOB_NAME},
    service_account=SERVICE_ACCOUNT,
    num_jobs=NUM_JOBS
)

훈련 결과

Colab 인스턴스를 다시 연결하세요.

대부분의 원격 훈련 작업은 장기간 실행됩니다. Colab을 사용하는 경우 훈련 결과를 확인하기 전에 시간 초과될 수 있습니다. 이 경우 다음 섹션을 다시 실행하여 학습 결과에 액세스할 수 있도록 Colab 인스턴스를 다시 연결하고 구성하세요. 다음 섹션을 순서대로 실행하세요.

  1. 필수 모듈 가져오기
  2. 프로젝트 구성
  3. Google Cloud 프로젝트를 사용하기 위해 노트북 인증

텐서보드 로드

훈련이 진행되는 동안 Tensorboard를 사용하여 결과를 볼 수 있습니다. 결과는 훈련이 시작된 후에만 표시됩니다. 이 작업은 몇 분 정도 걸릴 수 있습니다.

%load_ext tensorboard
%tensorboard --logdir $TENSORBOARD_LOGS_DIR

다음과 같이 교육 자산에 액세스할 수 있습니다. 결과는 튜닝 작업이 최소 한 번 이상 완료된 후에만 표시됩니다. 이 작업은 몇 분 정도 걸릴 수 있습니다.

if not tfc.remote():
    tuner.results_summary(1)
    best_model = tuner.get_best_models(1)[0]
    best_hyperparameters = tuner.get_best_hyperparameters(1)[0]

    # References to best trial assets
    best_trial_id = tuner.oracle.get_best_trials(1)[0].trial_id
    best_trial_dir = tuner.get_trial_dir(best_trial_id)