1. Tổng quan
Trong lớp học này, bạn sẽ tìm hiểu cách sử dụng Vertex AI để điều chỉnh tham số siêu dữ liệu và huấn luyện phân tán. Mặc dù lớp học lập trình này sử dụng TensorFlow cho mã mô hình, nhưng các khái niệm này cũng áp dụng cho các khung máy học khác.
Kiến thức bạn sẽ học được
Bạn sẽ tìm hiểu cách:
- Huấn luyện mô hình bằng phương pháp huấn luyện phân tán trên vùng chứa tuỳ chỉnh
- Khởi chạy nhiều bản dùng thử cho mã huấn luyện của bạn để điều chỉnh siêu tham số tự động
Tổng chi phí để chạy lớp học này trên Google Cloud là khoảng 6 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, các mô hình được huấn luyện bằng AutoML và mô hình tuỳ chỉnh có thể truy cập được 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. Nếu bạn có ý kiến phản hồi, vui lòng xem trang hỗ trợ.
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. Lớp học này sẽ tập trung vào phần Hướng dẫn và Bảng điều khiển.
3. Tổng quan về trường hợp sử dụng
Trong phòng thí nghiệm này, bạn sẽ sử dụng tính năng tinh chỉnh siêu tham số để khám phá các tham số tối ưu cho một mô hình phân loại hình ảnh được huấn luyện trên tập dữ liệu ngựa hoặc người từ Tập dữ liệu TensorFlow.
Điều chỉnh siêu tham số
Tính năng Điều chỉnh tham số siêu dữ liệu bằng tính năng Huấn luyện AI của Vertex hoạt động bằng cách chạy nhiều thử nghiệm của ứng dụng huấn luyện với các giá trị cho tham số siêu dữ liệu đã chọn, được đặt trong giới hạn mà bạn chỉ định. Vertex AI theo dõi kết quả của mỗi thử nghiệm và điều chỉnh cho các thử nghiệm tiếp theo.
Để sử dụng tính năng điều chỉnh tham số siêu dữ liệu bằng tính năng Huấn luyện AI của Vertex, bạn cần thực hiện 2 thay đổi đối với mã huấn luyện:
- Xác định đối số dòng lệnh trong mô-đun huấn luyện chính cho từng tham số siêu dữ liệu mà bạn muốn điều chỉnh.
- Sử dụng giá trị được truyền trong các đối số đó để đặt tham số siêu dữ liệu tương ứng trong mã của ứng dụng.
Đào tạo phân tán
Nếu bạn có một GPU, TensorFlow sẽ sử dụng trình tăng tốc này để tăng tốc quá trình huấn luyện mô hình mà bạn không cần làm gì thêm. Tuy nhiên, nếu muốn tăng hiệu suất bằng cách sử dụng nhiều GPU, bạn cần sử dụng tf.distribute
. Đây là mô-đun của TensorFlow để chạy phép tính trên nhiều thiết bị.
Phòng thí nghiệm này sử dụng tf.distribute.MirroredStrategy
mà bạn có thể thêm vào các ứng dụng huấn luyện chỉ bằng một vài lần thay đổi mã. Chiến lược này tạo một bản sao của mô hình trên mỗi GPU trên máy của bạn. Các lần cập nhật độ dốc tiếp theo sẽ diễn ra một cách đồng bộ. Điều này có nghĩa là mỗi GPU tính toán các lượt truyền tới và lui thông qua mô hình trên một lát cắt khác của dữ liệu đầu vào. Sau đó, các độ dốc được tính toán từ mỗi lát cắt này được tổng hợp trên tất cả GPU và được tính trung bình trong một quy trình được gọi là tất cả giảm. Các tham số của mô hình được cập nhật bằng các độ dốc trung bình này.
Bạn không cần phải biết thông tin chi tiết để hoàn thành phòng thí nghiệm này, nhưng nếu bạn muốn tìm hiểu thêm về cách hoạt động của chương trình đào tạo phân tán trong TensorFlow, hãy xem video dưới đây:
4. Thiết lập môi trường
Bạn cần một dự á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 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 Enable (Bật) nếu bạn chưa bật tính năng này.
Bước 2: Bật API Registry Container
Chuyển đến Container Registry (Cơ sở lưu trữ vùng chứa) rồi chọn Enable (Bật) nếu bạn chưa bật. Bạn sẽ sử dụng thông tin này để tạo một vùng chứa cho công việc huấn luyện tuỳ chỉnh.
Bước 3: Bật API Vertex AI
Chuyển đến mục Vertex AI trong Cloud Console rồi nhấp vào Bật API Vertex AI.
Bước 4: Tạo một thực thể 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):
Bật Notebooks API nếu bạn chưa bật.
Sau khi bật, hãy nhấp vào MANAGED NOTEBOOKS (SỔ ĐIỆN TỬ ĐƯỢC QUẢN LÝ):
Sau đó, chọn NOTEBOOK MỚI.
Đặt tên cho sổ tay của bạn, sau đó nhấp vào Cài đặt nâng cao.
Trong phần Cài đặt nâng cao, hãy bật tính năng tắt khi không hoạt động và đặt số phút thành 60. Điều này có nghĩa là máy tính xách tay của bạn sẽ tự động tắt khi không sử dụng để bạn không phải chịu các chi phí không cần thiết.
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.
Bạn có thể giữ nguyên mọi chế độ cài đặt nâng cao khác.
Tiếp theo, hãy nhấp vào Tạo. Quá trình cấp phép thực thể sẽ mất vài phút.
Sau khi tạo thực thể, hãy chọn Open JupyterLab (Mở JupyterLab).
Trong lần đầu tiên sử dụng một thực thể mới, bạn sẽ được yêu cầu xác thực. Hãy làm theo các bước trong giao diện người dùng để thực hiện việc này.
5. Viết mã huấn luyện
Để bắt đầu, trên trình đơn Trình chạy, hãy mở cửa sổ dòng lệnh trong thực thể sổ tay của bạn:
Tạo một thư mục mới có tên là vertex-codelab
rồi chuyển vào thư mục đó.
mkdir vertex-codelab
cd vertex-codelab
Chạy lệnh sau để tạo thư mục cho mã huấn luyện và một tệp Python nơi bạn sẽ thêm mã:
mkdir trainer
touch trainer/task.py
Bây giờ, bạn sẽ có những nội dung sau trong thư mục vertex-codelab
:
+ trainer/
+ task.py
Tiếp theo, hãy mở tệp task.py
bạn vừa tạo và dán tất cả mã bên dưới vào.
import tensorflow as tf
import tensorflow_datasets as tfds
import argparse
import hypertune
import os
NUM_EPOCHS = 10
BATCH_SIZE = 64
def get_args():
'''Parses args. Must include all hyperparameters you want to tune.'''
parser = argparse.ArgumentParser()
parser.add_argument(
'--learning_rate',
required=True,
type=float,
help='learning rate')
parser.add_argument(
'--momentum',
required=True,
type=float,
help='SGD momentum value')
parser.add_argument(
'--num_units',
required=True,
type=int,
help='number of units in last hidden layer')
args = parser.parse_args()
return args
def preprocess_data(image, label):
'''Resizes and scales images.'''
image = tf.image.resize(image, (150,150))
return tf.cast(image, tf.float32) / 255., label
def create_dataset(batch_size):
'''Loads Horses Or Humans dataset and preprocesses data.'''
data, info = tfds.load(name='horses_or_humans', as_supervised=True, with_info=True)
# Create train dataset
train_data = data['train'].map(preprocess_data)
train_data = train_data.shuffle(1000)
train_data = train_data.batch(batch_size)
# Create validation dataset
validation_data = data['test'].map(preprocess_data)
validation_data = validation_data.batch(batch_size)
return train_data, validation_data
def create_model(num_units, learning_rate, momentum):
'''Defines and compiles model.'''
inputs = tf.keras.Input(shape=(150, 150, 3))
x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(inputs)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Conv2D(64, (3, 3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((2, 2))(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(num_units, activation='relu')(x)
outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)
model = tf.keras.Model(inputs, outputs)
model.compile(
loss='binary_crossentropy',
optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum),
metrics=['accuracy'])
return model
def main():
args = get_args()
# Create distribution strategy
strategy = tf.distribute.MirroredStrategy()
# Get data
GLOBAL_BATCH_SIZE = BATCH_SIZE * strategy.num_replicas_in_sync
train_data, validation_data = create_dataset(GLOBAL_BATCH_SIZE)
# Wrap variable creation within strategy scope
with strategy.scope():
model = create_model(args.num_units, args.learning_rate, args.momentum)
# Train model
history = model.fit(train_data, epochs=NUM_EPOCHS, validation_data=validation_data)
# Define metric
hp_metric = history.history['val_accuracy'][-1]
hpt = hypertune.HyperTune()
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag='accuracy',
metric_value=hp_metric,
global_step=NUM_EPOCHS)
if __name__ == "__main__":
main()
Hãy cùng tìm hiểu kỹ hơn về mã và kiểm tra các thành phần dành riêng cho việc huấn luyện phân tán và điều chỉnh tham số siêu dữ liệu.
Đào tạo phân tán
- Trong hàm
main()
, đối tượngMirroredStrategy
được tạo. Tiếp theo, bạn kết hợp việc tạo các biến mô hình trong phạm vi của chiến lược. Bước này cho TensorFlow biết những biến nào cần được phản chiếu trên các GPU. - Kích thước lô được điều chỉnh theo tỷ lệ bằng
num_replicas_in_sync
. Điều chỉnh quy mô kích thước lô là phương pháp hay nhất khi sử dụng các chiến lược song song dữ liệu đồng bộ trong TensorFlow. Bạn có thể tìm hiểu thêm tại đây.
Điều chỉnh siêu tham số
- Tập lệnh này nhập thư viện
hypertune
. Sau này, khi tạo hình ảnh vùng chứa, chúng ta cần đảm bảo đã cài đặt thư viện này. - Hàm
get_args()
xác định đối số dòng lệnh cho từng tham số siêu dữ liệu mà bạn muốn điều chỉnh. Trong ví dụ này, các tham số siêu dữ liệu sẽ được điều chỉnh là tốc độ học, giá trị động lượng trong trình tối ưu hoá và số lượng đơn vị trong lớp ẩn cuối cùng của mô hình, nhưng bạn có thể tự do thử nghiệm với các tham số khác. Sau đó, giá trị được truyền trong các đối số đó được dùng để đặt tham số siêu dữ liệu tương ứng trong mã (ví dụ: đặtlearning_rate = args.learning_rate
) - Ở cuối hàm
main()
, thư việnhypertune
được dùng để xác định chỉ số bạn muốn tối ưu hoá. Trong TensorFlow, phương thứcmodel.fit
của Keras trả về một đối tượngHistory
. Thuộc tínhHistory.history
là bản ghi các giá trị tổn thất huấn luyện và giá trị chỉ số tại các thời gian liên tiếp. Nếu bạn chuyển dữ liệu xác thực đếnmodel.fit
, thuộc tínhHistory.history
cũng sẽ bao gồm tổn thất xác thực và các giá trị chỉ số. Ví dụ: nếu bạn huấn luyện một mô hình trong ba epoch bằng dữ liệu xác thực và cung cấpaccuracy
làm chỉ số, thì thuộc tínhHistory.history
sẽ tương tự như từ điển sau.
{
"accuracy": [
0.7795261740684509,
0.9471358060836792,
0.9870933294296265
],
"loss": [
0.6340447664260864,
0.16712145507335663,
0.04546636343002319
],
"val_accuracy": [
0.3795261740684509,
0.4471358060836792,
0.4870933294296265
],
"val_loss": [
2.044623374938965,
4.100203514099121,
3.0728273391723633
]
Nếu muốn dịch vụ điều chỉnh tham số siêu dữ liệu khám phá các giá trị giúp tối đa hoá độ chính xác xác thực của mô hình, bạn hãy xác định chỉ số này là mục cuối cùng (hoặc NUM_EPOCS - 1
) của danh sách val_accuracy
. Sau đó, hãy truyền chỉ số này đến một thực thể của HyperTune
. Bạn có thể chọn bất kỳ chuỗi nào bạn muốn cho hyperparameter_metric_tag
, nhưng sau này bạn sẽ cần sử dụng lại chuỗi đó khi bắt đầu công việc điều chỉnh tham số siêu dữ liệu.
6. Vùng chứa mã
Bước đầu tiên trong việc đóng gói mã là tạo một Dockerfile. Trong Dockerfile, bạn sẽ thêm tất cả các lệnh cần thiết để chạy hình ảnh. Công cụ này sẽ cài đặt tất cả thư viện cần thiết và thiết lập điểm truy cập cho mã huấn luyện.
Bước 1: Viết Dockerfile
Trong Terminal, hãy đảm bảo bạn đang ở thư mục vertex-codelab
và tạo một Dockerfile trống:
touch Dockerfile
Bây giờ, bạn sẽ có những nội dung sau trong thư mục vertex-codelab
:
+ Dockerfile
+ trainer/
+ task.py
Mở Dockerfile và sao chép nội dung sau vào tệp đó:
FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-7
WORKDIR /
# Installs hypertune library
RUN pip install cloudml-hypertune
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]
Tệp Dockerfile này sử dụng hình ảnh Docker GPU TensorFlow Enterprise 2.7 của Vùng chứa học sâu. Vùng chứa học sâu trên Google Cloud được cài đặt sẵn nhiều khung học máy và khoa học dữ liệu phổ biến. Sau khi tải hình ảnh đó xuống, Dockerfile này sẽ thiết lập điểm truy cập cho mã đào tạo.
Bước 2: Tạo vùng chứa
Trên Terminal, hãy chạy đoạn mã sau để xác định biến env cho dự án, nhớ thay thế your-cloud-project
bằng mã nhận dạng của dự án:
PROJECT_ID='your-cloud-project'
Xác định một biến bằng URI của hình ảnh vùng chứa trong Google Container Registry:
IMAGE_URI="gcr.io/$PROJECT_ID/horse-human-codelab:latest"
Định cấu hình Docker
gcloud auth configure-docker
Sau đó, hãy tạo vùng chứa bằng cách chạy lệnh sau từ thư mục gốc vertex-codelab
:
docker build ./ -t $IMAGE_URI
Cuối cùng, hãy đẩy địa chỉ email này đến Google Container Registry:
docker push $IMAGE_URI
Bước 3: Tạo một bộ chứa Cloud Storage
Trong công việc huấn luyện, chúng ta sẽ truyền vào đường dẫn đến một bộ chứa giai đoạn.
Chạy đoạn mã sau trong Terminal để tạo một bộ chứa mới trong dự án.
BUCKET_NAME="gs://${PROJECT_ID}-hptune-bucket"
gsutil mb -l us-central1 $BUCKET_NAME
7. Khởi chạy công việc điều chỉnh siêu tham số
Bước 1: Tạo công việc huấn luyện tuỳ chỉnh bằng cách điều chỉnh tham số siêu dữ liệu
Trên trình chạy, hãy mở một Sổ tay TensorFlow 2 mới.
Nhập SDK Vertex AI Python.
from google.cloud import aiplatform
from google.cloud.aiplatform import hyperparameter_tuning as hpt
Để chạy công việc điều chỉnh tham số siêu dữ liệu, trước tiên, bạn cần xác định worker_pool_specs
. Tham số này chỉ định loại máy và hình ảnh Docker. Thông số kỹ thuật sau đây xác định một máy có hai GPU NVIDIA Tesla V100.
Bạn cần thay thế {PROJECT_ID}
trong image_uri
bằng dự án của mình.
# The spec of the worker pools including machine type and Docker image
# Be sure to replace PROJECT_ID in the "image_uri" with your project.
worker_pool_specs = [{
"machine_spec": {
"machine_type": "n1-standard-4",
"accelerator_type": "NVIDIA_TESLA_V100",
"accelerator_count": 2
},
"replica_count": 1,
"container_spec": {
"image_uri": "gcr.io/{PROJECT_ID}/horse-human-codelab:latest"
}
}]
Tiếp theo, hãy xác định parameter_spec
. Đây là một từ điển chỉ định các thông số mà bạn muốn tối ưu hoá. Khoá từ điển là chuỗi mà bạn chỉ định cho đối số dòng lệnh cho mỗi tham số siêu dữ liệu và giá trị từ điển là thông số kỹ thuật của tham số.
Đối với mỗi tham số siêu dữ liệu, bạn cần xác định Loại cũng như giới hạn cho các giá trị mà dịch vụ điều chỉnh sẽ thử. Siêu tham số có thể thuộc loại Kép, Số nguyên, Phân loại hoặc Rời rạc. Nếu chọn loại Double hoặc Integer, bạn cần cung cấp giá trị tối thiểu và tối đa. Còn nếu chọn Phân loại hoặc Rời rạc, bạn cần cung cấp các giá trị. Đối với các loại Double và Integer, bạn cũng cần cung cấp giá trị Scaling (Điều chỉnh theo tỷ lệ). Bạn có thể tìm hiểu thêm về cách chọn thang đo phù hợp nhất trong video này.
# Dictionary representing parameters to optimize.
# The dictionary key is the parameter_id, which is passed into your training
# job as a command line argument,
# And the dictionary value is the parameter specification of the metric.
parameter_spec = {
"learning_rate": hpt.DoubleParameterSpec(min=0.001, max=1, scale="log"),
"momentum": hpt.DoubleParameterSpec(min=0, max=1, scale="linear"),
"num_units": hpt.DiscreteParameterSpec(values=[64, 128, 512], scale=None)
}
Thông số cuối cùng cần xác định là metric_spec
, đây là một từ điển đại diện cho chỉ số cần tối ưu hoá. Khoá từ điển là hyperparameter_metric_tag
mà bạn đặt trong mã ứng dụng huấn luyện và giá trị là mục tiêu tối ưu hoá.
# Dicionary representing metrics to optimize.
# The dictionary key is the metric_id, which is reported by your training job,
# And the dictionary value is the optimization goal of the metric.
metric_spec={'accuracy':'maximize'}
Sau khi xác định các thông số, bạn sẽ tạo một CustomJob
. Đây là thông số phổ biến dùng để chạy công việc của bạn trong mỗi lượt thử điều chỉnh siêu tham số.
Bạn cần thay thế {YOUR_BUCKET}
bằng bộ chứa mà bạn đã tạo trước đó.
# Replace YOUR_BUCKET
my_custom_job = aiplatform.CustomJob(display_name='horses-humans',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
Sau đó, hãy tạo và chạy HyperparameterTuningJob
.
hp_job = aiplatform.HyperparameterTuningJob(
display_name='horses-humans',
custom_job=my_custom_job,
metric_spec=metric_spec,
parameter_spec=parameter_spec,
max_trial_count=6,
parallel_trial_count=2,
search_algorithm=None)
hp_job.run()
Có một số đối số cần lưu ý:
- max_trial_count: Bạn cần phải đặt giới hạn trên về số lượt dùng thử mà dịch vụ sẽ chạy. Thông thường, càng có nhiều thử nghiệm thì kết quả càng tốt, nhưng sẽ có một điểm lợi tức giảm dần, sau đó các thử nghiệm bổ sung sẽ ít hoặc không ảnh hưởng đến chỉ số mà bạn đang cố gắng tối ưu hoá. Tốt nhất là bạn nên bắt đầu với số lượng thử nghiệm ít hơn và nắm được mức độ tác động của các tham số siêu dữ liệu mà bạn đã chọn trước khi mở rộng quy mô.
- parallel_trial_count: Nếu bạn sử dụng thử nghiệm song song, dịch vụ sẽ cung cấp nhiều cụm xử lý huấn luyện. Việc tăng số lượng phiên bản thử song song sẽ làm giảm thời gian cần để chạy công việc điều chỉnh siêu thông số. Tuy nhiên, điều này có thể làm giảm hiệu quả của toàn bộ công việc. Điều này là do chiến lược điều chỉnh mặc định sử dụng kết quả của các thử nghiệm trước đó để thông báo việc chỉ định giá trị trong các thử nghiệm tiếp theo.
- search_algorithm: Bạn có thể đặt thuật toán tìm kiếm thành lưới, ngẫu nhiên hoặc mặc định (Không có). Tuỳ chọn mặc định áp dụng phương pháp tối ưu hoá Bayesian để tìm kiếm không gian của các giá trị tham số siêu dữ liệu có thể có và là thuật toán được đề xuất. Bạn có thể tìm hiểu thêm về thuật toán này tại đây.
Sau khi công việc bắt đầu, bạn có thể theo dõi trạng thái trong giao diện người dùng trong thẻ CÔNG VIỆC ĐIỀU CHỈNH THÔNG SỐ Siêu tham số.
Sau khi công việc hoàn tất, bạn có thể xem và sắp xếp kết quả của các lượt thử để khám phá tổ hợp giá trị siêu tham số tốt nhất.
🎉 Xin chúc mừng! 🎉
Bạn đã tìm hiểu cách sử dụng Vertex AI để:
- Chạy công việc điều chỉnh tham số siêu dữ liệu bằng phương pháp huấn luyện phân tán
Để 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.
8. Dọn dẹp
Vì chúng ta đã định cấu hình máy tính xách 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 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 phần Vertex AI Workbench của bảng điều khiển. Nếu bạn muốn xoá toàn bộ sổ tay, hãy nhấp vào nút Xoá.
Để xoá Bộ nhớ, hãy sử dụng trình đơn Điều hướng trong Cloud Console, chuyển đến Bộ nhớ, chọn bộ nhớ của bạn rồi nhấp vào Xoá: