בניית רשתות נוירונים מסובכות (CNN) לשיפור ראייה ממוחשבת

1. לפני שמתחילים

במעבדה זו תלמדו איך להשתמש ברשתות CNN כדי לשפר את המודלים לסיווג תמונות.

דרישות מוקדמות

שיעור Lab זה מבוסס על עבודה שהושלמה בשני תשלומים קודמים, בניית מודל של ראייה ממוחשבת, שבה אנחנו מציגים חלק מהקוד שבו תשתמשו כאן, ואת עבודת הפיתוח והביצוע של מאגרי נתונים, שבה נציג המרות ומאגרות.

מה תלמדו

  • איך לשפר את הראייה הממוחשבת ואת מידת הדיוק באמצעות המרות

מה תיצור

  • שכבות לשיפור רשת הנוירונים

מה צריך?

תוכלו למצוא את הקוד עבור שאר קוד הקוד פועל ב-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% בנתוני האימות.

עכשיו אתם יכולים להריץ אותו במשך יותר תקופות של יותר מדי תקופות, ולספר על התוצאות. ייתכן שתוצאות האימון עשויות להיות ממש טובות, אבל תוצאות האימות עלולות לרדת בפועל בגלל תופעה שנקראת התאמה יתר.

התאמה יתר מתרחשת כשהרשת לומדת את הנתונים מהאימון בצורה טובה מדי, ולכן היא מתמחה באיתור של הנתונים האלה בלבד, וכתוצאה מכך היא פחות יעילה בהצגת נתונים אחרים במצבים כלליים יותר. לדוגמה, אם התאמנתם על נעלי עקב בלבד, הרשת עשויה להיות טובה מאוד בזיהוי נעלי עקב, אבל ייתכן שנעלי ספורט יבלבלו אותה.

בדקו שוב את הקוד ובדקו את כל שלבי הפיתוח של ההמרות.

4. לאסוף נתונים

השלב הראשון הוא לאסוף הנתונים.

תוכלו לראות שיש שינוי כאן ואת נתוני האימון שצריך לשנות. הסיבה לכך היא שהפיתול הראשון מצפה לטנור אחד שמכיל הכול, כך שבמקום 60,000 פריטים בגודל 28x28x1 ברשימה, יש לכם רשימת תלת-ממד אחת בגודל 60,000x28x28x1, ואותו דבר עבור תמונות הבדיקה. אם לא תעשו זאת, תופיע הודעת שגיאה בזמן האימון, כי ההמרות האוטומטיות לא מזהות את הצורה.

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) עם תמונות מורכבות.