Vertex AI Workbench: Đào tạo mô hình TensorFlow bằng dữ liệu từ BigQuery

1. Tổng quan

Trong phòng thí nghiệm này, bạn sẽ tìm hiểu cách sử dụng Vertex AI Workbench để khám phá dữ liệu và huấn luyện mô hình học máy.

Kiến thức bạn sẽ học được

Bạn sẽ tìm hiểu cách:

  • Tạo và định cấu hình một phiên bản Vertex AI Workbench
  • Sử dụng trình kết nối BigQuery của Vertex AI Workbench
  • Huấn luyện một mô hình trên nhân Vertex AI Workbench

Tổng chi phí để chạy bài tập thực hành này trên Google Cloud là khoảng 1 USD.

2. Giới thiệu về Vertex AI

Phòng thí nghiệm này sử dụng sản phẩm AI mới nhất hiện có trên Google Cloud. Vertex AI tích hợp các sản phẩm ML trên Google Cloud thành một trải nghiệm phát triển liền mạch. Trước đây, các mô hình được huấn luyện bằng AutoML và các mô hình tuỳ chỉnh có thể truy cập thông qua các dịch vụ riêng biệt. Sản phẩm mới này kết hợp cả hai thành một API duy nhất, cùng với các sản phẩm mới khác. Bạn cũng có thể di chuyển các dự án hiện có sang Vertex AI.

Vertex AI có nhiều sản phẩm để hỗ trợ quy trình làm việc ML toàn diện. Phòng thí nghiệm này sẽ tập trung vào Vertex AI Workbench.

Vertex AI Workbench giúp người dùng nhanh chóng xây dựng quy trình làm việc toàn diện dựa trên sổ tay thông qua việc tích hợp sâu với các dịch vụ dữ liệu (như Dataproc, Dataflow, BigQuery và Dataplex) và Vertex AI. Nhờ đó, các nhà khoa học dữ liệu có thể kết nối với các dịch vụ dữ liệu của GCP, phân tích tập dữ liệu, thử nghiệm các kỹ thuật mô hình hoá khác nhau, triển khai các mô hình đã huấn luyện vào quy trình sản xuất và quản lý MLOps trong suốt vòng đời của mô hình.

3. Tổng quan về trường hợp sử dụng

Trong lớp học lập trình này, bạn sẽ khám phá tập dữ liệu London Bicycles Hire (Dịch vụ cho thuê xe đạp ở London). Dữ liệu này chứa thông tin về các chuyến đi xe đạp trong chương trình chia sẻ xe đạp công cộng của London kể từ năm 2011. Bạn sẽ bắt đầu bằng cách khám phá tập dữ liệu này trong BigQuery thông qua trình kết nối BigQuery của Vertex AI Workbench. Sau đó, bạn sẽ tải dữ liệu vào một Jupyter Notebook bằng cách sử dụng pandas và huấn luyện một mô hình TensorFlow để dự đoán thời lượng của một chuyến đi xe đạp dựa trên thời điểm chuyến đi diễn ra và quãng đường mà người đó đã đạp xe.

Phòng thí nghiệm này sử dụng các lớp tiền xử lý Keras để chuyển đổi và chuẩn bị dữ liệu đầu vào cho quá trình huấn luyện mô hình. API này cho phép bạn tạo quy trình tiền xử lý ngay trong biểu đồ mô hình TensorFlow, giảm nguy cơ sai lệch giữa huấn luyện và phân phát bằng cách đảm bảo rằng dữ liệu huấn luyện và dữ liệu phân phát trải qua các biến đổi giống hệt nhau. Xin lưu ý rằng kể từ TensorFlow 2.6, API này đã ổn định. Nếu đang dùng một phiên bản TensorFlow cũ, bạn cần nhập biểu tượng thử nghiệm.

4. Thiết lập môi trường

Bạn cần có một dự án trên Google Cloud Platform đã bật tính năng thanh toán để chạy lớp học lập trình này. Để tạo một dự án, hãy làm theo hướng dẫn tại đây.

Bước 1: Bật Compute Engine API

