ساخت شبکه های عصبی کانولوشن (CNN) برای تقویت بینایی کامپیوتر

1. قبل از شروع

در این لبه کد، یاد خواهید گرفت که از CNN برای بهبود مدل های طبقه بندی تصاویر خود استفاده کنید.

پیش نیازها

این Codelab بر اساس کارهای تکمیل شده در دو قسمت قبلی ساخته شده است، ساخت مدل بینایی کامپیوتری ، که در آن تعدادی از کدهایی را که در اینجا استفاده خواهید کرد، و Build convolutions و انجام کدهای ادغام را معرفی می کنیم، جایی که ما convolutions و pooling را معرفی می کنیم.

چیزی که یاد خواهید گرفت

  • چگونه می توان دید و دقت کامپیوتر را با کانولوشن بهبود بخشید

چیزی که خواهی ساخت

  • لایه هایی برای تقویت شبکه عصبی شما

آنچه شما نیاز دارید

می‌توانید کد بقیه کدهای در حال اجرا در Colab را پیدا کنید.

همچنین به نصب TensorFlow و کتابخانه هایی که در codelab قبلی نصب کرده اید نیاز دارید.

2. بهبود دقت بینایی کامپیوتر با کانولوشن

اکنون می‌دانید که چگونه با استفاده از یک شبکه عصبی عمیق (DNN) شامل سه لایه - لایه ورودی (به شکل داده‌های ورودی)، لایه خروجی (به شکل خروجی مورد نظر) و یک لایه پنهان، تشخیص تصویر مد را انجام دهید. . شما چندین پارامتر را آزمایش کردید که بر دقت نهایی تأثیر می گذارد، مانند اندازه های مختلف لایه های پنهان و تعداد دوره های آموزشی.

برای راحتی، در اینجا دوباره کل کد آمده است. آن را اجرا کنید و دقت تست را که در انتها چاپ شده است یادداشت کنید.

import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images/255.0
test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_accuracy*100))

دقت شما احتمالاً در مورد آموزش حدود 89 درصد و در تأیید اعتبار 87 درصد است. می‌توانید با استفاده از کانولوشن، که محتوای تصویر را محدود می‌کند تا روی جزئیات خاص و متمایز تمرکز کنید، آن را حتی بهتر کنید.

اگر تا به حال پردازش تصویر را با استفاده از فیلتر انجام داده اید، پیچیدگی ها بسیار آشنا به نظر می رسند.

به طور خلاصه، شما یک آرایه (معمولاً 3x3 یا 5x5) می گیرید و آن را روی تصویر رد می کنید. با تغییر پیکسل های زیرین بر اساس فرمول درون آن ماتریس، می توانید عملیاتی مانند تشخیص لبه را انجام دهید. به عنوان مثال، معمولاً یک 3x3 برای تشخیص لبه تعریف می شود که در آن سلول میانی 8 است و همه همسایگان آن -1 هستند. در این حالت، برای هر پیکسل، مقدار آن را در 8 ضرب کنید، سپس مقدار هر همسایه را کم کنید. این کار را برای هر پیکسل انجام دهید، و در نهایت با یک تصویر جدید مواجه خواهید شد که لبه های آن افزایش یافته است.

این برای بینایی کامپیوتر عالی است، زیرا بهبود ویژگی‌هایی مانند لبه‌ها به رایانه کمک می‌کند تا یک مورد را از دیگری تشخیص دهد. بهتر از آن، مقدار اطلاعات مورد نیاز بسیار کمتر است، زیرا فقط با ویژگی های برجسته آموزش خواهید دید.

این مفهوم شبکه های عصبی کانولوشن است. قبل از اینکه لایه‌های متراکم داشته باشید، چند لایه برای انجام کانولوشن اضافه کنید، و سپس اطلاعاتی که به لایه‌های متراکم می‌روند متمرکزتر و احتمالاً دقیق‌تر می‌شوند.

3. کد را امتحان کنید

کد زیر را اجرا کنید. این همان شبکه عصبی قبلی است، اما این بار با لایه های کانولوشنال ابتدا اضافه شده است. بیشتر طول می کشد، اما به تأثیر آن بر دقت نگاه کنید:

