Xem trên TensorFlow.org | Chạy trong Google Colab | Xem trên GitHub | Tải xuống sổ ghi chép | Xem mô hình TF Hub |
TensorFlow Hub là một kho lưu trữ các mô hình TensorFlow được đào tạo trước.
Hướng dẫn này trình bày cách:
- Sử dụng các mô hình từ TensorFlow Hub với
tf.keras
. - Sử dụng mô hình phân loại hình ảnh từ TensorFlow Hub.
- Thực hiện học chuyển tiếp đơn giản để tinh chỉnh một mô hình cho các lớp hình ảnh của riêng bạn.
Thành lập
import numpy as np
import time
import PIL.Image as Image
import matplotlib.pylab as plt
import tensorflow as tf
import tensorflow_hub as hub
import datetime
%load_ext tensorboard
Bộ phân loại ImageNet
Bạn sẽ bắt đầu bằng cách sử dụng mô hình phân loại được đào tạo trước trên tập dữ liệu điểm chuẩn ImageNet — không cần đào tạo ban đầu!
Tải xuống trình phân loại
Chọn một mô hình được đào tạo trước MobileNetV2 từ TensorFlow Hub và bọc nó dưới dạng lớp Keras với hub.KerasLayer
. Mọi mô hình phân loại hình ảnh tương thích từ TensorFlow Hub sẽ hoạt động ở đây, bao gồm các ví dụ được cung cấp trong menu thả xuống bên dưới.
mobilenet_v2 ="https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/4"
inception_v3 = "https://tfhub.dev/google/imagenet/inception_v3/classification/5"
classifier_model = mobilenet_v2
IMAGE_SHAPE = (224, 224)
classifier = tf.keras.Sequential([
hub.KerasLayer(classifier_model, input_shape=IMAGE_SHAPE+(3,))
])
Chạy nó trên một hình ảnh duy nhất
Tải xuống một hình ảnh duy nhất để thử mô hình trên:
grace_hopper = tf.keras.utils.get_file('image.jpg','https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg')
grace_hopper = Image.open(grace_hopper).resize(IMAGE_SHAPE)
grace_hopper
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg 65536/61306 [================================] - 0s 0us/step 73728/61306 [====================================] - 0s 0us/step
grace_hopper = np.array(grace_hopper)/255.0
grace_hopper.shape
(224, 224, 3)
Thêm thứ nguyên lô (với np.newaxis
) và chuyển hình ảnh vào mô hình:
result = classifier.predict(grace_hopper[np.newaxis, ...])
result.shape
(1, 1001)
Kết quả là một vectơ gồm 1001 phần tử của logits, đánh giá xác suất của từng lớp cho hình ảnh.
ID lớp hàng đầu có thể được tìm thấy với tf.math.argmax
:
predicted_class = tf.math.argmax(result[0], axis=-1)
predicted_class
<tf.Tensor: shape=(), dtype=int64, numpy=653>
Giải mã các dự đoán
Lấy ID predicted_class
(chẳng hạn như 653
) và tìm nạp các nhãn tập dữ liệu ImageNet để giải mã các dự đoán:
labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt 16384/10484 [==============================================] - 0s 0us/step 24576/10484 [======================================================================] - 0s 0us/step
plt.imshow(grace_hopper)
plt.axis('off')
predicted_class_name = imagenet_labels[predicted_class]
_ = plt.title("Prediction: " + predicted_class_name.title())
Học chuyển tiếp đơn giản
Nhưng điều gì sẽ xảy ra nếu bạn muốn tạo một bộ phân loại tùy chỉnh bằng cách sử dụng tập dữ liệu của riêng bạn mà có các lớp không được bao gồm trong tập dữ liệu ImageNet ban đầu (mô hình được đào tạo trước đã được đào tạo)?
Để làm điều đó, bạn có thể:
- Chọn một mô hình được đào tạo trước từ TensorFlow Hub; và
- Đào tạo lại lớp trên cùng (cuối cùng) để nhận ra các lớp từ tập dữ liệu tùy chỉnh của bạn.
Dataset
Trong ví dụ này, bạn sẽ sử dụng tập dữ liệu hoa TensorFlow:
data_root = tf.keras.utils.get_file(
'flower_photos',
'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
untar=True)
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz 228818944/228813984 [==============================] - 7s 0us/step 228827136/228813984 [==============================] - 7s 0us/step
Đầu tiên, tải dữ liệu này vào mô hình bằng cách sử dụng dữ liệu hình ảnh trên đĩa với tf.keras.utils.image_dataset_from_directory
, sẽ tạo ra một tf.data.Dataset
:
batch_size = 32
img_height = 224
img_width = 224
train_ds = tf.keras.utils.image_dataset_from_directory(
str(data_root),
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size
)
val_ds = tf.keras.utils.image_dataset_from_directory(
str(data_root),
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size
)
Found 3670 files belonging to 5 classes. Using 2936 files for training. Found 3670 files belonging to 5 classes. Using 734 files for validation.
Tập dữ liệu về hoa có năm lớp:
class_names = np.array(train_ds.class_names)
print(class_names)
['daisy' 'dandelion' 'roses' 'sunflowers' 'tulips']
Thứ hai, vì quy ước của TensorFlow Hub cho các mô hình hình ảnh là mong đợi các đầu vào float trong phạm vi [0, 1]
, hãy sử dụng lớp tiền xử lý tf.keras.layers.Rescaling
để đạt được điều này.
normalization_layer = tf.keras.layers.Rescaling(1./255)
train_ds = train_ds.map(lambda x, y: (normalization_layer(x), y)) # Where x—images, y—labels.
val_ds = val_ds.map(lambda x, y: (normalization_layer(x), y)) # Where x—images, y—labels.
Thứ ba, hoàn thành đường dẫn đầu vào bằng cách sử dụng tìm nạp trước bộ đệm với Dataset.prefetch
, vì vậy bạn có thể cung cấp dữ liệu từ đĩa mà không gặp vấn đề về chặn I / O.
Đây là một số phương pháp tf.data
quan trọng nhất mà bạn nên sử dụng khi tải dữ liệu. Bạn đọc quan tâm có thể tìm hiểu thêm về chúng, cũng như cách lưu dữ liệu vào bộ nhớ cache vào đĩa và các kỹ thuật khác, trong phần Hiệu suất tốt hơn với hướng dẫn API tf.data .
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
for image_batch, labels_batch in train_ds:
print(image_batch.shape)
print(labels_batch.shape)
break
(32, 224, 224, 3) (32,) 2022-01-26 05:06:19.465331: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Chạy trình phân loại trên một loạt hình ảnh
Bây giờ, hãy chạy trình phân loại trên một lô hình ảnh:
result_batch = classifier.predict(train_ds)
predicted_class_names = imagenet_labels[tf.math.argmax(result_batch, axis=-1)]
predicted_class_names
array(['daisy', 'coral fungus', 'rapeseed', ..., 'daisy', 'daisy', 'birdhouse'], dtype='<U30')
Kiểm tra xem các dự đoán này sắp xếp như thế nào với các hình ảnh:
plt.figure(figsize=(10,9))
plt.subplots_adjust(hspace=0.5)
for n in range(30):
plt.subplot(6,5,n+1)
plt.imshow(image_batch[n])
plt.title(predicted_class_names[n])
plt.axis('off')
_ = plt.suptitle("ImageNet predictions")
Các kết quả còn lâu mới hoàn hảo, nhưng hợp lý khi xét rằng đây không phải là các lớp mà mô hình được đào tạo (ngoại trừ "daisy").
Tải xuống mô hình không đầu
TensorFlow Hub cũng phân phối các mô hình không có lớp phân loại trên cùng. Chúng có thể được sử dụng để dễ dàng thực hiện việc học chuyển tiếp.
Chọn một mô hình được đào tạo trước MobileNetV2 từ TensorFlow Hub . Mọi mô hình vectơ đặc trưng hình ảnh tương thích từ TensorFlow Hub sẽ hoạt động ở đây, bao gồm các ví dụ từ trình đơn thả xuống.
mobilenet_v2 = "https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4"
inception_v3 = "https://tfhub.dev/google/tf2-preview/inception_v3/feature_vector/4"
feature_extractor_model = mobilenet_v2
Tạo trình trích xuất tính năng bằng cách bao bọc mô hình được đào tạo trước dưới dạng lớp Keras với hub.KerasLayer
. Sử dụng đối số trainable=False
để đóng băng các biến, để quá trình huấn luyện chỉ sửa đổi lớp phân loại mới:
feature_extractor_layer = hub.KerasLayer(
feature_extractor_model,
input_shape=(224, 224, 3),
trainable=False)
Trình trích xuất tính năng trả về một vectơ dài 1280 cho mỗi hình ảnh (kích thước lô hình ảnh vẫn ở mức 32 trong ví dụ này):
feature_batch = feature_extractor_layer(image_batch)
print(feature_batch.shape)
(32, 1280)
Đính kèm đầu phân loại
Để hoàn thành mô hình, hãy bọc lớp trích xuất tính năng trong một mô hình tf.keras.Sequential
và thêm một lớp được kết nối đầy đủ để phân loại:
num_classes = len(class_names)
model = tf.keras.Sequential([
feature_extractor_layer,
tf.keras.layers.Dense(num_classes)
])
model.summary()
Model: "sequential_1" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= keras_layer_1 (KerasLayer) (None, 1280) 2257984 dense (Dense) (None, 5) 6405 ================================================================= Total params: 2,264,389 Trainable params: 6,405 Non-trainable params: 2,257,984 _________________________________________________________________
predictions = model(image_batch)
predictions.shape
TensorShape([32, 5])
Đào tạo mô hình
Sử dụng Model.compile
để định cấu hình quá trình đào tạo và thêm lệnh gọi lại tf.keras.callbacks.TensorBoard
để tạo và lưu trữ nhật ký:
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['acc'])
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(
log_dir=log_dir,
histogram_freq=1) # Enable histogram computation for every epoch.
Bây giờ sử dụng phương thức Model.fit
để đào tạo mô hình.
Để giữ cho ví dụ này ngắn gọn, bạn sẽ được đào tạo chỉ trong 10 kỷ. Để hình dung tiến trình đào tạo trong TensorBoard sau này, hãy tạo và lưu trữ nhật ký một lệnh gọi lại TensorBoard .
NUM_EPOCHS = 10
history = model.fit(train_ds,
validation_data=val_ds,
epochs=NUM_EPOCHS,
callbacks=tensorboard_callback)
Epoch 1/10 92/92 [==============================] - 7s 42ms/step - loss: 0.7904 - acc: 0.7210 - val_loss: 0.4592 - val_acc: 0.8515 Epoch 2/10 92/92 [==============================] - 3s 33ms/step - loss: 0.3850 - acc: 0.8713 - val_loss: 0.3694 - val_acc: 0.8787 Epoch 3/10 92/92 [==============================] - 3s 33ms/step - loss: 0.3027 - acc: 0.9057 - val_loss: 0.3367 - val_acc: 0.8856 Epoch 4/10 92/92 [==============================] - 3s 33ms/step - loss: 0.2524 - acc: 0.9237 - val_loss: 0.3210 - val_acc: 0.8869 Epoch 5/10 92/92 [==============================] - 3s 33ms/step - loss: 0.2164 - acc: 0.9373 - val_loss: 0.3124 - val_acc: 0.8896 Epoch 6/10 92/92 [==============================] - 3s 33ms/step - loss: 0.1888 - acc: 0.9469 - val_loss: 0.3070 - val_acc: 0.8937 Epoch 7/10 92/92 [==============================] - 3s 33ms/step - loss: 0.1668 - acc: 0.9550 - val_loss: 0.3032 - val_acc: 0.9005 Epoch 8/10 92/92 [==============================] - 3s 33ms/step - loss: 0.1487 - acc: 0.9619 - val_loss: 0.3004 - val_acc: 0.9005 Epoch 9/10 92/92 [==============================] - 3s 33ms/step - loss: 0.1335 - acc: 0.9687 - val_loss: 0.2981 - val_acc: 0.9019 Epoch 10/10 92/92 [==============================] - 3s 33ms/step - loss: 0.1206 - acc: 0.9748 - val_loss: 0.2964 - val_acc: 0.9046
Khởi động TensorBoard để xem các chỉ số thay đổi như thế nào theo từng kỷ nguyên và để theo dõi các giá trị vô hướng khác:
%tensorboard --logdir logs/fit
Kiểm tra các dự đoán
Nhận danh sách có thứ tự các tên lớp từ các dự đoán của mô hình:
predicted_batch = model.predict(image_batch)
predicted_id = tf.math.argmax(predicted_batch, axis=-1)
predicted_label_batch = class_names[predicted_id]
print(predicted_label_batch)
['roses' 'dandelion' 'tulips' 'sunflowers' 'dandelion' 'roses' 'dandelion' 'roses' 'tulips' 'dandelion' 'tulips' 'tulips' 'sunflowers' 'tulips' 'dandelion' 'roses' 'daisy' 'tulips' 'dandelion' 'dandelion' 'dandelion' 'tulips' 'sunflowers' 'roses' 'sunflowers' 'dandelion' 'tulips' 'roses' 'roses' 'sunflowers' 'tulips' 'sunflowers']
Vẽ đồ thị dự đoán mô hình:
plt.figure(figsize=(10,9))
plt.subplots_adjust(hspace=0.5)
for n in range(30):
plt.subplot(6,5,n+1)
plt.imshow(image_batch[n])
plt.title(predicted_label_batch[n].title())
plt.axis('off')
_ = plt.suptitle("Model predictions")
Xuất và tải lại mô hình của bạn
Bây giờ bạn đã đào tạo mô hình, hãy xuất nó dưới dạng SavedModel để sử dụng lại sau này.
t = time.time()
export_path = "/tmp/saved_models/{}".format(int(t))
model.save(export_path)
export_path
2022-01-26 05:07:03.429901: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them. INFO:tensorflow:Assets written to: /tmp/saved_models/1643173621/assets INFO:tensorflow:Assets written to: /tmp/saved_models/1643173621/assets '/tmp/saved_models/1643173621'
Xác nhận rằng bạn có thể tải lại SavedModel và mô hình có thể xuất ra kết quả tương tự:
reloaded = tf.keras.models.load_model(export_path)
result_batch = model.predict(image_batch)
reloaded_result_batch = reloaded.predict(image_batch)
abs(reloaded_result_batch - result_batch).max()
0.0
reloaded_predicted_id = tf.math.argmax(reloaded_result_batch, axis=-1)
reloaded_predicted_label_batch = class_names[reloaded_predicted_id]
print(reloaded_predicted_label_batch)
['roses' 'dandelion' 'tulips' 'sunflowers' 'dandelion' 'roses' 'dandelion' 'roses' 'tulips' 'dandelion' 'tulips' 'tulips' 'sunflowers' 'tulips' 'dandelion' 'roses' 'daisy' 'tulips' 'dandelion' 'dandelion' 'dandelion' 'tulips' 'sunflowers' 'roses' 'sunflowers' 'dandelion' 'tulips' 'roses' 'roses' 'sunflowers' 'tulips' 'sunflowers']
plt.figure(figsize=(10,9))
plt.subplots_adjust(hspace=0.5)
for n in range(30):
plt.subplot(6,5,n+1)
plt.imshow(image_batch[n])
plt.title(reloaded_predicted_label_batch[n].title())
plt.axis('off')
_ = plt.suptitle("Model predictions")
Bước tiếp theo
Bạn có thể sử dụng SavedModel để tải để suy luận hoặc chuyển đổi nó thành mô hình TensorFlow Lite (dành cho máy học trên thiết bị) hoặc mô hình TensorFlow.js (cho máy học trong JavaScript).
Khám phá thêm các hướng dẫn để tìm hiểu cách sử dụng các mô hình được đào tạo trước từ TensorFlow Hub cho các tác vụ hình ảnh, văn bản, âm thanh và video.