مشاهده در TensorFlow.org | در Google Colab اجرا شود | مشاهده منبع در GitHub | دانلود دفترچه یادداشت |
این آموزش آموزش یک شبکه عصبی کانولوشنال ساده (CNN) را برای طبقه بندی تصاویر CIFAR نشان می دهد . از آنجایی که این آموزش از Keras Sequential API استفاده می کند، ایجاد و آموزش مدل شما تنها به چند خط کد نیاز دارد.
وارد کردن TensorFlow
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
مجموعه داده CIFAR10 را دانلود و آماده کنید
مجموعه داده CIFAR10 شامل 60000 تصویر رنگی در 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 170508288/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])
# 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 تانسورهای شکل (ارتفاع_تصویر، پهنای_تصویر، رنگ_کانال ها) را می گیرد و اندازه دسته را نادیده می گیرد. اگر در این ابعاد تازه کار هستید، 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 (MaxPooling (None, 6, 6, 64) 0 2D) 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)) به یک یا چند لایه متراکم برای انجام طبقهبندی تغذیه میکنید. لایه های متراکم بردارها را به عنوان ورودی می گیرند (که 1 بعدی هستند)، در حالی که خروجی جریان یک تانسور سه بعدی است. ابتدا خروجی 3 بعدی را صاف می کنید (یا باز می کنید) و سپس یک یا چند لایه متراکم را در بالا اضافه می کنید. CIFAR دارای 10 کلاس خروجی است، بنابراین شما از یک لایه متراکم نهایی با 10 خروجی استفاده می کنید.
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
در اینجا معماری کامل مدل شما آمده است:
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 (MaxPooling (None, 6, 6, 64) 0 2D) 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 [==============================] - 8s 4ms/step - loss: 1.4971 - accuracy: 0.4553 - val_loss: 1.2659 - val_accuracy: 0.5492 Epoch 2/10 1563/1563 [==============================] - 6s 4ms/step - loss: 1.1424 - accuracy: 0.5966 - val_loss: 1.1025 - val_accuracy: 0.6098 Epoch 3/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.9885 - accuracy: 0.6539 - val_loss: 0.9557 - val_accuracy: 0.6629 Epoch 4/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.8932 - accuracy: 0.6878 - val_loss: 0.8924 - val_accuracy: 0.6935 Epoch 5/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.8222 - accuracy: 0.7130 - val_loss: 0.8679 - val_accuracy: 0.7025 Epoch 6/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.7663 - accuracy: 0.7323 - val_loss: 0.9336 - val_accuracy: 0.6819 Epoch 7/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.7224 - accuracy: 0.7466 - val_loss: 0.8546 - val_accuracy: 0.7086 Epoch 8/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.6726 - accuracy: 0.7611 - val_loss: 0.8777 - val_accuracy: 0.7068 Epoch 9/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.6372 - accuracy: 0.7760 - val_loss: 0.8410 - val_accuracy: 0.7179 Epoch 10/10 1563/1563 [==============================] - 6s 4ms/step - loss: 0.6024 - accuracy: 0.7875 - val_loss: 0.8475 - val_accuracy: 0.7192
مدل را ارزیابی کنید
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.8475 - accuracy: 0.7192 - 634ms/epoch - 2ms/step
print(test_acc)
0.7192000150680542
CNN ساده شما به دقت تست بیش از 70 درصد دست یافته است. برای چند خط کد بد نیست! برای یک سبک دیگر CNN، نمونه راه اندازی سریع TensorFlow 2 را برای متخصصان بررسی کنید که از API فرعی Keras و tf.GradientTape
استفاده می کند.