Vertex AI Workbench: Latih model TensorFlow dengan data dari BigQuery

1. Ringkasan

Di lab ini, Anda akan mempelajari cara menggunakan Vertex AI Workbench untuk eksplorasi data dan pelatihan model ML.

Yang Anda pelajari

Anda akan mempelajari cara:

  • Membuat dan mengonfigurasi instance Vertex AI Workbench
  • Menggunakan konektor BigQuery Vertex AI Workbench
  • Melatih model di kernel Vertex AI Workbench

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

2. Pengantar Vertex AI

Lab ini menggunakan penawaran produk AI terbaru yang tersedia di Google Cloud. Vertex AI mengintegrasikan penawaran ML di Google Cloud ke dalam pengalaman pengembangan yang lancar. Sebelumnya, model yang dilatih dengan AutoML dan model kustom dapat diakses melalui layanan terpisah. Penawaran baru ini menggabungkan kedua model ini menjadi satu API, beserta produk baru lainnya. Anda juga dapat memigrasikan project yang sudah ada ke Vertex AI.

Vertex AI mencakup banyak produk yang berbeda untuk mendukung alur kerja ML secara menyeluruh. Lab ini akan berfokus pada Vertex AI Workbench.

Vertex AI Workbench membantu pengguna membuat alur kerja berbasis notebook menyeluruh dengan cepat melalui integrasi mendalam dengan layanan data (seperti Dataproc, Dataflow, BigQuery, dan Dataplex) dan Vertex AI. Dengan demikian, data scientist dapat terhubung ke layanan data GCP, menganalisis set data, bereksperimen dengan berbagai teknik pemodelan, men-deploy model terlatih ke produksi, dan mengelola MLOps melalui siklus proses model.

3. Ringkasan Kasus Penggunaan

Di lab ini, Anda akan menjelajahi set data Persewaan Sepeda di London. Data ini berisi informasi tentang perjalanan sepeda dari program berbagi sepeda umum di London sejak tahun 2011. Anda akan memulai dengan menjelajahi set data ini di BigQuery melalui konektor BigQuery Vertex AI Workbench. Kemudian, Anda akan memuat data ke Jupyter Notebook menggunakan pandas dan melatih model TensorFlow untuk memprediksi durasi perjalanan sepeda berdasarkan waktu perjalanan dan jarak yang ditempuh orang tersebut dengan sepeda.

Lab ini menggunakan lapisan prapemrosesan Keras untuk mengubah dan menyiapkan data input untuk pelatihan model. API ini memungkinkan Anda membuat pra-pemrosesan langsung ke dalam grafik model TensorFlow, sehingga mengurangi risiko skew pelatihan/penayangan dengan memastikan bahwa data pelatihan dan data penayangan mengalami transformasi yang identik. Perhatikan bahwa mulai TensorFlow 2.6, API ini stabil. Jika menggunakan TensorFlow versi lama, Anda harus mengimpor simbol eksperimental.

4. 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 Compute Engine API

Buka Compute Engine dan pilih Aktifkan jika belum diaktifkan.

Langkah 2: Aktifkan Vertex AI API

Buka bagian Vertex AI di Cloud Console Anda, lalu klik Aktifkan Vertex AI API.

Dasbor Vertex AI

Langkah 3: Membuat instance Vertex AI Workbench

Dari bagian Vertex AI di Cloud Console Anda, klik Workbench:

Menu Vertex AI

Aktifkan Notebooks API jika belum diaktifkan.

Notebook_api

Setelah diaktifkan, klik NOTEBOOK TERKELOLA:

Notebooks_UI

Kemudian, pilih NOTEBOOK BARU.

new_notebook

Namai notebook Anda, lalu di bagian Izin, pilih Akun layanan

service_account

Pilih Setelan Lanjutan.

Di bagian Keamanan, pilih "Aktifkan terminal" jika belum diaktifkan.

enable_terminal

Anda dapat membiarkan semua setelan lanjutan lainnya apa adanya.

Selanjutnya, klik Buat.

Setelah instance dibuat, pilih BUKA JUPYTERLAB.

