Evrişimsel Sinir Ağı (CNN)

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Bu öğretici, CIFAR görüntülerini sınıflandırmak için basit bir Evrişimli Sinir Ağı (CNN) eğitimini gösterir. Bu öğretici Keras Sequential API kullandığından, modelinizi oluşturmak ve eğitmek yalnızca birkaç satır kod alacaktır.

TensorFlow'u İçe Aktar

import tensorflow as tf

from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt

CIFAR10 veri setini indirin ve hazırlayın

CIFAR10 veri seti, her sınıfta 6.000 görüntü olmak üzere 10 sınıfta 60.000 renkli görüntü içerir. Veri seti 50.000 eğitim görüntüsüne ve 10.000 test görüntüsüne bölünmüştür. Sınıflar birbirini dışlar ve aralarında örtüşme yoktur.

(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
tutucu2 l10n-yer
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170500096/170498071 [==============================] - 11s 0us/step
170508288/170498071 [==============================] - 11s 0us/step

Verileri doğrulayın

Veri kümesinin doğru göründüğünü doğrulamak için, eğitim kümesindeki ilk 25 görüntüyü çizelim ve her görüntünün altında sınıf adını görüntüleyelim:

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()

png

Evrişimli tabanı oluşturun

Aşağıdaki 6 kod satırı, ortak bir model kullanarak evrişimli tabanı tanımlar: bir Conv2D ve MaxPooling2D katmanları yığını.

Girdi olarak, bir CNN, parti boyutunu göz ardı ederek şekil tensörlerini (image_height, image_width, color_channels) alır. Bu boyutlarda yeniyseniz, color_channels (R,G,B) anlamına gelir. Bu örnekte, CNN'nizi, CIFAR görüntülerinin formatı olan şekil girişlerini (32, 32, 3) işlemek için yapılandıracaksınız. Bunu input_shape argümanını ilk katmanınıza ileterek yapabilirsiniz.

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'))

Şimdiye kadar modelinizin mimarisini gösterelim:

model.summary()
tutucu6 l10n-yer
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
_________________________________________________________________

Yukarıda, her Conv2D ve MaxPooling2D katmanının çıktısının bir 3B şekil tensörü (yükseklik, genişlik, kanallar) olduğunu görebilirsiniz. Ağda daha derine indikçe genişlik ve yükseklik boyutları küçülme eğilimindedir. Her Conv2D katmanı için çıktı kanallarının sayısı, ilk argüman tarafından kontrol edilir (örneğin, 32 veya 64). Tipik olarak, genişlik ve yükseklik küçüldükçe, her Conv2D katmanına daha fazla çıktı kanalı eklemeyi (hesaplamalı olarak) karşılayabilirsiniz.

Üzerine Yoğun katmanlar ekleyin

Modeli tamamlamak için, sınıflandırma gerçekleştirmek için konvolüsyonel tabandan (şekil (4, 4, 64)) son çıktı tensörünü bir veya daha fazla Yoğun katmana besleyeceksiniz. Yoğun katmanlar, giriş olarak vektörleri (1B olan) alırken, mevcut çıktı bir 3B tensördür. İlk olarak, 3B çıktıyı 1B olarak düzleştirecek (veya açacaksınız), ardından üstüne bir veya daha fazla Yoğun katman ekleyeceksiniz. CIFAR'ın 10 çıktı sınıfı vardır, bu nedenle 10 çıktılı son bir Yoğun katman kullanırsınız.

model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))

İşte modelinizin tam mimarisi:

model.summary()
tutucu9 l10n-yer
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
_________________________________________________________________

Ağ özeti, (4, 4, 64) çıktılarının, iki Yoğun katmandan geçmeden önce şekil vektörlerine (1024) düzleştirildiğini gösterir.

Modeli derleyin ve eğitin

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))
tutucu11 l10n-yer
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

Modeli değerlendirin

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)
tutucu13 l10n-yer
313/313 - 1s - loss: 0.8475 - accuracy: 0.7192 - 634ms/epoch - 2ms/step

png

print(test_acc)
tutucu15 l10n-yer
0.7192000150680542

Basit CNN'niz %70'in üzerinde bir test doğruluğu elde etti. Birkaç satır kod için fena değil! Başka bir CNN stili için, Keras alt sınıflama API'sini ve tf.GradientTape kullanan uzmanlar için TensorFlow 2 hızlı başlangıcına bakın.