עזרה להגן על שונית המחסום הגדולה עם TensorFlow על Kaggle הצטרפו אתגר

סיווג בסיסי: סיווג תמונות של בגדים

הצג באתר TensorFlow.org הפעל ב-Google Colab צפה במקור ב-GitHub הורד מחברת

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

מדריך זה משתמש tf.keras , ה- API ברמה גבוהה למודלים לבנות ורכבת TensorFlow.

# TensorFlow and tf.keras
import tensorflow as tf

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt

print(tf.__version__)
2.5.0

ייבא את מערך הנתונים של Fashion MNIST

מדריך זה משתמש אופנה MNIST הנתונים המכיל 70,000 תמונות בגווני אפור ב 10 קטגוריות. התמונות מציגות פריטי לבוש בודדים ברזולוציה נמוכה (28 על 28 פיקסלים), כפי שניתן לראות כאן:

אופנה ספרייט MNIST
איור 1. דגימות אופנה-MNIST (על ידי Zalando, רישיון MIT).

אופנה MNIST מיועד לשמש נפתח ב תחליף עבור קלאסי MNIST במערך-קרובות משמש "שלום, עולם" של תוכניות לימוד מכונה עבור ראייה ממוחשבת. מערך הנתונים של MNIST מכיל תמונות של ספרות בכתב יד (0, 1, 2 וכו') בפורמט זהה לזה של פריטי הלבוש שבהם תשתמשו כאן.

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

כאן, 60,000 תמונות משמשות לאימון הרשת ו-10,000 תמונות כדי להעריך באיזו מידה הרשת למדה לסווג תמונות. אתה יכול לגשת ל- Fashion MNIST ישירות מ- TensorFlow. ייבוא לטעון את הנתונים אופנה MNIST ישירות TensorFlow:

fashion_mnist = tf.keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz
32768/29515 [=================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz
26427392/26421880 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz
8192/5148 [===============================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz
4423680/4422102 [==============================] - 0s 0us/step

טעינת מערך הנתונים מחזירה ארבעה מערכי NumPy:

  • train_images ו train_labels המערכים הם האימונים להגדיר נתוני -The שימושי המודל ללמוד.
  • המודל נבדק כנגד סט בדיקה, test_images , ו test_labels מערכים.

התמונות הן 28x28 מערכי numpy, עם ערכי פיקסל בטווח שבין 0 ל 255. תוויות מערך של מספרים שלמים, בטווח שבין 0 ל 9. אלה תואמים את המעמד של בגדי התמונה מייצגת:

תווית מעמד
0 חולצה/טופ
1 מכנסיים
2 תעצור בצד
3 שמלה
4 מעיל
5 סַנְדָל
6 חוּלצָה
7 נַעַל הִתעַמְלוּת
8 תיק
9 מגף קרסול

כל תמונה ממופה לתווית אחת. מאז שמות בכיתה אינם כלולים עם הנתונים, לאחסן אותם כאן להשתמש מאוחר יותר כאשר מתכננים את התמונות:

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

חקור את הנתונים

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

train_images.shape
(60000, 28, 28)

כמו כן, יש 60,000 תוויות בערכת ההדרכה:

len(train_labels)
60000

כל תווית היא מספר שלם בין 0 ל-9:

train_labels
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)

יש 10,000 תמונות בערכת הבדיקה. שוב, כל תמונה מיוצגת כ-28 x 28 פיקסלים:

test_images.shape
(10000, 28, 28)

וערכת הבדיקה מכילה 10,000 תוויות תמונות:

len(test_labels)
10000

עבד מראש את הנתונים

יש לעבד את הנתונים מראש לפני אימון הרשת. אם תבדוק את התמונה הראשונה בערכת האימונים, תראה שערכי הפיקסלים נופלים בטווח של 0 עד 255:

plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()

png

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

train_images = train_images / 255.0

test_images = test_images / 255.0

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

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)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

png

בנה את הדגם

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

הגדר את השכבות

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

רוב הלמידה העמוקה מורכבת משרשור שכבות פשוטות. רוב השכבות, כגון tf.keras.layers.Dense , יש פרמטרים, כי הם למדו במהלך אימון.

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10)
])

השכבה הראשונה ברשת זו, tf.keras.layers.Flatten , הופכת את הפורמט של תמונות מתוך מערך דו-מימדי (של 28 על ידי 28 פיקסלים) כדי מערך חד-ממדי (של 28 * 28 = 784 פיקסלים). חשבו על שכבה זו כעל ביטול הערימה של שורות של פיקסלים בתמונה וליישר אותם. לשכבה זו אין פרמטרים ללמוד; זה רק מפרמט מחדש את הנתונים.

לאחר פיקסלים משוטחים, הרשת מורכבת מרצף של שתי tf.keras.layers.Dense שכבות. אלו שכבות עצביות מחוברות בצפיפות, או מחוברות במלואן. הראשון Dense השכבה יש 128 צומת (או נוירונים). השכבה השנייה (והאחרונה) מחזירה מערך לוגיטים באורך 10. כל צומת מכיל ציון המציין שהתמונה הנוכחית שייכת לאחת מ-10 המחלקות.

הרכב את המודל

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

  • פונקציה הפסד -זהו אמצעים איך מדויק המודל הוא במהלך אימון. אתה רוצה למזער את הפונקציה הזו כדי "לנווט" את הדגם בכיוון הנכון.
  • ייעול -זהו איך המודל מתעדכן על בסיס נתון שהוא רואה ותפקוד ההפסד שלה.
  • מדדי -משומשות לפקח על האימונים וצעדים ובדיקה. הדוגמה הבאה משתמשת דיוק, את החלק היחסי של התמונות מסווגות בצורה נכונה.
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