import tensorflow as tf
print(tf.__version__)
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(60000, 28, 28, 1)
training_images=training_images / 255.0
test_images = test_images.reshape(10000, 28, 28, 1)
test_images=test_images / 255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(28, 28, 1)),
  tf.keras.layers.MaxPooling2D(2, 2),
  tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
model.fit(training_images, training_labels, epochs=5)
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_accuracy*100))

احتمالاً در داده‌های آموزشی تا حدود 93 درصد و در داده‌های اعتبارسنجی به 91 درصد افزایش یافته است.

اکنون سعی کنید آن را برای دوره های بیشتری اجرا کنید - مثلاً 20 - و نتایج را بررسی کنید. در حالی که نتایج آموزشی ممکن است واقعاً خوب به نظر برسد، نتایج اعتبارسنجی ممکن است در واقع به دلیل پدیده‌ای به نام overfitting کاهش یابد.

تطبیق بیش از حد زمانی اتفاق می‌افتد که شبکه داده‌های مجموعه آموزشی را خیلی خوب یاد می‌گیرد، بنابراین تشخیص فقط آن داده‌ها تخصصی است و در نتیجه در دیدن سایر داده‌ها در موقعیت‌های عمومی‌تر کارایی کمتری دارد. به عنوان مثال، اگر فقط با کفش پاشنه‌دار تمرین کرده‌اید، ممکن است شبکه در تشخیص کفش‌های پاشنه‌دار بسیار خوب باشد، اما کفش‌های کتانی ممکن است آن را گیج کنند.

دوباره به کد نگاه کنید و گام به گام ببینید که کانولوشن ها چگونه ساخته شده اند.

4. داده ها را جمع آوری کنید

اولین قدم جمع آوری داده هاست.

متوجه خواهید شد که تغییری در اینجا وجود دارد و داده های آموزشی باید تغییر شکل دهند. به این دلیل که اولین کانولوشن انتظار دارد یک تانسور منفرد حاوی همه چیز باشد، بنابراین به جای 60000 مورد 28x28x1 در یک لیست، شما یک لیست 4 بعدی دارید که 60000x28x28x1 است و برای تصاویر آزمایشی یکسان است. اگر این کار را انجام ندهید، هنگام آموزش با خطا مواجه می شوید زیرا پیچش ها شکل را تشخیص نمی دهند.

import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(60000, 28, 28, 1)
training_images = training_images/255.0
test_images = test_images.reshape(10000, 28, 28, 1)
test_images = test_images/255.0

5. مدل را تعریف کنید

بعد، مدل خود را تعریف کنید. به جای لایه ورودی در بالا، می خواهید یک لایه کانولوشن اضافه کنید. پارامترها عبارتند از:

  • تعداد کانولوشن هایی که می خواهید ایجاد کنید. مقداری مانند 32 نقطه شروع خوبی است.
  • اندازه ماتریس کانولوشن، در این مورد یک شبکه 3x3.
  • تابع فعال سازی برای استفاده، در این مورد از relu استفاده کنید.
  • در لایه اول، شکل داده های ورودی.

شما کانولوشن را با یک لایه ادغام حداکثر دنبال می‌کنید، که برای فشرده‌سازی تصویر طراحی شده است و در عین حال محتوای ویژگی‌هایی را که توسط کانولوشن برجسته شده‌اند حفظ می‌کند. با تعیین (2،2) برای حداکثر ادغام، اثر کاهش اندازه تصویر به ضریب 4 است. یک آرایه 2x2 از پیکسل ها ایجاد می کند و بزرگترین مقدار پیکسل را انتخاب می کند و 4 پیکسل را به 1 تبدیل می کند. تکرار می شود. این محاسبه در سراسر تصویر، و با انجام این کار، تعداد پیکسل های افقی را به نصف و تعداد پیکسل های عمودی را به نصف کاهش می دهد.

برای دیدن اندازه و شکل شبکه می توانید مدل. model.summary() را فراخوانی کنید. توجه داشته باشید که پس از هر لایه جمع آوری حداکثر، اندازه تصویر به روش زیر کاهش می یابد:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_2 (Conv2D)            (None, 26, 26, 64)        640       
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 13, 13, 64)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 11, 11, 64)        36928     
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 1600)              0         
_________________________________________________________________
dense_4 (Dense)              (None, 128)               204928    
_________________________________________________________________
dense_5 (Dense)              (None, 10)                1290      
=================================================================