enable_terminal

5. Menjelajahi set data di BigQuery

Di instance Vertex AI Workbench, buka sisi kiri dan klik konektor BigQuery in Notebooks.

Konektor BQ

Konektor BigQuery memungkinkan Anda menjelajahi dan membuat kueri set data BigQuery dengan mudah. Selain set data di project Anda, Anda dapat menjelajahi set data di project lain dengan mengklik tombol Tambahkan Project.

sematkan

Untuk lab ini, Anda akan menggunakan data dari set data publik BigQuery. Scroll ke bawah hingga Anda menemukan set data london_bicycles. Anda akan melihat bahwa set data ini memiliki dua tabel, cycle_hire dan cycle_stations. Mari kita pelajari setiap jenis partisipasi.

london_bike_ds

Pertama, klik dua kali tabel cycle_hire. Anda akan melihat bahwa tabel terbuka sebagai tab baru dengan skema tabel serta metadata seperti jumlah baris dan ukuran.

cycle_hire_ds

Jika mengklik tab Preview, Anda akan dapat melihat sampel data. Mari kita jalankan kueri sederhana untuk melihat perjalanan yang populer. Pertama, klik tombol Tabel kueri.

cycle_hire_preview_ds

Kemudian, tempel kode berikut ke editor SQL dan klik Kirim Kueri.

SELECT
  start_station_name,
  end_station_name,
  IF(start_station_name = end_station_name,
    TRUE,
    FALSE) same_station,
  AVG(duration) AS avg_duration,
  COUNT(*) AS total_rides
FROM
  `bigquery-public-data.london_bicycles.cycle_hire`
GROUP BY
  start_station_name,
  end_station_name,
  same_station
ORDER BY
  total_rides DESC

Dari hasil kueri, Anda akan melihat bahwa perjalanan sepeda ke dan dari stasiun Hyde Park Corner adalah yang paling populer.

journey_query_results

Selanjutnya, klik dua kali pada tabel cycle_stations, yang memberikan informasi tentang setiap stasiun.

Kita ingin menggabungkan tabel cycle_hire dan cycle_stations. Tabel cycle_stations berisi lintang/bujur untuk setiap stasiun. Anda akan menggunakan informasi ini untuk memperkirakan jarak yang ditempuh pada setiap perjalanan sepeda dengan menghitung jarak antara stasiun awal dan akhir.

Untuk melakukan penghitungan ini, Anda akan menggunakan fungsi geografi BigQuery. Secara khusus, Anda akan mengonversi setiap string lintang/bujur menjadi ST_GEOGPOINT dan menggunakan fungsi ST_DISTANCE untuk menghitung jarak garis lurus dalam meter di antara kedua titik tersebut. Anda akan menggunakan nilai ini sebagai proxy untuk jarak yang ditempuh dalam setiap perjalanan bersepeda.

Salin kueri berikut ke editor SQL Anda, lalu klik Kirim Kueri. Perhatikan bahwa ada tiga tabel dalam kondisi JOIN karena kita perlu menggabungkan tabel stasiun dua kali untuk mendapatkan lintang/bujur untuk stasiun awal dan stasiun akhir siklus.

WITH staging AS (
    SELECT
        STRUCT(
            start_stn.name,
            ST_GEOGPOINT(start_stn.longitude, start_stn.latitude) AS POINT,
            start_stn.docks_count,
            start_stn.install_date
        ) AS starting,
        STRUCT(
            end_stn.name,
            ST_GEOGPOINT(end_stn.longitude, end_stn.latitude) AS point,
            end_stn.docks_count,
            end_stn.install_date
        ) AS ending,
        STRUCT(
            rental_id,
            bike_id,
            duration, --seconds
            ST_DISTANCE(
                ST_GEOGPOINT(start_stn.longitude, start_stn.latitude),
                ST_GEOGPOINT(end_stn.longitude, end_stn.latitude)
            ) AS distance, --meters
            start_date,
            end_date
        ) AS bike
        FROM `bigquery-public-data.london_bicycles.cycle_stations` AS start_stn
        LEFT JOIN `bigquery-public-data.london_bicycles.cycle_hire` as b
        ON start_stn.id = b.start_station_id
        LEFT JOIN `bigquery-public-data.london_bicycles.cycle_stations` AS end_stn
        ON end_stn.id = b.end_station_id
        LIMIT 700000)

