عرض على TensorFlow.org | تشغيل في Google Colab | عرض على جيثب | تحميل دفتر | انظر نموذج 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 عنصر ، ويصنف احتمالية كل فئة للصورة.
يمكن العثور على معرّف الفئة الأعلى باستخدام 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 (للتعلم الآلي في JavaScript).
اكتشف المزيد من البرامج التعليمية لمعرفة كيفية استخدام النماذج المدربة مسبقًا من TensorFlow Hub في مهام الصور والنص والصوت والفيديو.