FINE TUNING LÀ GÌ

  -  

Tiếp nối bài trước về Transfer Learning, hôm nay chúng ta cùng tìm hiểu về Fine Tuning.

Bạn đang xem: Fine tuning là gì

Mở đầu

Fine tuning : Thuật ngữ này có thể được dịch là “Tinh chỉnh” – là một quá trình sử dụng một mô hình mạng đã được huấn luyện cho một nhiệm vụ nhất định để thực hiện một nhiệm vụ tương tự. Sở dĩ cách lý giải này có phần giống Transfer Learning – bởi Fine Tuning là một kỹ thuật Transfer Learning mà ! Hãy cùng tìm hiểu xem cụ thể nó là thế nào nhé.

Khi mô hình của bạn đã hội tụ trên dữ liệu mới, bạn có thể cố gắng giải phóng toàn bộ hoặc một phần của mô hình cơ sở và đào tạo lại toàn bộ mô hình từ đầu đến cuối với tỷ lệ học tập rất thấp.

Đây là bước cuối cùng tùy chọn có thể mang lại cho bạn những cải tiến gia tăng. Nó cũng có thể dẫn đến tình trạng overfitting – hãy cân nhắc điều đó.

Điều quan trọng là chỉ thực hiện bước này sau khi mô hình với các lớp đông lạnh đã được huấn luyện để hội tụ. Nếu bạn trộn các lớp trainable được khởi tạo ngẫu nhiên với các lớp trainable chứa các tính năng đã được huấn luyện trước, các lớp được khởi tạo ngẫu nhiên sẽ gây ra các cập nhật gradient rất lớn trong quá trình huấn luyện, điều này sẽ phá hủy các tính năng đã được huấn luyện trước của bạn.

Một vấn đề quan trọng nữa là là sử dụng tỷ lệ học tập rất thấp ở giai đoạn này, bởi vì bạn đang đào tạo một mô hình lớn hơn nhiều so với trong vòng đào tạo đầu tiên, trên một tập dữ liệu thường rất nhỏ. Do đó, bạn có nguy cơ bị overfitting rất nhanh nếu áp dụng các biện pháp cập nhật trọng lượng lớn. Ở đây, bạn chỉ muốn đọc các trọng số được huấn luyện trước theo cách tăng dần.

Đây là cách implement fine-tuning toàn bộ mô hình cơ sở:

# Hủy đóng băng mô hình cơ sởbase_model.trainable = True# Quan trọng là phải biên dịch lại mô hình của bạn sau khi thực hiện bất kỳ thay đổi nào đối với thuộc tính `trainable` của bất kỳ lớp bên trong nào# Để các thay đổi của bạn được tính đếnmodel.compile(optimizer=keras.optimizers.Adam(1e-5), # Tỉ lệ học rất thấp loss=keras.losses.BinaryCrossentropy(from_logits=True), metrics=)# Train. Cẩn thận để dừng lại trước khi bị overfitmodel.fit(new_dataset, epochs=10, callbacks=..., validation_data=...)Lưu ý quan trọng về compile() và trainable

Việc gọi compile() trên một mô hình có nghĩa là "đóng băng" hành vi của mô hình đó. Điều này ngụ ý rằng các giá trị thuộc tính trainable tại thời điểm mô hình được biên dịch nên được bảo toàn trong suốt thời gian tồn tại của mô hình đó, cho đến khi quá trình biên dịch được gọi lại. Do đó, nếu bạn thay đổi bất kỳ giá trị có thể đào tạo nào, hãy đảm bảo gọi lại compile () trên mô hình của bạn để các thay đổi của bạn được tính đến.

Lưu ý quan trọng về lớp BatchNormalization

Nhiều mô hình hình ảnh chứa các lớp BatchNormalization. Lớp đó là một trường hợp đặc biệt trên mọi số lượng có thể tưởng tượng được. Dưới đây là một số điều cần ghi nhớ.

BatchNormalization chứa 2 trọng lượng không thể đào tạo được cập nhật trong quá trình đào tạo. Đây là các biến theo dõi giá trị trung bình và phương sai của các yếu tố đầu vào.Khi bạn đặt bn_layer.trainable = False, lớp BatchNormalization sẽ chạy ở chế độ suy luận và sẽ không cập nhật thống kê trung bình & phương sai của nó. Điều này không đúng với các lớp khác nói chung, vì khả năng tập tạ & chế độ suy luận / huấn luyện là hai khái niệm trực giao. Nhưng cả hai được gắn với nhau trong trường hợp của lớp BatchNormalization.Khi bạn giải phóng một mô hình có chứa các lớp BatchNormalization để thực hiện tinh chỉnh, bạn nên giữ các lớp BatchNormalization ở chế độ suy luận bằng cách chuyển training = False khi gọi mô hình cơ sở. Nếu không, các bản cập nhật được áp dụng cho các trọng lượng không thể đào tạo sẽ đột ngột phá hủy những gì mà mô hình đã học được.

Xem thêm: Kinh Nghiệm Du Lịch Nhatrang Bằng Tàu 5 Sao Đi Nha Trang, Cận Cảnh Tàu Ƌ Sao' Tuyến Sài Gòn

Bạn sẽ thấy mẫu này hoạt động trong ví dụ end-to-end ở cuối hướng dẫn này.

Transfer learning & fine-tuning với một vòng lặp đào tạo tùy chỉnh