SELECT * from STAGING

6. Melatih model ML pada kernel TensorFlow

Vertex AI Workbench memiliki lapisan kompatibilitas komputasi yang memungkinkan Anda meluncurkan kernel untuk TensorFlow, PySpark, R, dll., semuanya dari satu instance notebook. Di lab ini, Anda akan membuat notebook menggunakan kernel TensorFlow.

Membuat DataFrame

Setelah kueri dieksekusi, klik Salin kode untuk DataFrame. Tindakan ini akan memungkinkan Anda menempelkan kode Python ke notebook yang terhubung ke klien BigQuery dan mengekstrak data ini sebagai DataFrame pandas.

copy_for_df

Selanjutnya, kembali ke Peluncur dan buat notebook TensorFlow 2.

tf_kernel

Di sel pertama notebook, tempel kode yang disalin dari Editor Kueri. Tampilannya akan terlihat seperti berikut:

# The following two lines are only necessary to run once.
# Comment out otherwise for speed-up.
from google.cloud.bigquery import Client, QueryJobConfig
client = Client()

query = """WITH staging AS (
    SELECT
        STRUCT(
            start_stn.name,
            ST_GEOGPOINT(start_stn.longitude, start_stn.latitude) AS POINT,
            start_stn.docks_count,
            start_stn.install_date
        ) AS starting,
        STRUCT(
            end_stn.name,
            ST_GEOGPOINT(end_stn.longitude, end_stn.latitude) AS point,
            end_stn.docks_count,
            end_stn.install_date
        ) AS ending,
        STRUCT(
            rental_id,
            bike_id,
            duration, --seconds
            ST_DISTANCE(
                ST_GEOGPOINT(start_stn.longitude, start_stn.latitude),
                ST_GEOGPOINT(end_stn.longitude, end_stn.latitude)
            ) AS distance, --meters
            start_date,
            end_date
        ) AS bike
        FROM `bigquery-public-data.london_bicycles.cycle_stations` AS start_stn
        LEFT JOIN `bigquery-public-data.london_bicycles.cycle_hire` as b 
        ON start_stn.id = b.start_station_id
        LEFT JOIN `bigquery-public-data.london_bicycles.cycle_stations` AS end_stn
        ON end_stn.id = b.end_station_id
        LIMIT 700000)

SELECT * from STAGING"""
job = client.query(query)
df = job.to_dataframe()

Untuk tujuan lab ini, kita membatasi set data hingga 700.000 agar waktu pelatihan lebih singkat. Namun, jangan ragu untuk mengubah kueri dan bereksperimen dengan seluruh set data.

Selanjutnya, impor library yang diperlukan.

from datetime import datetime
import pandas as pd
import tensorflow as tf

Jalankan kode berikut untuk membuat dataframe yang diperkecil yang hanya berisi kolom yang diperlukan untuk bagian ML dalam latihan ini.

values = df['bike'].values
duration = list(map(lambda a: a['duration'], values))
distance = list(map(lambda a: a['distance'], values))
dates = list(map(lambda a: a['start_date'], values))
data = pd.DataFrame(data={'duration': duration, 'distance': distance, 'start_date':dates})
data = data.dropna()

Kolom start_date adalah Python datetime. Daripada menggunakan datetime ini dalam model secara langsung, Anda akan membuat dua fitur baru yang menunjukkan hari dalam seminggu dan jam saat perjalanan sepeda terjadi.

data['weekday'] = data['start_date'].apply(lambda a: a.weekday())
data['hour'] = data['start_date'].apply(lambda a: a.time().hour)
data = data.drop(columns=['start_date'])

Terakhir, konversikan kolom durasi dari detik ke menit agar lebih mudah dipahami

data['duration'] = data['duration'].apply(lambda x:float(x / 60))

