אימון מותאם אישית: הדרכה

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

מדריך זה משתמש בלמידת מכונה כדי לסווג את פרחי האירוס לפי מינים. הוא משתמש ב-TensorFlow כדי:

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

תכנות TensorFlow

מדריך זה משתמש במושגי TensorFlow ברמה גבוהה אלה:

  • השתמש בסביבת הפיתוח של TensorFlow המוגדרת כברירת מחדל,
  • ייבוא ​​נתונים עם ה- API של ערכות נתונים,
  • בנה מודלים ושכבות עם ה-Keras API של TensorFlow.

מדריך זה בנוי כמו תוכניות TensorFlow רבות:

  1. ייבא ונתח את מערך הנתונים.
  2. בחר את סוג הדגם.
  3. אימון הדגם.
  4. הערך את יעילות המודל.
  5. השתמש במודל המאומן כדי ליצור תחזיות.

תוכנית התקנה

הגדר יבוא

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

import os
import matplotlib.pyplot as plt
import tensorflow as tf
print("TensorFlow version: {}".format(tf.__version__))
print("Eager execution: {}".format(tf.executing_eagerly()))
TensorFlow version: 2.8.0-rc1
Eager execution: True

בעיית הסיווג של איריס

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

הסוג איריס כולל כ-300 מינים, אך התוכנית שלנו תסווג רק את השלושה הבאים:

  • איריס סטוסה
  • איריס וירג'יניקה
  • איריס ורסיקולור
גיאומטריית עלי הכותרת בהשוואה לשלושה מיני איריס: איריס setosa, איריס וירג'יניקה ואיריס versicolor
איור 1. Iris setosa (מאת Radomil , CC BY-SA 3.0), Iris versicolor , (על ידי Dlanglois , CC BY-SA 3.0), ו- Iris virginica (מאת Frank Mayfield , CC BY-SA 2.0).

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

ייבא ונתח את מערך ההדרכה

הורד את קובץ הנתונים והמר אותו למבנה שיכול לשמש את תוכנית Python זו.

הורד את מערך הנתונים

הורד את קובץ מערך הנתונים לאימון באמצעות הפונקציה tf.keras.utils.get_file . זה מחזיר את נתיב הקובץ של הקובץ שהורד:

train_dataset_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv"

train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url),
                                           origin=train_dataset_url)

print("Local copy of the dataset file: {}".format(train_dataset_fp))
Local copy of the dataset file: /home/kbuilder/.keras/datasets/iris_training.csv

בדוק את הנתונים

מערך נתונים זה, iris_training.csv , הוא קובץ טקסט רגיל המאחסן נתונים טבלאיים המעוצבים כערכים מופרדים בפסיקים (CSV). השתמש בפקודה head -n5 כדי להציץ בחמשת הערכים הראשונים:

head -n5 {train_dataset_fp}
120,4,setosa,versicolor,virginica
6.4,2.8,5.6,2.2,2
5.0,2.3,3.3,1.0,1
4.9,2.5,4.5,1.7,2
4.9,3.1,1.5,0.1,0

מתצוגה זו של מערך הנתונים, שימו לב לדברים הבאים:

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

בוא נכתוב את זה בקוד:

# column order in CSV file
column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']

feature_names = column_names[:-1]
label_name = column_names[-1]

print("Features: {}".format(feature_names))
print("Label: {}".format(label_name))
Features: ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
Label: species

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

  • 0 : איריס סטוסה
  • 1 : איריס ורסיקולור
  • 2 : איריס וירג'יניקה

למידע נוסף על תכונות ותוויות, עיין בסעיף ML Terminology של קורס התרסקות למידת מכונה .

class_names = ['Iris setosa', 'Iris versicolor', 'Iris virginica']

צור מערך tf.data.Dataset

ה-API של Dataset של TensorFlow מטפל במקרים נפוצים רבים של טעינת נתונים למודל. זהו API ברמה גבוהה לקריאת נתונים והפיכתם לטופס המשמש לאימון.

מכיוון שמערך הנתונים הוא קובץ טקסט בפורמט CSV, השתמש בפונקציה tf.data.experimental.make_csv_dataset כדי לנתח את הנתונים לפורמט מתאים. מכיוון שפונקציה זו מייצרת נתונים עבור מודלים לאימון, התנהגות ברירת המחדל היא לערבב את הנתונים ( shuffle=True, shuffle_buffer_size=10000 ), ולחזור על מערך הנתונים לנצח ( num_epochs=None ). אנחנו גם מגדירים את הפרמטר batch_size :

batch_size = 32

train_dataset = tf.data.experimental.make_csv_dataset(
    train_dataset_fp,
    batch_size,
    column_names=column_names,
    label_name=label_name,
    num_epochs=1)

הפונקציה make_csv_dataset מחזירה ערכת tf.data.Dataset . של זוגות (features, label) , כאשר features הן מילון: {'feature_name': value}

אובייקטים אלה של ערכת Dataset ניתנים לחזרה. בואו נסתכל על אצווה של תכונות:

features, labels = next(iter(train_dataset))

print(features)
OrderedDict([('sepal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([5. , 7.4, 6. , 7.2, 5.9, 5.8, 5. , 5. , 7.7, 5.7, 6.3, 5.8, 5. ,
       4.8, 6.6, 6.3, 5.4, 6.9, 4.8, 6.6, 5.8, 7.7, 6.7, 7.6, 5.5, 6.4,
       5.6, 6.4, 4.4, 4.5, 6.5, 6.3], dtype=float32)>), ('sepal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([3.5, 2.8, 2.7, 3.2, 3. , 2.6, 2. , 3.4, 3. , 2.8, 2.3, 2.7, 3.6,
       3.1, 2.9, 3.3, 3. , 3.1, 3. , 3. , 4. , 2.6, 3. , 3. , 2.4, 2.7,
       2.7, 2.8, 3. , 2.3, 2.8, 2.5], dtype=float32)>), ('petal_length', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([1.6, 6.1, 5.1, 6. , 5.1, 4. , 3.5, 1.6, 6.1, 4.5, 4.4, 5.1, 1.4,
       1.6, 4.6, 4.7, 4.5, 5.1, 1.4, 4.4, 1.2, 6.9, 5. , 6.6, 3.7, 5.3,
       4.2, 5.6, 1.3, 1.3, 4.6, 5. ], dtype=float32)>), ('petal_width', <tf.Tensor: shape=(32,), dtype=float32, numpy=
array([0.6, 1.9, 1.6, 1.8, 1.8, 1.2, 1. , 0.4, 2.3, 1.3, 1.3, 1.9, 0.2,
       0.2, 1.3, 1.6, 1.5, 2.3, 0.3, 1.4, 0.2, 2.3, 1.7, 2.1, 1. , 1.9,
       1.3, 2.1, 0.2, 0.3, 1.5, 1.9], dtype=float32)>)])

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

אתה יכול להתחיל לראות כמה אשכולות על ידי שרטוט של כמה תכונות מהאצווה:

plt.scatter(features['petal_length'],
            features['sepal_length'],
            c=labels,
            cmap='viridis')

plt.xlabel("Petal length")
plt.ylabel("Sepal length")
plt.show()

png

כדי לפשט את שלב בניית המודל, צור פונקציה לאריזה מחדש של מילון התכונות למערך יחיד עם צורה: (batch_size, num_features) .

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

def pack_features_vector(features, labels):
  """Pack the features into a single array."""
  features = tf.stack(list(features.values()), axis=1)
  return features, labels

לאחר מכן השתמש בשיטת tf.data.Dataset#map כדי לארוז את features של כל זוג (features,label) במערך ההדרכה:

train_dataset = train_dataset.map(pack_features_vector)

רכיב התכונות של ערכת הנתונים הם כעת מערכים עם צורה ( Dataset (batch_size, num_features) . בואו נסתכל על הדוגמאות הראשונות:

features, labels = next(iter(train_dataset))

print(features[:5])
tf.Tensor(
[[4.9 3.  1.4 0.2]
 [6.1 3.  4.9 1.8]
 [6.1 2.6 5.6 1.4]
 [6.9 3.2 5.7 2.3]
 [6.7 3.1 4.4 1.4]], shape=(5, 4), dtype=float32)

בחר את סוג הדגם

למה לדגמן?

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

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

בחר את הדגם

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

תרשים של ארכיטקטורת הרשת: כניסות, 2 שכבות נסתרות ויציאות
איור 2. רשת עצבית עם תכונות, שכבות נסתרות ותחזיות.

כאשר המודל מאיור 2 מאומן ומוזן בדוגמה ללא תווית, הוא מניב שלוש תחזיות: הסבירות שהפרח הזה הוא מין האירוס הנתון. תחזית זו נקראת הסקה . עבור דוגמה זו, סכום תחזיות הפלט הוא 1.0. באיור 2, חיזוי זה מתחלק ל: 0.02 עבור Iris setosa , 0.95 עבור Iris versicolor ו 0.03 עבור Iris virginica . המשמעות היא שהמודל חוזה - בהסתברות של 95% - שפרח לדוגמה ללא תווית הוא איריס ורסיקולור .

צור מודל באמצעות Keras

ה-API של TensorFlow tf.keras הוא הדרך המועדפת ליצירת מודלים ושכבות. זה מקל על בניית מודלים וניסויים בעוד ש-Keras מטפל במורכבות של חיבור הכל יחד.

המודל tf.keras.Sequential הוא ערימה לינארית של שכבות. הבנאי שלו לוקח רשימה של מופעי שכבות, במקרה זה, שתי שכבות tf.keras.layers.Dense עם 10 צמתים כל אחד, ושכבת פלט עם 3 צמתים המייצגים את תחזיות התווית שלנו. הפרמטר input_shape של השכבה הראשונה מתאים למספר התכונות ממערך הנתונים, והוא נדרש:

model = tf.keras.Sequential([
  tf.keras.layers.Dense(10, activation=tf.nn.relu, input_shape=(4,)),  # input shape required
  tf.keras.layers.Dense(10, activation=tf.nn.relu),
  tf.keras.layers.Dense(3)
])

פונקציית ההפעלה קובעת את צורת הפלט של כל צומת בשכבה. האי-לינאריות הללו חשובות - בלעדיהם המודל יהיה שווה ערך לשכבה אחת. ישנן tf.keras.activations רבות, אך ReLU נפוץ עבור שכבות נסתרות.

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

שימוש בדגם

בואו נסתכל במהירות מה הדגם הזה עושה לקבוצת תכונות:

predictions = model(features)
predictions[:5]
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[-4.0874639e+00,  1.5199981e-03, -9.9991310e-01],
       [-5.3246369e+00, -1.8366380e-01, -1.3161827e+00],
       [-5.1154275e+00, -2.8129923e-01, -1.3305402e+00],
       [-6.0694785e+00, -2.1251860e-01, -1.5091233e+00],
       [-5.6730523e+00, -1.4321266e-01, -1.4437559e+00]], dtype=float32)>

כאן, כל דוגמה מחזירה לוגיט עבור כל מחלקה.

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

tf.nn.softmax(predictions[:5])
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[0.01210616, 0.7224865 , 0.26540732],
       [0.00440638, 0.75297093, 0.24262273],
       [0.00585618, 0.7362918 , 0.25785193],
       [0.00224076, 0.7835035 , 0.21425581],
       [0.00310779, 0.7834839 , 0.21340834]], dtype=float32)>

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

print("Prediction: {}".format(tf.argmax(predictions, axis=1)))
print("    Labels: {}".format(labels))
Prediction: [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
    Labels: [0 2 2 2 1 1 0 1 1 2 2 1 0 2 2 2 1 0 2 2 1 0 2 1 2 0 1 1 2 2 1 2]

אימון הדגם

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

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

הגדר את פונקציית האובדן והשיפוע

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

המודל שלנו יחשב את ההפסד שלו באמצעות הפונקציה tf.keras.losses.SparseCategoricalCrossentropy אשר לוקחת את תחזיות ההסתברות של המודל ואת התווית הרצויה, ומחזירה את ההפסד הממוצע על פני הדוגמאות.

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
def loss(model, x, y, training):
  # training=training is needed only if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  y_ = model(x, training=training)

  return loss_object(y_true=y, y_pred=y_)


l = loss(model, features, labels, training=False)
print("Loss test: {}".format(l))
Loss test: 1.6059828996658325

השתמש בהקשר tf.GradientTape כדי לחשב את ההדרגות המשמשות למיטוב המודל שלך:

def grad(model, inputs, targets):
  with tf.GradientTape() as tape:
    loss_value = loss(model, inputs, targets, training=True)
  return loss_value, tape.gradient(loss_value, model.trainable_variables)

צור מייעל

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

אלגוריתמי אופטימיזציה המוצגים לאורך זמן בחלל תלת מימד.
איור 3. אלגוריתמי אופטימיזציה המוצגים לאורך זמן בחלל תלת מימדי.
(מקור: Stanford class CS231n , רישיון MIT, קרדיט תמונה: Alec Radford )

ל- TensorFlow יש אלגוריתמי אופטימיזציה רבים הזמינים לאימון. מודל זה משתמש ב- tf.keras.optimizers.SGD המיישם את אלגוריתם הירידה הסטוכסטית (SGD). קצב learning_rate מגדיר את גודל הצעד שיש לבצע עבור כל איטרציה במורד הגבעה. זהו היפרפרמטר שבדרך כלל תתאים כדי להשיג תוצאות טובות יותר.

בואו נגדיר את האופטימיזציה:

optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)

נשתמש בזה כדי לחשב שלב אופטימיזציה בודד:

loss_value, grads = grad(model, features, labels)

print("Step: {}, Initial Loss: {}".format(optimizer.iterations.numpy(),
                                          loss_value.numpy()))

optimizer.apply_gradients(zip(grads, model.trainable_variables))

print("Step: {},         Loss: {}".format(optimizer.iterations.numpy(),
                                          loss(model, features, labels, training=True).numpy()))
Step: 0, Initial Loss: 1.6059828996658325
Step: 1,         Loss: 1.3759253025054932

לולאת אימון

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

  1. חזור על כל תקופה . עידן הוא מעבר אחד במערך הנתונים.
  2. בתוך תקופה, חזרו על כל דוגמה בערכת הנתונים האימון Dataset את התכונות שלו ( x ) והתווית ( y ).
  3. השתמש בתכונות של הדוגמה, בצע חיזוי והשווה אותו עם התווית. מדוד את חוסר הדיוק של החיזוי והשתמש בזה כדי לחשב את האובדן והשיפועים של המודל.
  4. השתמש בכלי optimizer כדי לעדכן את משתני המודל.
  5. עקוב אחר כמה נתונים סטטיסטיים להדמיה.
  6. חזור על כל תקופה.

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

## Note: Rerunning this cell uses the same model variables

# Keep results for plotting
train_loss_results = []
train_accuracy_results = []

num_epochs = 201

for epoch in range(num_epochs):
  epoch_loss_avg = tf.keras.metrics.Mean()
  epoch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()

  # Training loop - using batches of 32
  for x, y in train_dataset:
    # Optimize the model
    loss_value, grads = grad(model, x, y)
    optimizer.apply_gradients(zip(grads, model.trainable_variables))

    # Track progress
    epoch_loss_avg.update_state(loss_value)  # Add current batch loss
    # Compare predicted label to actual label
    # training=True is needed only if there are layers with different
    # behavior during training versus inference (e.g. Dropout).
    epoch_accuracy.update_state(y, model(x, training=True))

  # End epoch
  train_loss_results.append(epoch_loss_avg.result())
  train_accuracy_results.append(epoch_accuracy.result())

  if epoch % 50 == 0:
    print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch,
                                                                epoch_loss_avg.result(),
                                                                epoch_accuracy.result()))
Epoch 000: Loss: 1.766, Accuracy: 43.333%
Epoch 050: Loss: 0.579, Accuracy: 71.667%
Epoch 100: Loss: 0.398, Accuracy: 82.500%
Epoch 150: Loss: 0.307, Accuracy: 92.500%
Epoch 200: Loss: 0.224, Accuracy: 95.833%

דמיינו את פונקציית האובדן לאורך זמן

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

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

fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))
fig.suptitle('Training Metrics')

axes[0].set_ylabel("Loss", fontsize=14)
axes[0].plot(train_loss_results)

axes[1].set_ylabel("Accuracy", fontsize=14)
axes[1].set_xlabel("Epoch", fontsize=14)
axes[1].plot(train_accuracy_results)
plt.show()

png

הערך את יעילות המודל

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

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

תכונות לדוגמה תווית חיזוי מודל
5.9 3.0 4.3 1.5 1 1
6.9 3.1 5.4 2.1 2 2
5.1 3.3 1.7 0.5 0 0
6.0 3.4 4.5 1.6 1 2
5.5 2.5 4.0 1.3 1 1
איור 4. מסווג קשתית המדויק ב-80%.

הגדר את מערך הנתונים של הבדיקה

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

ההגדרה של Dataset של הבדיקה דומה להגדרה של Dataset אימון. הורד את קובץ הטקסט של ה-CSV ונתח את הערכים האלה, ואז תערב אותו קצת:

test_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv"

test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url),
                                  origin=test_url)
test_dataset = tf.data.experimental.make_csv_dataset(
    test_fp,
    batch_size,
    column_names=column_names,
    label_name='species',
    num_epochs=1,
    shuffle=False)

test_dataset = test_dataset.map(pack_features_vector)

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

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

test_accuracy = tf.keras.metrics.Accuracy()

for (x, y) in test_dataset:
  # training=False is needed only if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  logits = model(x, training=False)
  prediction = tf.argmax(logits, axis=1, output_type=tf.int32)
  test_accuracy(prediction, y)

print("Test set accuracy: {:.3%}".format(test_accuracy.result()))
Test set accuracy: 96.667%

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

tf.stack([y,prediction],axis=1)
<tf.Tensor: shape=(30, 2), dtype=int32, numpy=
array([[1, 1],
       [2, 2],
       [0, 0],
       [1, 1],
       [1, 1],
       [1, 1],
       [0, 0],
       [2, 2],
       [1, 1],
       [2, 2],
       [2, 2],
       [0, 0],
       [2, 2],
       [1, 1],
       [1, 1],
       [0, 0],
       [1, 1],
       [0, 0],
       [0, 0],
       [2, 2],
       [0, 0],
       [1, 1],
       [2, 2],
       [1, 2],
       [1, 1],
       [1, 1],
       [0, 0],
       [1, 1],
       [2, 2],
       [1, 1]], dtype=int32)>

השתמש במודל המאומן כדי ליצור תחזיות

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

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

  • 0 : איריס סטוסה
  • 1 : איריס ורסיקולור
  • 2 : איריס וירג'יניקה
predict_dataset = tf.convert_to_tensor([
    [5.1, 3.3, 1.7, 0.5,],
    [5.9, 3.0, 4.2, 1.5,],
    [6.9, 3.1, 5.4, 2.1]
])

# training=False is needed only if there are layers with different
# behavior during training versus inference (e.g. Dropout).
predictions = model(predict_dataset, training=False)

for i, logits in enumerate(predictions):
  class_idx = tf.argmax(logits).numpy()
  p = tf.nn.softmax(logits)[class_idx]
  name = class_names[class_idx]
  print("Example {} prediction: {} ({:4.1f}%)".format(i, name, 100*p))
Example 0 prediction: Iris setosa (97.6%)
Example 1 prediction: Iris versicolor (82.0%)
Example 2 prediction: Iris virginica (56.4%)