در اینجا کد کامل برای CNN آمده است:

model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(2, 2),
#Add another convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
#Now flatten the output. After this you'll just have the same DNN structure as the non convolutional version
tf.keras.layers.Flatten(),
#The same 128 dense layers, and 10 output layers as in the pre-convolution example:
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])

6. مدل را کامپایل و آموزش دهید

مدل را کامپایل کنید، روش فیت را برای انجام آموزش فراخوانی کنید و از دست دادن و دقت از مجموعه تست ارزیابی کنید.

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)
test_loss, test_acc = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_acc*100))

7. پیچیدگی ها و ادغام ها را تجسم کنید

این کد پیچیدگی ها را به صورت گرافیکی به شما نشان می دهد. print (test_labels[:100]) 100 برچسب اول در مجموعه آزمایشی را نشان می دهد، و می توانید ببینید که آنهایی که در شاخص 0، شاخص 23 و شاخص 28 قرار دارند، همگی یک مقدار هستند (9). همشون کفش هستن به نتیجه اجرای کانولوشن روی هر یک نگاهی بیندازید و خواهید دید که ویژگی های مشترک بین آنها ظاهر می شود. اکنون، زمانی که DNN بر روی آن داده‌ها آموزش می‌دهد، با اطلاعات بسیار کمتری کار می‌کند و شاید بر اساس آن ترکیب کانولوشن و ادغام، وجه اشتراکی بین کفش‌ها پیدا کند.

print(test_labels[:100])
[9 2 1 1 6 1 4 6 5 7 4 5 7 3 4 1 2 4 8 0 2 5 7 9 1 4 6 0 9 3 8 8 3 3 8 0 7
 5 7 9 6 1 3 7 6 7 2 1 2 2 4 4 5 8 2 2 8 4 8 0 7 7 8 5 1 1 2 3 9 8 7 0 2 6
 2 3 1 2 8 4 1 8 5 9 5 0 3 2 0 6 5 3 6 7 1 8 0 1 4 2]

اکنون می‌توانید برخی از تصاویر مربوطه را برای آن برچسب‌ها انتخاب کنید و در کانولوشن‌ها به شکل ظاهری آن‌ها ارائه دهید. بنابراین، در کد زیر، FIRST_IMAGE ، SECOND_IMAGE و THIRD_IMAGE همه شاخص‌های مقدار 9، یک بوت مچ پا هستند.

import matplotlib.pyplot as plt
f, axarr = plt.subplots(3,4)
FIRST_IMAGE=0
SECOND_IMAGE=23
THIRD_IMAGE=28
CONVOLUTION_NUMBER = 6
from tensorflow.keras import models
layer_outputs = [layer.output for layer in model.layers]
activation_model = tf.keras.models.Model(inputs = model.input, outputs = layer_outputs)
for x in range(0,4):
  f1 = activation_model.predict(test_images[FIRST_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[0,x].imshow(f1[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[0,x].grid(False)
  f2 = activation_model.predict(test_images[SECOND_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[1,x].imshow(f2[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[1,x].grid(False)
  f3 = activation_model.predict(test_images[THIRD_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[2,x].imshow(f3[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[2,x].grid(False)

و شما باید چیزی شبیه به زیر را ببینید، جایی که پیچیدگی جوهره زیره کفش را می گیرد و به طور موثر آن را به عنوان یک ویژگی مشترک در همه کفش ها می بیند.

6c9109bcc640a1ec.png

8. تمرینات

تمرین 1

سعی کنید پیچیدگی ها را ویرایش کنید. تعداد پیچش ها را از 32 به 16 یا 64 تغییر دهید. چه تأثیری بر دقت و زمان تمرین دارد؟

تمرین 2

پیچ نهایی را حذف کنید. چه تأثیری بر دقت یا زمان تمرین دارد؟

تمرین 3

کانولوشن های بیشتری اضافه کنید. چه تاثیری دارد؟

تمرین 4

همه پیچیدگی ها را حذف کنید به جز اولین. چه تاثیری دارد؟ با آن آزمایش کنید.

9. تبریک می گویم

شما اولین CNN خود را ساخته اید! برای یادگیری نحوه بهبود بیشتر مدل‌های بینایی رایانه خود، به استفاده از شبکه‌های عصبی کانولوشن (CNN) با تصاویر پیچیده بروید.