مشاهده در TensorFlow.org | در Google Colab اجرا شود | در GitHub مشاهده کنید | دانلود دفترچه یادداشت | مدل TF Hub را ببینید |
TensorFlow Hub یک مخزن از مدل های TensorFlow از پیش آموزش دیده است.
این آموزش نشان می دهد که چگونه:
- از مدل های TensorFlow Hub با
tf.keras
استفاده کنید. - از یک مدل طبقه بندی تصویر از TensorFlow Hub استفاده کنید.
- آموزش انتقال ساده را انجام دهید تا یک مدل را برای کلاس های تصویر خود تنظیم کنید.
برپایی
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
یک طبقه بندی کننده ImageNet
شما با استفاده از یک مدل طبقهبندیکننده که از قبل بر روی مجموعه دادههای معیار ImageNet آموزش داده شده است، شروع میکنید — بدون نیاز به آموزش اولیه!
طبقه بندی کننده را دانلود کنید
یک مدل از پیش آموزش دیده MobileNetV2 را از TensorFlow Hub انتخاب کنید و آن را به عنوان یک لایه Keras با hub.KerasLayer
. هر مدل طبقهبندی کننده تصویر سازگار از TensorFlow Hub، از جمله نمونههای ارائهشده در کشویی زیر، در اینجا کار میکند.
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,))
])
آن را روی یک تصویر اجرا کنید
برای امتحان مدل، یک تصویر را دانلود کنید:
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)
یک بعد دسته ای اضافه کنید (با np.newaxis
) و تصویر را به مدل منتقل کنید:
result = classifier.predict(grace_hopper[np.newaxis, ...])
result.shape
(1, 1001)
نتیجه یک بردار 1001 عنصری از logit ها است که احتمال هر کلاس را برای تصویر رتبه بندی می کند.
شناسه کلاس برتر را می توان با tf.math.argmax
پیدا کرد:
predicted_class = tf.math.argmax(result[0], axis=-1)
predicted_class
<tf.Tensor: shape=(), dtype=int64, numpy=653>
پیش بینی ها را رمزگشایی کنید
شناسه predicted_class
(مانند 653
) را بگیرید و برچسب های مجموعه داده ImageNet را برای رمزگشایی پیش بینی ها واکشی کنید:
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())
یادگیری انتقال ساده
اما اگر میخواهید با استفاده از مجموعه دادههای خود یک طبقهبندی سفارشی ایجاد کنید که دارای کلاسهایی باشد که در مجموعه داده اصلی ImageNet گنجانده نشدهاند (که مدل از پیش آموزش دیده روی آن آموزش داده شده است)؟
برای انجام این کار، می توانید:
- یک مدل از پیش آموزش دیده را از TensorFlow Hub انتخاب کنید. و
- لایه بالایی (آخرین) را مجدداً آموزش دهید تا کلاس ها را از مجموعه داده سفارشی خود شناسایی کنید.
مجموعه داده
در این مثال، از مجموعه داده گل های 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
ابتدا، این داده ها را با استفاده از داده های تصویر خارج از دیسک با tf.keras.utils.image_dataset_from_directory
در مدل بارگذاری کنید، که یک 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.
مجموعه داده گل دارای پنج کلاس است:
class_names = np.array(train_ds.class_names)
print(class_names)
['daisy' 'dandelion' 'roses' 'sunflowers' 'tulips']
دوم، از آنجایی که قرارداد TensorFlow Hub برای مدلهای تصویر انتظار ورودیهای شناور در محدوده [0, 1]
است، برای رسیدن به این هدف از لایه پیشپردازش tf.keras.layers.Rescaling
استفاده کنید.
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.
سوم، خط لوله ورودی را با استفاده از واکشی اولیه بافر با Dataset.prefetch
به پایان برسانید، بنابراین می توانید داده ها را از دیسک بدون مشکلات مسدود کردن ورودی/خروجی به دست آورید.
اینها برخی از مهم ترین روش های tf.data
هستند که باید هنگام بارگیری داده ها استفاده کنید. خوانندگان علاقه مند می توانند با راهنمای tf.data API اطلاعات بیشتری در مورد آنها و همچنین نحوه ذخیره داده ها در حافظه پنهان روی دیسک و سایر تکنیک ها کسب کنند.
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.
طبقه بندی کننده را روی دسته ای از تصاویر اجرا کنید
اکنون، طبقهبندی کننده را روی یک دسته تصویر اجرا کنید:
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')
بررسی کنید که چگونه این پیش بینی ها با تصاویر مطابقت دارند:
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")
با توجه به اینکه اینها طبقاتی نیستند که مدل برای آنها آموزش داده شده است (به جز "دیزی") نتایج بسیار عالی هستند، اما معقول هستند.
دانلود مدل بی سر
TensorFlow Hub همچنین مدل ها را بدون لایه طبقه بندی بالایی توزیع می کند. از اینها می توان برای انجام آسان یادگیری انتقال استفاده کرد.
یک مدل از پیش آموزش دیده MobileNetV2 را از TensorFlow Hub انتخاب کنید. هر مدل بردار ویژگی تصویر سازگار از TensorFlow Hub در اینجا کار می کند، از جمله نمونه هایی از منوی کشویی.
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
استخراج کننده ویژگی را با قرار دادن مدل از پیش آموزش داده شده به عنوان لایه Keras با hub.KerasLayer
کنید. از آرگومان trainable=False
برای ثابت کردن متغیرها استفاده کنید، به طوری که آموزش فقط لایه طبقهبندیکننده جدید را تغییر میدهد:
feature_extractor_layer = hub.KerasLayer(
feature_extractor_model,
input_shape=(224, 224, 3),
trainable=False)
استخراج کننده ویژگی برای هر تصویر یک بردار 1280 برمی گرداند (اندازه دسته تصویر در این مثال 32 باقی می ماند):
feature_batch = feature_extractor_layer(image_batch)
print(feature_batch.shape)
(32, 1280)
یک سر طبقه بندی را ضمیمه کنید
برای تکمیل مدل، لایه استخراج ویژگی را در یک مدل tf.keras.Sequential
و یک لایه کاملا متصل برای طبقه بندی اضافه کنید:
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])
مدل را آموزش دهید
از Model.compile
برای پیکربندی فرآیند آموزش استفاده کنید و یک پاسخ تماس tf.keras.callbacks.TensorBoard
برای ایجاد و ذخیره گزارشها اضافه کنید:
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.
حال از روش Model.fit
برای آموزش مدل استفاده کنید.
برای کوتاه نگه داشتن این مثال، شما فقط برای 10 دوره آموزش خواهید دید. برای تجسم پیشرفت آموزش در TensorBoard بعداً، یک تماس 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
TensorBoard را برای مشاهده نحوه تغییر معیارها در هر دوره و ردیابی سایر مقادیر اسکالر راه اندازی کنید:
%tensorboard --logdir logs/fit
پیش بینی ها را بررسی کنید
لیست مرتب نام کلاس ها را از پیش بینی های مدل بدست آورید:
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']
پیش بینی های مدل را ترسیم کنید:
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")
مدل خود را صادر و بارگذاری مجدد کنید
اکنون که مدل را آموزش دادهاید، آن را به عنوان SavedModel صادر کنید تا بعداً دوباره از آن استفاده کنید.
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'
تأیید کنید که میتوانید SavedModel را مجدداً بارگیری کنید و مدل میتواند نتایج یکسانی را ارائه دهد:
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")
مراحل بعدی
میتوانید از SavedModel برای بارگیری برای استنتاج استفاده کنید یا آن را به یک مدل TensorFlow Lite (برای یادگیری ماشین روی دستگاه) یا یک مدل TensorFlow.js (برای یادگیری ماشین در جاوا اسکریپت) تبدیل کنید.
برای یادگیری نحوه استفاده از مدل های از پیش آموزش دیده از TensorFlow Hub در کارهای تصویری، متنی، صوتی و ویدیویی، آموزش های بیشتری را کشف کنید.