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

1. Tổng quan

Trong lớp học lập trình 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 máy học.

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ô hình trên hạt nhân Vertex AI Workbench

Tổng chi phí để chạy lớp học này trên Google Cloud là khoảng 1 USD.

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

Lớp học này sử dụng sản phẩm AI mới nhất có trên Google Cloud. Vertex AI tích hợp các dịch vụ học máy trên Google Cloud vào một trải nghiệm phát triển liền mạch. Trước đây, bạn có thể truy cập vào các mô hình được huấn luyện bằng AutoML và mô hình tuỳ chỉnh thông qua các dịch vụ riêng biệt. Sản phẩm mới 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 bao gồm nhiều sản phẩm để hỗ trợ quy trình làm việc toàn diện về máy học. 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. Công cụ này cho phép các nhà khoa học dữ liệu 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 nhiều kỹ thuật lập mô hình, triển khai các mô hình đã huấn luyện vào môi trường sản xuất và quản lý MLOps trong 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 Thuê xe đạp ở London. Dữ liệu này chứa thông tin về các chuyến đi bằng xe đạp từ 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 Jupyter Notebook bằng pandas và huấn luyện 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 diễn ra chuyến đi và quãng đường người đó đã đi xe đạp.

Lớp học này sử dụng các lớp xử lý trước Keras để biến đổi và chuẩn bị dữ liệu đầu vào cho việc huấn luyện mô hình. API này cho phép bạn tạo quy trình xử lý trước trực tiếp vào biểu đồ mô hình TensorFlow, giảm nguy cơ huấn luyện/phân phát không chính xác 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 phép 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 sử dụng phiên bản TensorFlow cũ, bạn cần nhập ký hiệu 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 API Compute Engine

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

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

Chuyển đến phần Vertex AI trong Cloud Console 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 (Bảng điều khiển):

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Ổ ĐIỆN TỬ ĐƯỢC QUẢN LÝ):

Notebooks_UI

Sau đó, chọn NOTEBOOK MỚI.

new_notebook

Đặt tên cho sổ tay của bạn và trong phần 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 Security (Bảo mật), hãy chọn "Enable terminal" (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 thực thể, 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 phầ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 BigQuery. Ngoài các tập dữ liệu trong dự án, bạn có thể khám phá các tập dữ liệu trong các dự án khác bằng cách nhấp vào nút Thêm dự án.

ghim

Trong lớp học này, bạn sẽ sử dụng dữ liệu từ các 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 tập dữ liệu này có hai 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 đó, 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 các chuyến đi bằng xe đạp đến và đi từ ga 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.

Chúng ta muốn kết hợp các bảng cycle_hirecycle_stations. Bảng cycle_stations chứa lat/lon cho mỗi trạm. Bạn sẽ sử dụng thông tin này để ước tính quãng đường đã đi trên mỗi chuyến đi bằng cách tính toán quãng đường giữa trạm xuất phát 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 ST_GEOGPOINT và sử dụng hàm ST_DISTANCE để tính khoảng cách đường thẳng theo mét giữa hai điểm. Bạn sẽ sử dụng giá trị này làm giá trị đại diện cho quãng đường đã đi trong mỗi chuyến đi bằng 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ó ba bảng trong điều kiện JOIN vì chúng ta cần liên kết bảng stations hai lần để lấy lat/lon cho cả trạm bắt đầu và trạm kết thúc của chu kỳ.

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 hạt nhân TensorFlow

Vertex AI Workbench có một lớp tương thích điện toán cho phép bạn chạy hạt nhân cho TensorFlow, PySpark, R, v.v., tất cả đều từ một phiên bản máy tính xách tay. Trong lớp học này, bạn sẽ tạo một sổ tay bằng cách sử dụng hạt 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 cho phép bạn dán mã Python vào một sổ ghi 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. Mã 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()

Trong phòng thí nghiệm 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 đào tạo. Tuy nhiên, bạn có thể 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 khung dữ liệu rút gọn chỉ chứa những cột cần thiết cho phần Máy học 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 của Python. Thay vì sử dụng trực tiếp datetime này trong mô hình, bạn sẽ tạo hai 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 đã định dạng. Giờ đây, đối với mỗi chuyến đi theo chu kỳ, bạn sẽ có dữ liệu về ngày trong tuần và giờ trong ngày diễn ra chuyến đi, cũng như quãng đường đã đi. Dựa vào thông tin này, bạn sẽ cố gắng dự đoán chuyến đi mất bao lâu.

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 các tập huấn luyện và xác thực.

# 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 chức năng Keras. Để 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 tiện ích 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

Sử dụng hàm ở trên để tạo hai tf.data.Dataset, một để huấn luyện và một để xác thực. Bạn có thể thấy một số cảnh báo, nhưng bạn có thể yên tâm bỏ qua những cảnh báo đó.

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 xử lý trước sau đây trong mô hình:

  • Lớp chuẩn hoá: thực hiện việc chuẩn hoá theo tính năng của các tính năng đầu vào.
  • Lớp tìm số nguyên: biến các giá trị phân loại số nguyên thành chỉ mục số nguyên.
  • Lớp CategoryEncoding: biến các tính năng danh mục số nguyên thành các đại diện dày đặc một chiều, nhiều chiều hoặc TF-IDF.

Xin lưu ý rằng các lớp này không thể huấn luyện được. Thay vào đó, bạn thiết lập trạng thái của lớp xử lý trước bằng cách hiển thị lớp này 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 cho 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 để sử dụng cho việc chuẩn hoá. Sau đó, khi bạn truyền tập dữ liệu xác thực vào mô hình, trung bình và phương sai tương tự được tính toán trên dữ liệu huấn luyện sẽ được dùng để điều chỉnh 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 sẽ tạo một mã hoá danh mục mà bạn sẽ sử dụng cho các tính năng 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 xử lý trước 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 xử lý trước, 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 đặc điểm đầu vào và truyền các đặc điểm đó đế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')

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

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. Nội dung này nhằm mục đích minh hoạ.

Hãy huấn luyện trong 1 khoảng thời gian bắt đầu của hệ thống chỉ để xác nhận rằng đoạn mã đã 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à sử dụng trình chuyển đổi phần cứng để tăng tốc độ 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 cùng bên phải rồi chọn Sửa đổi phần cứng

modify_hardware

Chọn Attach GPUs (Gắn GPU) rồi chọn một GPU NVIDIA T4 Tensor Core.

add_gpu

Quá trình định cấu hình 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 thời gian bắt đầu của hệ thống 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ô hình TensorFlow bằng các Lớp xử lý trước 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ì đã định cấu hình sổ tay hết thời gian chờ sau 60 phút ở trạng thái rảnh, nên chúng ta không cần phải lo lắng về việc tắt thực thể. 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 mục Vertex AI Workbench (Bảng điều khiển Vertex AI) 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