Periksa beberapa baris pertama dari DataFrame yang diformat. Untuk setiap perjalanan sepeda, Anda sekarang memiliki data hari dan jam saat perjalanan terjadi, serta jarak yang ditempuh. Dari informasi ini, Anda akan mencoba memprediksi berapa lama perjalanan tersebut.

data.head()

data_head

Sebelum dapat membuat dan melatih model, Anda perlu membagi data ke dalam set pelatihan dan validasi.

# Use 80/20 train/eval split
train_size = int(len(data) * .8)
print ("Train size: %d" % train_size)
print ("Evaluation size: %d" % (len(data) - train_size))

# Split data into train and test sets
train_data = data[:train_size]
val_data = data[train_size:]

Membuat model TensorFlow

Anda akan membuat model TensorFlow menggunakan Keras Functional API. Untuk memproses data input, Anda akan menggunakan API lapisan prapemrosesan Keras.

Fungsi utilitas berikut akan membuat tf.data.Dataset dari Dataframe pandas.

def df_to_dataset(dataframe, label, shuffle=True, batch_size=32):
  dataframe = dataframe.copy()
  labels = dataframe.pop(label)
  ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
  if shuffle:
    ds = ds.shuffle(buffer_size=len(dataframe))
  ds = ds.batch(batch_size)
  ds = ds.prefetch(batch_size)
  return ds

Gunakan fungsi di atas untuk membuat dua tf.data.Dataset, satu untuk pelatihan dan satu untuk validasi. Anda mungkin melihat beberapa peringatan, tetapi Anda dapat mengabaikannya dengan aman.

train_dataset = df_to_dataset(train_data, 'duration')
validation_dataset = df_to_dataset(val_data, 'duration')

Anda akan menggunakan lapisan prapemrosesan berikut dalam model:

  • Lapisan normalisasi: melakukan normalisasi fitur input berdasarkan fitur.
  • Lapisan IntegerLookup: mengubah nilai kategoris bilangan bulat menjadi indeks bilangan bulat.
  • Lapisan CategoryEncoding: mengubah fitur kategoris bilangan bulat menjadi representasi padat one-hot, multi-hot, atau TF-IDF.

Perhatikan bahwa lapisan ini tidak dapat dilatih. Sebagai gantinya, Anda menetapkan status lapisan prapemrosesan dengan mengeksposnya ke data pelatihan, melalui metode adapt().

Fungsi berikut akan membuat lapisan normalisasi yang dapat Anda gunakan pada fitur jarak. Anda akan menetapkan status sebelum menyesuaikan model menggunakan metode adapt() pada data pelatihan. Tindakan ini akan menghitung rata-rata dan varian yang akan digunakan untuk normalisasi. Kemudian, saat Anda meneruskan set data validasi ke model, rata-rata dan varian yang sama yang dihitung pada data pelatihan akan digunakan untuk menskalakan data validasi.

def get_normalization_layer(name, dataset):
  # Create a Normalization layer for our feature.
  normalizer = tf.keras.layers.Normalization(axis=None)

  # Prepare a Dataset that only yields our feature.
  feature_ds = dataset.map(lambda x, y: x[name])

  # Learn the statistics of the data.
  normalizer.adapt(feature_ds)

  return normalizer

Demikian pula, fungsi berikut membuat encoding kategori yang akan Anda gunakan pada fitur jam dan hari kerja.

def get_category_encoding_layer(name, dataset, dtype, max_tokens=None):
  index = tf.keras.layers.IntegerLookup(max_tokens=max_tokens)

  # Prepare a Dataset that only yields our feature
  feature_ds = dataset.map(lambda x, y: x[name])

  # Learn the set of possible values and assign them a fixed integer index.
  index.adapt(feature_ds)

  # Create a Discretization for our integer indices.
  encoder = tf.keras.layers.CategoryEncoding(num_tokens=index.vocabulary_size())

  # Apply one-hot encoding to our indices. The lambda function captures the
  # layer so we can use them, or include them in the functional model later.
  return lambda feature: encoder(index(feature))

Selanjutnya, buat bagian pra-pemrosesan pada model. Pertama, buat lapisan tf.keras.Input untuk setiap fitur.