Chuyển đến Compute Engine rồi chọn Bật nếu bạn chưa bật.

Bước 2: Bật Vertex AI API

Chuyển đến mục Vertex AI trong Bảng điều khiển Cloud rồi nhấp vào Bật Vertex AI API.

Trang tổng quan Vertex AI

Bước 3: Tạo một phiên bản Vertex AI Workbench

Trong phần Vertex AI của Cloud Console, hãy nhấp vào Workbench:

Trình đơn Vertex AI

Bật Notebooks API nếu bạn chưa bật.

Notebook_api

Sau khi bật, hãy nhấp vào MANAGED NOTEBOOKS (SỔ TAY ĐƯỢC QUẢN LÝ):

Notebooks_UI

Sau đó, chọn SỔ TAY MỚI.

new_notebook

Đặt tên cho sổ tay của bạn, rồi trong mục Quyền, hãy chọn Tài khoản dịch vụ

service_account

Chọn Cài đặt nâng cao.

Trong phần Bảo mật, hãy chọn "Bật thiết bị đầu cuối" nếu bạn chưa bật.

enable_terminal

Bạn có thể giữ nguyên tất cả các chế độ cài đặt nâng cao khác.

Tiếp theo, hãy nhấp vào Tạo.

Sau khi tạo phiên bản, hãy chọn MỞ JUPYTERLAB.

enable_terminal

5. Khám phá tập dữ liệu trong BigQuery

Trong phiên bản Vertex AI Workbench, hãy chuyển đến bên trái rồi nhấp vào trình kết nối BigQuery in Notebooks.

Trình kết nối BQ

Trình kết nối BigQuery giúp bạn dễ dàng khám phá và truy vấn các tập dữ liệu trên BigQuery. Ngoài mọi tập dữ liệu trong dự án của bạn, bạn có thể khám phá các tập dữ liệu trong những dự án khác bằng cách nhấp vào nút Thêm dự án.

ghim

Trong bài thực hành này, bạn sẽ sử dụng dữ liệu từ tập dữ liệu công khai của BigQuery. Di chuyển xuống cho đến khi bạn tìm thấy tập dữ liệu london_bicycles. Bạn sẽ thấy rằng tập dữ liệu này có 2 bảng là cycle_hirecycle_stations. Hãy cùng tìm hiểu từng loại.

london_bike_ds

Trước tiên, hãy nhấp đúp vào bảng cycle_hire. Bạn sẽ thấy bảng mở ra dưới dạng một thẻ mới có giản đồ của bảng cũng như siêu dữ liệu như số lượng hàng và kích thước.

cycle_hire_ds

Nếu nhấp vào thẻ Xem trước, bạn sẽ có thể xem mẫu dữ liệu. Hãy chạy một truy vấn đơn giản để xem những hành trình phổ biến. Trước tiên, hãy nhấp vào nút Bảng truy vấn.

cycle_hire_preview_ds

Sau đó, hãy dán nội dung sau vào trình chỉnh sửa SQL rồi nhấp vào Gửi truy vấn.

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

Trong kết quả truy vấn, bạn sẽ thấy rằng các chuyến đi xe đạp đến và đi từ trạm Hyde Park Corner là phổ biến nhất.

journey_query_results

Tiếp theo, hãy nhấp đúp vào bảng cycle_stations. Bảng này cung cấp thông tin về từng trạm sạc.

Chúng ta muốn kết hợp các bảng cycle_hirecycle_stations. Bảng cycle_stations chứa vĩ độ/kinh độ của từng trạm. Bạn sẽ sử dụng thông tin này để ước tính quãng đường đã đi trong mỗi chuyến đi xe đạp bằng cách tính khoảng cách giữa trạm bắt đầu và trạm kết thúc.

Để thực hiện phép tính này, bạn sẽ sử dụng các hàm địa lý của BigQuery. Cụ thể, bạn sẽ chuyển đổi từng chuỗi vĩ độ/kinh độ thành một ST_GEOGPOINT và sử dụng hàm ST_DISTANCE để tính khoảng cách đường thẳng (tính bằng mét) giữa hai điểm. Bạn sẽ dùng giá trị này làm proxy cho quãng đường đã đi trong mỗi chuyến đi xe đạp.

Sao chép truy vấn sau vào trình chỉnh sửa SQL rồi nhấp vào Gửi truy vấn. Xin lưu ý rằng có 3 bảng trong điều kiện JOIN vì chúng ta cần kết hợp bảng trạm hai lần để lấy vĩ độ/kinh độ cho cả trạm bắt đầu và trạm kết thúc của xe đạp.

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. Huấn luyện mô hình học máy trên một nhân TensorFlow

Vertex AI Workbench có một lớp tương thích về điện toán, cho phép bạn chạy các nhân cho TensorFlow, PySpark, R, v.v., tất cả đều từ một phiên bản sổ tay duy nhất. Trong phòng thí nghiệm này, bạn sẽ tạo một sổ tay bằng cách sử dụng nhân TensorFlow.

Tạo DataFrame

Sau khi truy vấn thực thi, hãy nhấp vào Sao chép mã cho DataFrame. Thao tác này sẽ cho phép bạn dán mã Python vào một sổ tay kết nối với ứng dụng BigQuery và trích xuất dữ liệu này dưới dạng DataFrame của pandas.

copy_for_df

Tiếp theo, hãy quay lại Trình chạy và tạo một sổ tay TensorFlow 2.

tf_kernel

Trong ô đầu tiên của sổ tay, hãy dán mã đã sao chép từ Trình chỉnh sửa truy vấn. Nội dung sẽ có dạng như sau:

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

Để phục vụ mục đích của lớp học này, chúng tôi giới hạn tập dữ liệu ở mức 700.000 để rút ngắn thời gian huấn luyện. Tuy nhiên, bạn có thể thoải mái sửa đổi truy vấn và thử nghiệm với toàn bộ tập dữ liệu.

Tiếp theo, hãy nhập các thư viện cần thiết.

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

Chạy mã sau để tạo một DataFrame được rút gọn, chỉ chứa các cột cần thiết cho phần học máy của bài tập này.

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

Cột start_date là một datetime Python. Thay vì sử dụng datetime này trực tiếp trong mô hình, bạn sẽ tạo 2 tính năng mới cho biết ngày trong tuần và giờ trong ngày mà chuyến đi xe đạp diễn ra.

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

Cuối cùng, hãy chuyển đổi cột thời lượng từ giây sang phút để dễ hiểu hơn

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

Kiểm tra một vài hàng đầu tiên của DataFrame được định dạng. Đối với mỗi chuyến đi xe đạp, giờ đây bạn có dữ liệu về ngày trong tuần và giờ trong ngày mà chuyến đi diễn ra, cũng như khoảng cách đã đi. Dựa vào thông tin này, bạn sẽ cố gắng dự đoán thời gian của chuyến đi.

data.head()

data_head

Trước khi có thể tạo và huấn luyện mô hình, bạn cần chia dữ liệu thành tập huấn luyện và tập xác nhận.

# 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:]

Tạo mô hình TensorFlow

Bạn sẽ tạo một mô hình TensorFlow bằng API Keras Functional. Để xử lý trước dữ liệu đầu vào, bạn sẽ sử dụng API lớp xử lý trước của Keras.

Hàm hiệu dụng sau đây sẽ tạo một tf.data.Dataset từ Dataframe của 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

Dùng hàm trên để tạo 2 tf.data.Dataset, một cho quá trình huấn luyện và một cho quá trình xác thực. Bạn có thể thấy một số cảnh báo nhưng có thể yên tâm bỏ qua.

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

Bạn sẽ sử dụng các lớp tiền xử lý sau đây trong mô hình:

  • Lớp chuẩn hoá: thực hiện chuẩn hoá theo từng đối tượng của các đối tượng đầu vào.
  • Lớp IntegerLookup: chuyển các giá trị phân loại số nguyên thành chỉ mục số nguyên.
  • Lớp CategoryEncoding: chuyển các đối tượng phân loại số nguyên thành các biểu diễn dày đặc one-hot, multi-hot hoặc TF-IDF.