Nếu thay vì fit(), bạn đang sử dụng vòng lặp đào tạo cấp thấp của riêng mình, thì quy trình làm việc về cơ bản vẫn giữ nguyên. Bạn nên cẩn thận chỉ tính đến danh sách model.trainable_weights khi áp dụng cập nhật gradient:

# Khởi tạo mô hình cơ sởbase_model = keras.applications.Xception( weights='imagenet', input_shape=(150, 150, 3), include_top=False)# Đóng băng mô hình cơ sởbase_model.trainable = False# Khởi tạo một mô hình mới on top.inputs = keras.Input(shape=(150, 150, 3))x = base_model(inputs, training=False)x = keras.layers.GlobalAveragePooling2D()(x)outputs = keras.layers.Dense(1)(x)model = keras.Model(inputs, outputs)loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)optimizer = keras.optimizers.Adam()# Lặp lại các lô của tập dữ liệu.for inputs, targets in new_dataset: # Mở GradientTape. with tf.GradientTape() as tape: # Chuyển tiếp predictions = model(inputs) # Tính toán giá trị tổn thất cho lô này. loss_value = loss_fn(targets, predictions) # Lấy gradients với độ giảm của trọng số *trainable*. gradients = tape.gradient(loss_value, model.trainable_weights) # Cập nhật trọng số của mô hình optimizer.apply_gradients(zip(gradients, model.trainable_weights))

Một ví dụ từ đầu đến cuối: tinh chỉnh mô hình phân loại hình ảnh trên tập dữ liệu mèo và chó

Để củng cố những khái niệm này, hãy hướng dẫn bạn qua một ví dụ cụ thể về học tập và tinh chỉnh chuyển giao từ đầu đến cuối. Chúng tôi sẽ tải mô hình Xception, được đào tạo trước trên ImageNet và sử dụng nó trên tập dữ liệu phân loại Kaggle "mèo so với chó".

Lấy dữ liệu

Đầu tiên, hãy tìm nạp tập dữ liệu mèo và chó bằng TFDS. Nếu bạn có tập dữ liệu của riêng mình, có thể bạn sẽ muốn sử dụng tiện ích tf.keras.preprocessing.image_dataset_from_directory để tạo các đối tượng tập dữ liệu có nhãn tương tự từ một tập hợp các hình ảnh trên đĩa được lưu trữ vào các thư mục dành riêng cho lớp.

Học chuyển giao hữu ích nhất khi làm việc với các tập dữ liệu rất nhỏ. Để giữ cho tập dữ liệu của chúng tôi nhỏ, chúng tôi sẽ sử dụng 40% dữ liệu đào tạo ban đầu (25.000 hình ảnh) để đào tạo, 10% để xác thực và 10% để kiểm tra.

import tensorflow_datasets as tfdstfds.disable_progress_bar()train_ds, validation_ds, test_ds = tfds.load( "cats_vs_dogs", # Reserve 10% for validation and 10% for test split=<"train<:40%>", "train<40%:50%>", "train<50%:60%>">, as_supervised=True, # Include labels)print("Number of training samples: %d" % tf.data.experimental.cardinality(train_ds))print("Number of validation samples: %d" % tf.data.experimental.cardinality(validation_ds))print("Number of test samples: %d" % tf.data.experimental.cardinality(test_ds))Number of training samples: 9305Number of validation samples: 2326Number of test samples: 2326Đây là 9 hình ảnh đầu tiên trong tập dữ liệu đào tạo – như bạn có thể thấy, chúng đều có kích thước khác nhau.

import matplotlib.pyplot as pltplt.figure(figsize=(10, 10))for i, (image, label) in enumerate(train_ds.take(9)): ax = plt.subplot(3, 3, i + 1) plt.imshow(image) plt.title(int(label)) plt.axis("off")

*
*
*

Xây dựng một mô hình

Bây giờ chúng ta hãy xây dựng một mô hình theo kế hoạch chi tiết đã giải thích trước đó.

Lưu ý rằng:

Thêm một lớp Rescaling để chia tỷ lệ các giá trị đầu vào (ban đầu trong phạm vi <0, 255>) thành phạm vi <-1, 1>.Thêm một lớp Dropout trước lớp phân loại, để chính quy hóa.Đảm bảo training = False khi gọi mô hình cơ sở, để nó chạy ở chế độ suy luận, do đó thống kê batchnorm không được cập nhật ngay cả sau khi chúng tôi giải phóng mô hình cơ sở để fine-tuning.

Xem thêm: Cách Làm Thủ Tục Lên Máy Bay Vietjet Air 2021, Cách Làm Thủ Tục Lên Máy Bay Vietjet

Quan trọng là, mặc dù mô hình cơ sở trở nên có thể huấn luyện được, nhưng nó vẫn đang chạy ở chế độ suy luận vì chúng ta đã đặt training=False khi gọi nó khi chúng ta xây dựng mô hình. Điều này có nghĩa là các lớp chuẩn hóa hàng loạt bên trong sẽ không cập nhật thống kê hàng loạt của chúng. Nếu họ làm vậy, họ sẽ phá hủy các đại diện mà mô hình đã học cho đến nay.

Kết bài

Trên đây chúng ta đã tìm hiểu kỹ thuật Fine-tuning.Cảm ơn các bạn đã giành thời gian theo dõi.Thân ái !