לאמן את הדגם

אימון מודל הרשת העצבית דורש את השלבים הבאים:

  1. הזינו את נתוני האימון למודל. בדוגמא זו, נתון ההכשרה נמצאים train_images ו train_labels המערכים.
  2. המודל לומד לשייך תמונות ותוויות.
  3. אתה שואל את המודל לבצע תחזיות לגבי מבחן סט-בדוגמה זו, test_images מערך.
  4. ודא כי התחזיות להתאים את התוויות מן test_labels מערך.

האכילו את הדגם

כדי להתחיל אימונים, קורא model.fit שיטה הנקרא כך משום שהיא "מתאימה" המודל לנתוני אימונים:

model.fit(train_images, train_labels, epochs=10)
Epoch 1/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.4982 - accuracy: 0.8256
Epoch 2/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.3747 - accuracy: 0.8658
Epoch 3/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.3356 - accuracy: 0.8770
Epoch 4/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.3112 - accuracy: 0.8856
Epoch 5/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2941 - accuracy: 0.8915
Epoch 6/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2776 - accuracy: 0.8972
Epoch 7/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2678 - accuracy: 0.9000
Epoch 8/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2564 - accuracy: 0.9049
Epoch 9/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2467 - accuracy: 0.9083
Epoch 10/10
1875/1875 [==============================] - 3s 1ms/step - loss: 0.2399 - accuracy: 0.9103
<tensorflow.python.keras.callbacks.History at 0x7fe108a0c150>

כאשר הדגם מתאמן, מוצגים מדדי ההפסד והדיוק. מודל זה מגיע לדיוק של כ-0.91 (או 91%) בנתוני האימון.

הערכת דיוק

לאחר מכן, השווה את ביצועי המודל במערך הנתונים של הבדיקה:

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)
313/313 - 0s - loss: 0.3413 - accuracy: 0.8814

Test accuracy: 0.8813999891281128

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

לעשות תחזיות

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

probability_model = tf.keras.Sequential([model, 
                                         tf.keras.layers.Softmax()])
predictions = probability_model.predict(test_images)

כאן, המודל חזה את התווית עבור כל תמונה בערכת הבדיקות. בואו נסתכל על התחזית הראשונה:

predictions[0]
array([2.9212106e-07, 1.6208847e-10, 1.3363140e-08, 2.7341349e-09,
       5.5379962e-10, 4.5457238e-04, 4.2226111e-06, 4.4925120e-03,
       5.8868943e-07, 9.9504781e-01], dtype=float32)

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

np.argmax(predictions[0])
9

אז, הדגם הכי בטוח כי התמונה אינה אתחול קרסול, או class_names[9] . בחינת תווית הבדיקה מראה שסיווג זה נכון:

test_labels[0]
9

גרף את זה כדי להסתכל על הסט המלא של 10 תחזיות הכיתה.

def plot_image(i, predictions_array, true_label, img):
  true_label, img = true_label[i], img[i]
  plt.grid(False)
  plt.xticks([])
  plt.yticks([])

  plt.imshow(img, cmap=plt.cm.binary)

  predicted_label = np.argmax(predictions_array)
  if predicted_label == true_label:
    color = 'blue'
  else:
    color = 'red'

  plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                100*np.max(predictions_array),
                                class_names[true_label]),
                                color=color)

def plot_value_array(i, predictions_array, true_label):
  true_label = true_label[i]
  plt.grid(False)
  plt.xticks(range(10))
  plt.yticks([])
  thisplot = plt.bar(range(10), predictions_array, color="#777777")
  plt.ylim([0, 1])
  predicted_label = np.argmax(predictions_array)

  thisplot[predicted_label].set_color('red')
  thisplot[true_label].set_color('blue')

אמת את התחזיות

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

בואו נסתכל על התמונה ה-0, התחזיות ומערך החיזוי. תוויות חיזוי נכונות הן כחולות ותוויות חיזוי לא נכונות הן אדומות. המספר נותן את האחוז (מתוך 100) עבור התווית החזויה.

i = 0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i],  test_labels)
plt.show()

png

i = 12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i],  test_labels)
plt.show()

png

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

# Plot the first X test images, their predicted labels, and the true labels.
# Color correct predictions in blue and incorrect predictions in red.
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions[i], test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()

png

השתמש בדגם המיומן

לבסוף, השתמש במודל המאומן כדי ליצור תחזית לגבי תמונה בודדת.

# Grab an image from the test dataset.
img = test_images[1]

print(img.shape)
(28, 28)

tf.keras מודלים מותאמים לבצע תחזיות על תצווה, או אוסף, של דוגמא בבת אחת. בהתאם לכך, למרות שאתה משתמש בתמונה בודדת, עליך להוסיף אותה לרשימה:

# Add the image to a batch where it's the only member.
img = (np.expand_dims(img,0))

print(img.shape)
(1, 28, 28)

כעת חזה את התווית הנכונה עבור התמונה הזו:

predictions_single = probability_model.predict(img)

print(predictions_single)
[[8.8914348e-05 1.3264636e-13 9.9108773e-01 1.2658383e-10 8.1463791e-03
  1.6905785e-08 6.7695131e-04 2.7492119e-17 5.1699739e-10 7.1339325e-17]]
plot_value_array(1, predictions_single[0], test_labels)
_ = plt.xticks(range(10), class_names, rotation=45)
plt.show()

png

tf.keras.Model.predict מחזיר רשימה של הרשימה רשימות-אחד עבור כל תמונה אצווה של נתונים. קח את התחזיות עבור התמונה (היחידה) שלנו באצווה:

np.argmax(predictions_single[0])
2

והמודל חוזה תווית כצפוי.

# MIT License
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.