# Create a Keras input layer for each feature
numeric_col = tf.keras.Input(shape=(1,), name='distance')
hour_col = tf.keras.Input(shape=(1,), name='hour', dtype='int64')
weekday_col = tf.keras.Input(shape=(1,), name='weekday', dtype='int64')

Kemudian buat lapisan encoding normalisasi dan kategori, dengan menyimpannya dalam sebuah daftar.

all_inputs = []
encoded_features = []

# Pass 'distance' input to normalization layer
normalization_layer = get_normalization_layer('distance', train_dataset)
encoded_numeric_col = normalization_layer(numeric_col)
all_inputs.append(numeric_col)
encoded_features.append(encoded_numeric_col)

# Pass 'hour' input to category encoding layer
encoding_layer = get_category_encoding_layer('hour', train_dataset, dtype='int64')
encoded_hour_col = encoding_layer(hour_col)
all_inputs.append(hour_col)
encoded_features.append(encoded_hour_col)

# Pass 'weekday' input to category encoding layer
encoding_layer = get_category_encoding_layer('weekday', train_dataset, dtype='int64')
encoded_weekday_col = encoding_layer(weekday_col)
all_inputs.append(weekday_col)
encoded_features.append(encoded_weekday_col)

Setelah menentukan lapisan prapemrosesan, Anda dapat menentukan bagian model lainnya. Anda akan menggabungkan semua fitur input, dan meneruskannya ke lapisan padat. Lapisan output adalah satu unit karena ini adalah masalah regresi.

all_features = tf.keras.layers.concatenate(encoded_features)
x = tf.keras.layers.Dense(64, activation="relu")(all_features)
output = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(all_inputs, output)

Terakhir, kompilasi model.

model.compile(optimizer = tf.keras.optimizers.Adam(0.001),
              loss='mean_squared_logarithmic_error')

Setelah menentukan model, Anda dapat memvisualisasikan arsitektur

tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")

keras_model

Perhatikan bahwa model ini cukup rumit untuk set data sederhana ini. Demo ini ditujukan untuk tujuan demonstrasi.

Mari kita latih 1 epoch hanya untuk mengonfirmasi bahwa kode berjalan.

model.fit(train_dataset, validation_data = validation_dataset, epochs = 1)

Melatih model dengan GPU

Selanjutnya, Anda akan melatih model lebih lama dan menggunakan pengalih hardware untuk mempercepat pelatihan. Vertex AI Workbench memungkinkan Anda mengubah hardware tanpa menonaktifkan instance. Dengan menambahkan GPU hanya saat Anda membutuhkannya, Anda dapat menekan biaya.

Untuk mengubah profil hardware, klik jenis mesin di sudut kanan atas, lalu pilih Ubah hardware

modify_hardware

Pilih Attach GPUs, lalu pilih GPU NVIDIA T4 Tensor Core.

add_gpu

Perlu waktu sekitar lima menit untuk mengonfigurasi hardware. Setelah proses selesai, mari kita latih model sedikit lebih lama. Anda akan melihat bahwa setiap epoch sekarang memerlukan waktu lebih sedikit.

model.fit(train_dataset, validation_data = validation_dataset, epochs = 5)

🎉 Selamat! 🎉

Anda telah mempelajari cara menggunakan Vertex AI Workbench untuk:

  • Menjelajahi data di BigQuery
  • Menggunakan klien BigQuery untuk memuat data ke Python
  • Melatih model TensorFlow dengan Lapisan Prapemrosesan Keras dan GPU

Untuk mempelajari lebih lanjut berbagai bagian Vertex AI, lihat dokumentasinya.

7. Pembersihan

Karena sebelumnya kita telah mengonfigurasi notebook agar kehabisan waktu setelah 60 menit tidak ada aktivitas, jangan khawatir untuk menonaktifkan instance-nya. Jika Anda ingin menonaktifkan instance secara manual, klik tombol Hentikan di bagian Vertex AI Workbench pada konsol. Jika Anda ingin menghapus notebook secara keseluruhan, klik tombol Hapus.

hapus