Xin lưu ý rằng bạn không thể huấn luyện các lớp này. Thay vào đó, bạn thiết lập trạng thái của lớp tiền xử lý bằng cách hiển thị lớp đó cho dữ liệu huấn luyện thông qua phương thức adapt().

Hàm sau đây sẽ tạo một lớp chuẩn hoá mà bạn có thể sử dụng trên tính năng khoảng cách. Bạn sẽ đặt trạng thái trước khi điều chỉnh mô hình bằng cách sử dụng phương thức adapt() trên dữ liệu huấn luyện. Thao tác này sẽ tính toán giá trị trung bình và phương sai để dùng cho việc chuẩn hoá. Sau đó, khi bạn truyền tập dữ liệu xác thực đến mô hình, cùng một giá trị trung bình và phương sai được tính toán trên dữ liệu huấn luyện sẽ được dùng để điều chỉnh quy mô dữ liệu xác thực.

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

Tương tự, hàm sau đây tạo một mã hoá danh mục mà bạn sẽ sử dụng cho các đặc điểm về giờ và ngày trong tuần.

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

Tiếp theo, hãy tạo phần tiền xử lý của mô hình. Trước tiên, hãy tạo một lớp tf.keras.Input cho từng đối tượng.

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

Sau đó, hãy tạo các lớp chuẩn hoá và mã hoá danh mục, lưu trữ các lớp này trong một danh sách.

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)

Sau khi xác định các lớp tiền xử lý, bạn có thể xác định phần còn lại của mô hình. Bạn sẽ nối tất cả các đối tượng đầu vào và truyền chúng đến một lớp dày đặc. Lớp đầu ra là một đơn vị duy nhất vì đây là vấn đề hồi quy.

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)

Cuối cùng, hãy biên dịch mô hình.

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

Bây giờ, bạn có thể hình dung cấu trúc sau khi đã xác định mô hình

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

keras_model

Xin lưu ý rằng mô hình này khá phức tạp đối với tập dữ liệu đơn giản này. Tài liệu này chỉ nhằm mục đích minh hoạ.

Hãy huấn luyện trong 1 giai đoạn chỉ để xác nhận rằng mã đang chạy.

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

Đào tạo mô hình bằng GPU

Tiếp theo, bạn sẽ huấn luyện mô hình lâu hơn và dùng bộ chuyển đổi phần cứng để tăng tốc quá trình huấn luyện. Vertex AI Workbench cho phép bạn thay đổi phần cứng mà không cần tắt phiên bản. Bằng cách chỉ thêm GPU khi cần, bạn có thể giảm chi phí.

Để thay đổi hồ sơ phần cứng, hãy nhấp vào loại máy ở góc trên bên phải rồi chọn Sửa đổi phần cứng

modify_hardware

Chọn Attach GPUs (Đính kèm GPU) rồi chọn một GPU NVIDIA T4 Tensor Core.

add_gpu

Quá trình thiết lập phần cứng sẽ mất khoảng 5 phút. Sau khi quá trình này hoàn tất, hãy huấn luyện mô hình lâu hơn một chút. Bạn sẽ nhận thấy rằng mỗi giai đoạn hiện mất ít thời gian hơn.

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

🎉 Xin chúc mừng! 🎉

Bạn đã tìm hiểu cách sử dụng Vertex AI Workbench để:

  • Khám phá dữ liệu trong BigQuery
  • Sử dụng ứng dụng BigQuery để tải dữ liệu vào Python
  • Huấn luyện một mô hình TensorFlow bằng các Lớp tiền xử lý Keras và GPU

Để tìm hiểu thêm về các phần khác nhau của Vertex AI, hãy xem tài liệu.

7. Dọn dẹp

Vì chúng ta đã định cấu hình sổ tay để hết thời gian chờ sau 60 phút không hoạt động, nên chúng ta không cần lo lắng về việc tắt phiên bản. Nếu bạn muốn tắt thực thể theo cách thủ công, hãy nhấp vào nút Dừng trong phần Vertex AI Workbench của bảng điều khiển. Nếu bạn muốn xoá hoàn toàn sổ tay, hãy nhấp vào nút Xoá.

xóa