![]() | ![]() | ![]() | ![]() |
يوضح هذا البرنامج التعليمي تدريب شبكة عصبية تلافيفية بسيطة (CNN) لتصنيف صور CIFAR . نظرًا لأن هذا البرنامج التعليمي يستخدم Keras Sequential API ، فإن إنشاء نموذجنا وتدريبه سيستغرق بضعة أسطر من التعليمات البرمجية.
استيراد TensorFlow
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
قم بتنزيل وإعداد مجموعة بيانات CIFAR10
تحتوي مجموعة بيانات CIFAR10 على 60.000 صورة ملونة في 10 فئات ، مع 6000 صورة في كل فئة. تنقسم مجموعة البيانات إلى 50000 صورة تدريب و 10000 صورة اختبار. الفئات متنافية ولا يوجد تداخل بينها.
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
# Normalize pixel values to be between 0 and 1
train_images, test_images = train_images / 255.0, test_images / 255.0
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 170500096/170498071 [==============================] - 11s 0us/step
تحقق من البيانات
للتحقق من أن مجموعة البيانات تبدو صحيحة ، دعنا نرسم أول 25 صورة من مجموعة التدريب ونعرض اسم الفصل أسفل كل صورة.
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck']
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i], cmap=plt.cm.binary)
# The CIFAR labels happen to be arrays,
# which is why you need the extra index
plt.xlabel(class_names[train_labels[i][0]])
plt.show()
أنشئ القاعدة التلافيفية
خطوط 6 من التعليمات البرمجية أدناه تحديد قاعدة التلافيف باستخدام النمط الشائع: كومة من Conv2D و MaxPooling2D طبقات.
كإدخال ، تأخذ CNN الموترات من الشكل (image_height ، image_width ، color_channels) ، متجاهلة حجم الدُفعة. إذا كنت جديدًا على هذه الأبعاد ، فإن قنوات color_channels تشير إلى (R ، G ، B). في هذا المثال ، ستقوم بتكوين شبكة CNN الخاصة بنا لمعالجة مدخلات الشكل (32 ، 32 ، 3) ، وهو تنسيق صور CIFAR. يمكنك القيام بذلك عن طريق تمرير input_shape
إلى الطبقة الأولى.
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
دعونا نعرض بنية نموذجنا حتى الآن.
model.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 30, 30, 32) 896 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 13, 13, 64) 18496 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 4, 4, 64) 36928 ================================================================= Total params: 56,320 Trainable params: 56,320 Non-trainable params: 0 _________________________________________________________________
أعلاه ، يمكنك أن ترى أن ناتج كل طبقة Conv2D و MaxPooling2D هو موتر ثلاثي الأبعاد للشكل (الارتفاع ، العرض ، القنوات). تميل أبعاد العرض والارتفاع إلى الانكماش كلما تعمقت في الشبكة. يتم التحكم في عدد قنوات الإخراج لكل طبقة Conv2D بواسطة الوسيطة الأولى (على سبيل المثال ، 32 أو 64). عادةً ، مع تقلص العرض والارتفاع ، يمكنك تحمل (حسابيًا) لإضافة المزيد من قنوات الإخراج في كل طبقة Conv2D.
أضف طبقات كثيفة في الأعلى
لإكمال نموذجنا ، ستقوم بتغذية آخر موتر الإخراج من القاعدة التلافيفية (للشكل (4 ، 4 ، 64)) في طبقة كثيفة واحدة أو أكثر لإجراء التصنيف. تأخذ الطبقات الكثيفة المتجهات كمدخلات (وهي 1D) ، بينما الإخراج الحالي هو موتر ثلاثي الأبعاد. أولاً ، ستقوم بتسوية (أو إلغاء) الإخراج ثلاثي الأبعاد إلى 1D ، ثم إضافة طبقة كثيفة واحدة أو أكثر في الأعلى. تحتوي CIFAR على 10 فئات إخراج ، لذلك يمكنك استخدام طبقة كثيفة نهائية مع 10 مخرجات.
0029 ب 61270ها هي البنية الكاملة لنموذجنا.
model.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 30, 30, 32) 896 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 13, 13, 64) 18496 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 4, 4, 64) 36928 _________________________________________________________________ flatten (Flatten) (None, 1024) 0 _________________________________________________________________ dense (Dense) (None, 64) 65600 _________________________________________________________________ dense_1 (Dense) (None, 10) 650 ================================================================= Total params: 122,570 Trainable params: 122,570 Non-trainable params: 0 _________________________________________________________________
كما ترى ، تم تسوية مخرجاتنا (4 ، 4 ، 64) إلى متجهات الشكل (1024) قبل المرور عبر طبقتين كثيفتين.
تجميع وتدريب النموذج
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels))
Epoch 1/10 1563/1563 [==============================] - 18s 4ms/step - loss: 1.7606 - accuracy: 0.3488 - val_loss: 1.2753 - val_accuracy: 0.5504 Epoch 2/10 1563/1563 [==============================] - 6s 4ms/step - loss: 1.1977 - accuracy: 0.5751 - val_loss: 1.0409 - val_accuracy: 0.6371 Epoch 3/10 1563/1563 [==============================] - 6s 4ms/step - loss: 1.0137 - accuracy: 0.6439 - val_loss: 0.9613 - val_accuracy: 0.6597 Epoch 4/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.8844 - accuracy: 0.6908 - val_loss: 0.9272 - val_accuracy: 0.6766 Epoch 5/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.7950 - accuracy: 0.7205 - val_loss: 0.8712 - val_accuracy: 0.6923 Epoch 6/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.7410 - accuracy: 0.7388 - val_loss: 0.8894 - val_accuracy: 0.6943 Epoch 7/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.6924 - accuracy: 0.7547 - val_loss: 0.8980 - val_accuracy: 0.6993 Epoch 8/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.6453 - accuracy: 0.7728 - val_loss: 0.8695 - val_accuracy: 0.7109 Epoch 9/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.5999 - accuracy: 0.7881 - val_loss: 0.8887 - val_accuracy: 0.7098 Epoch 10/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.5461 - accuracy: 0.8088 - val_loss: 0.8840 - val_accuracy: 0.7157
قم بتقييم النموذج
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0.5, 1])
plt.legend(loc='lower right')
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
313/313 - 1s - loss: 0.8840 - accuracy: 0.7157
print(test_acc)
0.7156999707221985
لقد حققت شبكة CNN البسيطة الخاصة بنا دقة اختبار تزيد عن 70٪. ليس سيئا لبضعة أسطر من التعليمات البرمجية! للحصول على نمط CNN آخر ، راجع مثالاً باستخدام واجهة برمجة تطبيقات الفئة الفرعية Keras وtf.GradientTape
هنا .