השב / י לאירוע TensorFlow Everywhere המקומי שלך היום!
דף זה תורגם על ידי Cloud Translation API.
Switch to English

הדרכה והערכה בשיטות המובנות

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

להכין

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

מבוא

מדריך זה מכסה הדרכה, הערכה וחיזוי (הסקת מסקנות) בעת שימוש בממשקי API מובנים לאימון ואימות (כגון model.fit() , model.evaluate() , model.predict() ).

אם אתה מעוניין למנף fit() תוך ציון פונקציית שלב האימון שלך, עיין במדריך "התאמה אישית של מה שקורה fit() " .

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

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

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

סקירת API: דוגמה ראשונה מקצה לקצה

כאשר מעבירים נתונים ללולאות האימון המובנות של מודל, עליכם להשתמש במערכי NumPy (אם הנתונים שלכם קטנים tf.data Dataset בזיכרון) או tf.data Dataset . בפסקאות הבאות נשתמש במערך הנתונים MNIST כמערכי NumPy על מנת להדגים כיצד להשתמש במיטוב, הפסדים ומדדים.

בואו ניקח בחשבון את המודל הבא (כאן נבנה עם ה- API הפונקציונלי, אבל זה יכול להיות גם מודל רציף או מודל מסווג משנה):

inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, activation="softmax", name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)

הנה איך נראית זרימת העבודה האופיינית מקצה לקצה, המורכבת מ:

  • הַדְרָכָה
  • אימות על קבוצת עצירה שנוצרה מנתוני האימון המקוריים
  • הערכה על נתוני הבדיקה

אנו נשתמש בנתוני MNIST לדוגמא זו.

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

# Preprocess the data (these are NumPy arrays)
x_train = x_train.reshape(60000, 784).astype("float32") / 255
x_test = x_test.reshape(10000, 784).astype("float32") / 255

y_train = y_train.astype("float32")
y_test = y_test.astype("float32")

# Reserve 10,000 samples for validation
x_val = x_train[-10000:]
y_val = y_train[-10000:]
x_train = x_train[:-10000]
y_train = y_train[:-10000]

אנו מציינים את תצורת האימון (אופטימיזציה, אובדן, מדדים):

model.compile(
    optimizer=keras.optimizers.RMSprop(),  # Optimizer
    # Loss function to minimize
    loss=keras.losses.SparseCategoricalCrossentropy(),
    # List of metrics to monitor
    metrics=[keras.metrics.SparseCategoricalAccuracy()],
)

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

print("Fit model on training data")
history = model.fit(
    x_train,
    y_train,
    batch_size=64,
    epochs=2,
    # We pass some validation for
    # monitoring validation loss and metrics
    # at the end of each epoch
    validation_data=(x_val, y_val),
)
Fit model on training data
Epoch 1/2
782/782 [==============================] - 3s 3ms/step - loss: 0.5821 - sparse_categorical_accuracy: 0.8361 - val_loss: 0.1893 - val_sparse_categorical_accuracy: 0.9483
Epoch 2/2
782/782 [==============================] - 2s 3ms/step - loss: 0.1676 - sparse_categorical_accuracy: 0.9500 - val_loss: 0.1631 - val_sparse_categorical_accuracy: 0.9488

האובייקט "היסטוריה" שהוחזר מחזיק בתיעוד של ערכי האובדן וערכי המדד במהלך האימון:

history.history
{'loss': [0.344687819480896, 0.15941613912582397],
 'sparse_categorical_accuracy': [0.9019200205802917, 0.9523000121116638],
 'val_loss': [0.1892719268798828, 0.1630939543247223],
 'val_sparse_categorical_accuracy': [0.9483000040054321, 0.9488000273704529]}

אנו מעריכים את המודל על נתוני הבדיקה באמצעות evaluate() :

# Evaluate the model on the test data using `evaluate`
print("Evaluate on test data")
results = model.evaluate(x_test, y_test, batch_size=128)
print("test loss, test acc:", results)

# Generate predictions (probabilities -- the output of the last layer)
# on new data using `predict`
print("Generate predictions for 3 samples")
predictions = model.predict(x_test[:3])
print("predictions shape:", predictions.shape)
Evaluate on test data
79/79 [==============================] - 0s 2ms/step - loss: 0.1750 - sparse_categorical_accuracy: 0.9460
test loss, test acc: [0.17500483989715576, 0.9459999799728394]
Generate predictions for 3 samples
predictions shape: (3, 10)

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

שיטת compile() : ציון הפסד, מדדים ומייעל

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

אתה מעביר את אלה למודל כטיעונים לשיטת compile() :

model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[keras.metrics.SparseCategoricalAccuracy()],
)

ארגומנט metrics צריך להיות רשימה - המודל שלך יכול לכלול מספר מדדים כלשהו.

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

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

model.compile(
    optimizer="rmsprop",
    loss="sparse_categorical_crossentropy",
    metrics=["sparse_categorical_accuracy"],
)

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

def get_uncompiled_model():
    inputs = keras.Input(shape=(784,), name="digits")
    x = layers.Dense(64, activation="relu", name="dense_1")(inputs)
    x = layers.Dense(64, activation="relu", name="dense_2")(x)
    outputs = layers.Dense(10, activation="softmax", name="predictions")(x)
    model = keras.Model(inputs=inputs, outputs=outputs)
    return model


def get_compiled_model():
    model = get_uncompiled_model()
    model.compile(
        optimizer="rmsprop",
        loss="sparse_categorical_crossentropy",
        metrics=["sparse_categorical_accuracy"],
    )
    return model

קיימים אופטימיזציה מובנית, הפסדים ומדדים מובנים

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

אופטימיזציה:

  • SGD() (עם או בלי מומנטום)
  • RMSprop()
  • Adam()
  • וכו '

אֲבֵדוֹת:

  • MeanSquaredError()
  • KLDivergence()
  • CosineSimilarity()
  • וכו '

מדדים:

  • AUC()
  • Precision()
  • Recall()
  • וכו '

הפסדים בהתאמה אישית

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

def custom_mean_squared_error(y_true, y_pred):
    return tf.math.reduce_mean(tf.square(y_true - y_pred))


model = get_uncompiled_model()
model.compile(optimizer=keras.optimizers.Adam(), loss=custom_mean_squared_error)

# We need to one-hot encode the labels to use MSE
y_train_one_hot = tf.one_hot(y_train, depth=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)
782/782 [==============================] - 2s 2ms/step - loss: 0.0265

<tensorflow.python.keras.callbacks.History at 0x7fb27c7a6cf8>

אם אתה זקוק לפונקציית הפסד שמקבלת פרמטרים לצד y_true ו- y_pred , אתה יכול tf.keras.losses.Loss את מחלקה tf.keras.losses.Loss וליישם את שתי השיטות הבאות:

  • __init__(self) : קבל פרמטרים שיעברו במהלך השיחה של פונקציית האובדן שלך
  • call(self, y_true, y_pred) : השתמש ביעדים (y_true) ובחיזוי המודל (y_pred) כדי לחשב את אובדן המודל

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

כך תעשה זאת:

class CustomMSE(keras.losses.Loss):
    def __init__(self, regularization_factor=0.1, name="custom_mse"):
        super().__init__(name=name)
        self.regularization_factor = regularization_factor

    def call(self, y_true, y_pred):
        mse = tf.math.reduce_mean(tf.square(y_true - y_pred))
        reg = tf.math.reduce_mean(tf.square(0.5 - y_pred))
        return mse + reg * self.regularization_factor


model = get_uncompiled_model()
model.compile(optimizer=keras.optimizers.Adam(), loss=CustomMSE())

y_train_one_hot = tf.one_hot(y_train, depth=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)
782/782 [==============================] - 2s 2ms/step - loss: 0.0485

<tensorflow.python.keras.callbacks.History at 0x7fb27c64d438>

מדדים מותאמים אישית

אם אתה זקוק למדד שאינו חלק tf.keras.metrics.Metric ה- API, תוכל ליצור ערכים מותאמים אישית בקלות על ידי tf.keras.metrics.Metric משנה של המחלקה tf.keras.metrics.Metric . יהיה עליך ליישם 4 שיטות:

  • __init__(self) , בו תיצרו משתני מצב למדד שלכם.
  • update_state(self, y_true, y_pred, sample_weight=None) , המשתמש במטרות y_true ובחיזוי המודל y_pred לעדכון משתני המצב.
  • result(self) , המשתמשת במשתני המצב לחישוב התוצאות הסופיות.
  • reset_states(self) , reset_states(self) מחדש את מצב המדד.

עדכון המדינה וחישוב התוצאות נשמרים בנפרד (בהתאמה update_state() result() , בהתאמה) מכיוון שבמקרים מסוימים, חישוב התוצאות עשוי להיות יקר מאוד update_state() רק מעת לעת.

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

class CategoricalTruePositives(keras.metrics.Metric):
    def __init__(self, name="categorical_true_positives", **kwargs):
        super(CategoricalTruePositives, self).__init__(name=name, **kwargs)
        self.true_positives = self.add_weight(name="ctp", initializer="zeros")

    def update_state(self, y_true, y_pred, sample_weight=None):
        y_pred = tf.reshape(tf.argmax(y_pred, axis=1), shape=(-1, 1))
        values = tf.cast(y_true, "int32") == tf.cast(y_pred, "int32")
        values = tf.cast(values, "float32")
        if sample_weight is not None:
            sample_weight = tf.cast(sample_weight, "float32")
            values = tf.multiply(values, sample_weight)
        self.true_positives.assign_add(tf.reduce_sum(values))

    def result(self):
        return self.true_positives

    def reset_states(self):
        # The state of the metric will be reset at the start of each epoch.
        self.true_positives.assign(0.0)


model = get_uncompiled_model()
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[CategoricalTruePositives()],
)
model.fit(x_train, y_train, batch_size=64, epochs=3)
Epoch 1/3
782/782 [==============================] - 3s 2ms/step - loss: 0.5801 - categorical_true_positives: 22009.8493
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1717 - categorical_true_positives: 23861.7190
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1200 - categorical_true_positives: 24233.9246

<tensorflow.python.keras.callbacks.History at 0x7fb27c56f2e8>

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

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

במקרים כאלה, אתה יכול להתקשר אל self.add_loss(loss_value) מתוך שיטת השיחה של שכבה מותאמת אישית. הפסדים שנוספו בצורה זו מתווספים לאובדן "העיקרי" במהלך האימון (זה שעבר compile() ). הנה דוגמה פשוטה שמוסיפה הרגולציה של הפעילות (שימו לב כי ויסות הפעילות מובנה בכל שכבות Keras - שכבה זו נועדה רק לצורך מתן דוגמה קונקרטית):

class ActivityRegularizationLayer(layers.Layer):
    def call(self, inputs):
        self.add_loss(tf.reduce_sum(inputs) * 0.1)
        return inputs  # Pass-through layer.


inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)

# Insert activity regularization as a layer
x = ActivityRegularizationLayer()(x)

x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)

# The displayed loss will be much higher than before
# due to the regularization component.
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 2s 2ms/step - loss: 3.2794

<tensorflow.python.keras.callbacks.History at 0x7fb27c4ea3c8>

אתה יכול לעשות את אותו הדבר לרישום ערכי מדדים, באמצעות add_metric() :

class MetricLoggingLayer(layers.Layer):
    def call(self, inputs):
        # The `aggregation` argument defines
        # how to aggregate the per-batch values
        # over each epoch:
        # in this case we simply average them.
        self.add_metric(
            keras.backend.std(inputs), name="std_of_activation", aggregation="mean"
        )
        return inputs  # Pass-through layer.


inputs = keras.Input(shape=(784,), name="digits")
x = layers.Dense(64, activation="relu", name="dense_1")(inputs)

# Insert std logging as a layer.
x = MetricLoggingLayer()(x)

x = layers.Dense(64, activation="relu", name="dense_2")(x)
outputs = layers.Dense(10, name="predictions")(x)

model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 2s 2ms/step - loss: 0.5627 - std_of_activation: 0.9609

<tensorflow.python.keras.callbacks.History at 0x7fb27c39e320>

בממשק ה- API הפונקציונלי , ניתן להתקשר גם model.add_loss(loss_tensor) או model.add_metric(metric_tensor, name, aggregation) .

הנה דוגמה פשוטה:

inputs = keras.Input(shape=(784,), name="digits")
x1 = layers.Dense(64, activation="relu", name="dense_1")(inputs)
x2 = layers.Dense(64, activation="relu", name="dense_2")(x1)
outputs = layers.Dense(10, name="predictions")(x2)
model = keras.Model(inputs=inputs, outputs=outputs)

model.add_loss(tf.reduce_sum(x1) * 0.1)

model.add_metric(keras.backend.std(x1), name="std_of_activation", aggregation="mean")

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
)
model.fit(x_train, y_train, batch_size=64, epochs=1)
782/782 [==============================] - 2s 2ms/step - loss: 3.6785 - std_of_activation: 0.0020

<tensorflow.python.keras.callbacks.History at 0x7fb27c2b4860>

שים לב שכאשר אתה מעביר הפסדים באמצעות add_loss() , יתאפשר להתקשר compile() ללא פונקציית הפסד, מכיוון add_loss() כבר יש הפסד למזער.

שקול את שכבת LogisticEndpoint הבאה: היא נדרשת כיעדי קלט וכניסה, והיא עוקבת אחר אובדן add_loss() באמצעות add_loss() . זה גם עוקב אחר דיוק הסיווג באמצעות add_metric() .

class LogisticEndpoint(keras.layers.Layer):
    def __init__(self, name=None):
        super(LogisticEndpoint, self).__init__(name=name)
        self.loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)
        self.accuracy_fn = keras.metrics.BinaryAccuracy()

    def call(self, targets, logits, sample_weights=None):
        # Compute the training-time loss value and add it
        # to the layer using `self.add_loss()`.
        loss = self.loss_fn(targets, logits, sample_weights)
        self.add_loss(loss)

        # Log accuracy as a metric and add it
        # to the layer using `self.add_metric()`.
        acc = self.accuracy_fn(targets, logits, sample_weights)
        self.add_metric(acc, name="accuracy")

        # Return the inference-time prediction tensor (for `.predict()`).
        return tf.nn.softmax(logits)

אתה יכול להשתמש בו במודל עם שתי תשומות (נתוני קלט ויעדים), שהורכבו ללא טיעון loss , כך:

import numpy as np

inputs = keras.Input(shape=(3,), name="inputs")
targets = keras.Input(shape=(10,), name="targets")
logits = keras.layers.Dense(10)(inputs)
predictions = LogisticEndpoint(name="predictions")(logits, targets)

model = keras.Model(inputs=[inputs, targets], outputs=predictions)
model.compile(optimizer="adam")  # No loss argument!

data = {
    "inputs": np.random.random((3, 3)),
    "targets": np.random.random((3, 10)),
}
model.fit(data)
1/1 [==============================] - 0s 260ms/step - loss: 1.0546 - binary_accuracy: 0.0000e+00

<tensorflow.python.keras.callbacks.History at 0x7fb27c09cc88>

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

מגדירה באופן אוטומטי ערכת השהיית אימות

בדוגמה הראשונה מקצה לקצה שראית, השתמשנו בארגומנט validation_data כדי להעביר כפל של מערכי (x_val, y_val) למודל להערכת מדדי איבוד אימות ואימות בסוף כל תקופה.

הנה אפשרות נוספת: הארגומנט validation_split מאפשר לך לשמור אוטומטית חלק מנתוני האימון שלך לאימות. ערך הארגומנט מייצג את חלקי הנתונים שיש לשמור לאימות, ולכן יש להגדיר אותו למספר הגבוה מ- 0 ונמוך מ- 1. לדוגמה, validation_split=0.2 פירושו "השתמש ב- 20% מהנתונים לצורך אימות", ו validation_split=0.6 פירושו "השתמש ב- 60% מהנתונים לצורך אימות".

אופן חישוב האימות הוא על ידי לקיחת דגימות ה- x% האחרונות של המערכים שקיבלו שיחת ההתאמה, לפני כל דשדוש.

שים לב שאתה יכול להשתמש ב- validation_split רק בעת אימון עם נתוני NumPy.

model = get_compiled_model()
model.fit(x_train, y_train, batch_size=64, validation_split=0.2, epochs=1)
625/625 [==============================] - 2s 3ms/step - loss: 0.6332 - sparse_categorical_accuracy: 0.8232 - val_loss: 0.2352 - val_sparse_categorical_accuracy: 0.9284

<tensorflow.python.keras.callbacks.History at 0x7fb27014f0f0>

הדרכה והערכה ממערכי הנתונים tf.data

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

בואו נסתכל על המקרה בו הנתונים שלכם מגיעים בצורה של אובייקטtf.data.Dataset .

ממשק ה- API של tf.data הוא קבוצה של כלי עזר ב- TensorFlow 2.0 לטעינת ועיבוד נתונים מראש בצורה מהירה וניתנת להרחבה.

לקבלת מדריך מלא אודות יצירת Datasets , עיין בתיעוד tf.data .

באפשרותך להעביר מופע של Dataset ישירות לשיטות fit() , evaluate() predict() :

model = get_compiled_model()

# First, let's create a training Dataset instance.
# For the sake of our example, we'll use the same MNIST data as before.
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
# Shuffle and slice the dataset.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Now we get a test dataset.
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_dataset = test_dataset.batch(64)

# Since the dataset already takes care of batching,
# we don't pass a `batch_size` argument.
model.fit(train_dataset, epochs=3)

# You can also evaluate or predict on a dataset.
print("Evaluate")
result = model.evaluate(test_dataset)
dict(zip(model.metrics_names, result))
Epoch 1/3
782/782 [==============================] - 2s 3ms/step - loss: 0.5405 - sparse_categorical_accuracy: 0.8524
Epoch 2/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1624 - sparse_categorical_accuracy: 0.9517
Epoch 3/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1150 - sparse_categorical_accuracy: 0.9660
Evaluate
157/157 [==============================] - 0s 2ms/step - loss: 0.1337 - sparse_categorical_accuracy: 0.9583

{'loss': 0.13374954462051392, 'sparse_categorical_accuracy': 0.958299994468689}

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

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

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

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Only use the 100 batches per epoch (that's 64 * 100 samples)
model.fit(train_dataset, epochs=3, steps_per_epoch=100)
Epoch 1/3
100/100 [==============================] - 1s 3ms/step - loss: 1.2317 - sparse_categorical_accuracy: 0.6776
Epoch 2/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3834 - sparse_categorical_accuracy: 0.8949
Epoch 3/3
100/100 [==============================] - 0s 3ms/step - loss: 0.3568 - sparse_categorical_accuracy: 0.8912

<tensorflow.python.keras.callbacks.History at 0x7fb21c3b7320>

שימוש במערך אימות

באפשרותך להעביר מופע של Dataset כארגומנט validation_data fit() :

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Prepare the validation dataset
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)

model.fit(train_dataset, epochs=1, validation_data=val_dataset)
782/782 [==============================] - 3s 3ms/step - loss: 0.5587 - sparse_categorical_accuracy: 0.8436 - val_loss: 0.1735 - val_sparse_categorical_accuracy: 0.9517

<tensorflow.python.keras.callbacks.History at 0x7fb21c19c7b8>

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

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

model = get_compiled_model()

# Prepare the training dataset
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

# Prepare the validation dataset
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)

model.fit(
    train_dataset,
    epochs=1,
    # Only run validation using the first 10 batches of the dataset
    # using the `validation_steps` argument
    validation_data=val_dataset,
    validation_steps=10,
)
782/782 [==============================] - 3s 3ms/step - loss: 0.5708 - sparse_categorical_accuracy: 0.8453 - val_loss: 0.2911 - val_sparse_categorical_accuracy: 0.9312

<tensorflow.python.keras.callbacks.History at 0x7fb21c31ff98>

שים לב כי מערך האימות יאופס לאחר כל שימוש (כך שתמיד תערוך הערכה על אותן דגימות מתקופה לתקופה).

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

תבניות קלט אחרות נתמכות

מלבד מערכי NumPy, טנזורים להוטים ומערכי Datasets TensorFlow, ניתן להכשיר מודל Keras באמצעות מסגרות נתונים של Pandas, או ממחוללי Python המניבים קבוצות של נתונים ותוויות.

בפרט, מחלקת keras.utils.Sequence מציעה ממשק פשוט לבניית מחוללי נתונים של פייתון שהם מודעים keras.utils.Sequence .

באופן כללי, אנו ממליצים להשתמש:

  • נתוני קלט NumPy אם הנתונים שלך קטנים ומשתלבים בזיכרון
  • אובייקטים של Dataset אם יש לך מערכי נתונים גדולים ואתה צריך לבצע הכשרה מבוזרת
  • אובייקטי Sequence אם יש לך מערכי נתונים גדולים ואתה צריך לעשות הרבה עיבוד מותאם אישית בצד ה- Python שלא ניתן לעשות זאת ב- TensorFlow (למשל אם אתה מסתמך על ספריות חיצוניות לצורך טעינת נתונים או עיבוד מקדים).

שימוש באובייקט keras.utils.Sequence כקלט

keras.utils.Sequence הוא כלי עזר שתוכל keras.utils.Sequence אותו בכדי להשיג מחולל פייתון עם שני מאפיינים חשובים:

  • זה עובד טוב עם ריבוי עיבודים.
  • ניתן לערבב (למשל כאשר מעבירים shuffle=True fit() ).

Sequence חייב ליישם שתי שיטות:

  • __getitem__
  • __len__

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

הנה דוגמה מהירה:

from skimage.io import imread
from skimage.transform import resize
import numpy as np

# Here, `filenames` is list of path to the images
# and `labels` are the associated labels.

class CIFAR10Sequence(Sequence):
    def __init__(self, filenames, labels, batch_size):
        self.filenames, self.labels = filenames, labels
        self.batch_size = batch_size

    def __len__(self):
        return int(np.ceil(len(self.filenames) / float(self.batch_size)))

    def __getitem__(self, idx):
        batch_x = self.filenames[idx * self.batch_size:(idx + 1) * self.batch_size]
        batch_y = self.labels[idx * self.batch_size:(idx + 1) * self.batch_size]
        return np.array([
            resize(imread(filename), (200, 200))
               for filename in batch_x]), np.array(batch_y)

sequence = CIFAR10Sequence(filenames, labels, batch_size)
model.fit(sequence, epochs=10)

באמצעות שקלול מדגם ושקלול כיתה

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

  • משקולות כיתה
  • משקולות לדוגמא

משקולות כיתה

זה מוגדר על ידי העברת מילון אל class_weight טיעון כדי Model.fit() . מילון זה ממפה מדדי כיתות למשקל שיש להשתמש בדוגמאות השייכות למחלקה זו.

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

למשל, אם המחלקה "0" מיוצגת במחצית מהמחלקה "1" בנתונים שלך, תוכל להשתמש ב- Model.fit(..., class_weight={0: 1., 1: 0.5}) .

הנה דוגמה של NumPy שבה אנו משתמשים במשקולות מחלקה או משקולות לדוגמא כדי לתת חשיבות רבה יותר לסיווג הנכון של מחלקה מספר 5 (שהיא הספרה "5" במערך MNIST).

import numpy as np

class_weight = {
    0: 1.0,
    1: 1.0,
    2: 1.0,
    3: 1.0,
    4: 1.0,
    # Set weight "2" for class "5",
    # making this class 2x more important
    5: 2.0,
    6: 1.0,
    7: 1.0,
    8: 1.0,
    9: 1.0,
}

print("Fit with class weight")
model = get_compiled_model()
model.fit(x_train, y_train, class_weight=class_weight, batch_size=64, epochs=1)
Fit with class weight
782/782 [==============================] - 2s 2ms/step - loss: 0.6531 - sparse_categorical_accuracy: 0.8268

<tensorflow.python.keras.callbacks.History at 0x7fb27c4e6da0>

משקולות לדוגמא

לבקרת גרגירים עדינים, או אם אינכם בונים מסווג, תוכלו להשתמש ב"משקולות לדוגמא ".

  • בעת אימון מנתוני sample_weight : העבירו את הארגומנט Model.fit() ל- Model.fit() .
  • בעת אימון מ- tf.data או מכל סוג אחר של איטרטור: תשואות (input_batch, label_batch, sample_weight_batch) .

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

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

sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.0

print("Fit with sample weight")
model = get_compiled_model()
model.fit(x_train, y_train, sample_weight=sample_weight, batch_size=64, epochs=1)
Fit with sample weight
782/782 [==============================] - 2s 2ms/step - loss: 0.6471 - sparse_categorical_accuracy: 0.8342

<tensorflow.python.keras.callbacks.History at 0x7fb21c1257f0>

הנה דוגמה Dataset תואם:

sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.0

# Create a Dataset that includes sample weights
# (3rd element in the return tuple).
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train, sample_weight))

# Shuffle and slice the dataset.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

model = get_compiled_model()
model.fit(train_dataset, epochs=1)
782/782 [==============================] - 2s 3ms/step - loss: 0.6161 - sparse_categorical_accuracy: 0.8486

<tensorflow.python.keras.callbacks.History at 0x7fb27c7a46a0>

העברת נתונים למודלים מרובי-קלט, רב-פלט

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

שקול את המודל הבא, בעל קלט תמונה של צורה (32, 32, 3) (כלומר (height, width, channels) ) וקלט זמן של צורה (None, 10) (כלומר (timesteps, features) ). המודל שלנו יכלול שתי יציאות המחושבות משילוב הקלטים הללו: "ציון" (של צורה (1,) ) והתפלגות הסתברות על פני חמש סוגים (של צורה (5,) ).

image_input = keras.Input(shape=(32, 32, 3), name="img_input")
timeseries_input = keras.Input(shape=(None, 10), name="ts_input")

x1 = layers.Conv2D(3, 3)(image_input)
x1 = layers.GlobalMaxPooling2D()(x1)

x2 = layers.Conv1D(3, 3)(timeseries_input)
x2 = layers.GlobalMaxPooling1D()(x2)

x = layers.concatenate([x1, x2])

score_output = layers.Dense(1, name="score_output")(x)
class_output = layers.Dense(5, name="class_output")(x)

model = keras.Model(
    inputs=[image_input, timeseries_input], outputs=[score_output, class_output]
)

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

keras.utils.plot_model(model, "multi_input_and_output_model.png", show_shapes=True)

png

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

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
)

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

כך גם למדדים:

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
    metrics=[
        [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        [keras.metrics.CategoricalAccuracy()],
    ],
)

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

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={
        "score_output": keras.losses.MeanSquaredError(),
        "class_output": keras.losses.CategoricalCrossentropy(),
    },
    metrics={
        "score_output": [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        "class_output": [keras.metrics.CategoricalAccuracy()],
    },
)

אנו ממליצים להשתמש בשמות ודיקטים מפורשים אם יש לך יותר מ -2 תפוקות.

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

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={
        "score_output": keras.losses.MeanSquaredError(),
        "class_output": keras.losses.CategoricalCrossentropy(),
    },
    metrics={
        "score_output": [
            keras.metrics.MeanAbsolutePercentageError(),
            keras.metrics.MeanAbsoluteError(),
        ],
        "class_output": [keras.metrics.CategoricalAccuracy()],
    },
    loss_weights={"score_output": 2.0, "class_output": 1.0},
)

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

# List loss version
model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[None, keras.losses.CategoricalCrossentropy()],
)

# Or dict loss version
model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss={"class_output": keras.losses.CategoricalCrossentropy()},
)

העברת נתונים למודל רב קלט או רב פלט בכושר עובדת באופן דומה לציון פונקציית הפסד בקומפילציה: ניתן להעביר רשימות של מערכי NumPy (עם מיפוי 1: 1 ליציאות שקיבלו פונקציית הפסד) או מכתיב מיפוי שמות פלט למערכי NumPy .

model.compile(
    optimizer=keras.optimizers.RMSprop(1e-3),
    loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()],
)

# Generate dummy NumPy data
img_data = np.random.random_sample(size=(100, 32, 32, 3))
ts_data = np.random.random_sample(size=(100, 20, 10))
score_targets = np.random.random_sample(size=(100, 1))
class_targets = np.random.random_sample(size=(100, 5))

# Fit on lists
model.fit([img_data, ts_data], [score_targets, class_targets], batch_size=32, epochs=1)

# Alternatively, fit on dicts
model.fit(
    {"img_input": img_data, "ts_input": ts_data},
    {"score_output": score_targets, "class_output": class_targets},
    batch_size=32,
    epochs=1,
)
4/4 [==============================] - 2s 12ms/step - loss: 19.3697 - score_output_loss: 1.3639 - class_output_loss: 18.0058
4/4 [==============================] - 0s 6ms/step - loss: 17.6548 - score_output_loss: 0.7146 - class_output_loss: 16.9402

<tensorflow.python.keras.callbacks.History at 0x7fb27c5d51d0>

הנה מקרה השימוש Dataset : בדומה למה שעשינו למערכי NumPy, Dataset אמור להחזיר מעט דיקטים.

train_dataset = tf.data.Dataset.from_tensor_slices(
    (
        {"img_input": img_data, "ts_input": ts_data},
        {"score_output": score_targets, "class_output": class_targets},
    )
)
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)

model.fit(train_dataset, epochs=1)
2/2 [==============================] - 0s 29ms/step - loss: 17.3215 - score_output_loss: 0.5076 - class_output_loss: 16.8139

<tensorflow.python.keras.callbacks.History at 0x7fb27c46b438>

באמצעות שיחות חוזרות

Callbacks ב- Keras הם אובייקטים שנקראים בנקודות שונות במהלך האימון (בתחילת תקופה, בסוף אצווה, בסוף תקופה וכו ') ואשר ניתן להשתמש בהם ליישום התנהגויות כגון:

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

ניתן להעביר שיחות fit() כרשימה לשיחתך fit() :

model = get_compiled_model()

callbacks = [
    keras.callbacks.EarlyStopping(
        # Stop training when `val_loss` is no longer improving
        monitor="val_loss",
        # "no longer improving" being defined as "no better than 1e-2 less"
        min_delta=1e-2,
        # "no longer improving" being further defined as "for at least 2 epochs"
        patience=2,
        verbose=1,
    )
]
model.fit(
    x_train,
    y_train,
    epochs=20,
    batch_size=64,
    callbacks=callbacks,
    validation_split=0.2,
)
Epoch 1/20
625/625 [==============================] - 2s 3ms/step - loss: 0.6313 - sparse_categorical_accuracy: 0.8207 - val_loss: 0.2313 - val_sparse_categorical_accuracy: 0.9307
Epoch 2/20
625/625 [==============================] - 2s 3ms/step - loss: 0.1827 - sparse_categorical_accuracy: 0.9459 - val_loss: 0.1989 - val_sparse_categorical_accuracy: 0.9410
Epoch 3/20
625/625 [==============================] - 2s 3ms/step - loss: 0.1298 - sparse_categorical_accuracy: 0.9619 - val_loss: 0.1561 - val_sparse_categorical_accuracy: 0.9529
Epoch 4/20
625/625 [==============================] - 2s 2ms/step - loss: 0.0977 - sparse_categorical_accuracy: 0.9713 - val_loss: 0.1434 - val_sparse_categorical_accuracy: 0.9576
Epoch 5/20
625/625 [==============================] - 2s 3ms/step - loss: 0.0799 - sparse_categorical_accuracy: 0.9755 - val_loss: 0.1364 - val_sparse_categorical_accuracy: 0.9614
Epoch 6/20
625/625 [==============================] - 2s 3ms/step - loss: 0.0648 - sparse_categorical_accuracy: 0.9806 - val_loss: 0.1351 - val_sparse_categorical_accuracy: 0.9617
Epoch 00006: early stopping

<tensorflow.python.keras.callbacks.History at 0x7fb29ca68940>

קיימים שיחות חוזרות מובנות רבות

  • ModelCheckpoint : שמור את המודל מעת לעת.
  • עצירה EarlyStopping : הפסק את האימון כאשר האימון אינו משפר עוד את מדדי האימות.
  • TensorBoard : כתוב מעת לעת יומני מודל שניתן לדמיין אותם ב- TensorBoard (פרטים נוספים בסעיף "ויזואליזציה").
  • CSVLogger : מזרים נתוני אובדן וערכים לקובץ CSV.
  • וכו '

עיין בתיעוד השיחות החזרה לרשימה המלאה.

כותב התקשרות חוזרת משלך

באפשרותך ליצור התקשרות חוזרת בהתאמה אישית על ידי הרחבת מחלקת הבסיס keras.callbacks.Callback . להתקשרות חוזרת יש גישה למודל המשויך שלה באמצעות מודל הרכוש self.model class.

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

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

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs):
        self.per_batch_losses = []

    def on_batch_end(self, batch, logs):
        self.per_batch_losses.append(logs.get("loss"))

מודלים למחסום

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

הדרך הקלה ביותר להשיג זאת היא באמצעות התקשרות חוזרת של ModelCheckpoint :

model = get_compiled_model()

callbacks = [
    keras.callbacks.ModelCheckpoint(
        # Path where to save the model
        # The two parameters below mean that we will overwrite
        # the current checkpoint if and only if
        # the `val_loss` score has improved.
        # The saved model name will include the current epoch.
        filepath="mymodel_{epoch}",
        save_best_only=True,  # Only save a model if `val_loss` has improved.
        monitor="val_loss",
        verbose=1,
    )
]
model.fit(
    x_train, y_train, epochs=2, batch_size=64, callbacks=callbacks, validation_split=0.2
)
Epoch 1/2
625/625 [==============================] - 2s 3ms/step - loss: 0.6208 - sparse_categorical_accuracy: 0.8258 - val_loss: 0.2241 - val_sparse_categorical_accuracy: 0.9326

Epoch 00001: val_loss improved from inf to 0.22410, saving model to mymodel_1
INFO:tensorflow:Assets written to: mymodel_1/assets
Epoch 2/2
625/625 [==============================] - 2s 3ms/step - loss: 0.1820 - sparse_categorical_accuracy: 0.9470 - val_loss: 0.1621 - val_sparse_categorical_accuracy: 0.9497

Epoch 00002: val_loss improved from 0.22410 to 0.16212, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets

<tensorflow.python.keras.callbacks.History at 0x7fb21c3e8a20>

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

import os

# Prepare a directory to store all the checkpoints.
checkpoint_dir = "./ckpt"
if not os.path.exists(checkpoint_dir):
    os.makedirs(checkpoint_dir)


def make_or_restore_model():
    # Either restore the latest model, or create a fresh one
    # if there is no checkpoint available.
    checkpoints = [checkpoint_dir + "/" + name for name in os.listdir(checkpoint_dir)]
    if checkpoints:
        latest_checkpoint = max(checkpoints, key=os.path.getctime)
        print("Restoring from", latest_checkpoint)
        return keras.models.load_model(latest_checkpoint)
    print("Creating a new model")
    return get_compiled_model()


model = make_or_restore_model()
callbacks = [
    # This callback saves a SavedModel every 100 batches.
    # We include the training loss in the saved model name.
    keras.callbacks.ModelCheckpoint(
        filepath=checkpoint_dir + "/ckpt-loss={loss:.2f}", save_freq=100
    )
]
model.fit(x_train, y_train, epochs=1, callbacks=callbacks)
Creating a new model
  94/1563 [>.............................] - ETA: 3s - loss: 1.4324 - sparse_categorical_accuracy: 0.5773INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.96/assets
 193/1563 [==>...........................] - ETA: 5s - loss: 1.1162 - sparse_categorical_accuracy: 0.6814INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.69/assets
 290/1563 [====>.........................] - ETA: 6s - loss: 0.9546 - sparse_categorical_accuracy: 0.7298INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.57/assets
 395/1563 [======>.......................] - ETA: 6s - loss: 0.8447 - sparse_categorical_accuracy: 0.7617INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.51/assets
 493/1563 [========>.....................] - ETA: 6s - loss: 0.7744 - sparse_categorical_accuracy: 0.7817INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.47/assets
 598/1563 [==========>...................] - ETA: 5s - loss: 0.7186 - sparse_categorical_accuracy: 0.7973INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.44/assets
 696/1563 [============>.................] - ETA: 5s - loss: 0.6778 - sparse_categorical_accuracy: 0.8086INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.42/assets
 794/1563 [==============>...............] - ETA: 4s - loss: 0.6445 - sparse_categorical_accuracy: 0.8178INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.40/assets
 898/1563 [================>.............] - ETA: 4s - loss: 0.6146 - sparse_categorical_accuracy: 0.8260INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.38/assets
 995/1563 [==================>...........] - ETA: 3s - loss: 0.5907 - sparse_categorical_accuracy: 0.8326INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.36/assets
1095/1563 [====================>.........] - ETA: 2s - loss: 0.5693 - sparse_categorical_accuracy: 0.8385INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.35/assets
1196/1563 [=====================>........] - ETA: 2s - loss: 0.5503 - sparse_categorical_accuracy: 0.8437INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1297/1563 [=======================>......] - ETA: 1s - loss: 0.5334 - sparse_categorical_accuracy: 0.8484INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1391/1563 [=========================>....] - ETA: 1s - loss: 0.5193 - sparse_categorical_accuracy: 0.8523INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1497/1563 [===========================>..] - ETA: 0s - loss: 0.5050 - sparse_categorical_accuracy: 0.8563INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.31/assets
1563/1563 [==============================] - 11s 6ms/step - loss: 0.4966 - sparse_categorical_accuracy: 0.8586

<tensorflow.python.keras.callbacks.History at 0x7fb2700955c0>

אתה מתקשר גם כותב התקשרות חוזרת משלך לשמירה ושחזור דגמים.

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

שימוש בלוחות זמנים של קצב למידה

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

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

העברת לוח זמנים למייעל

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

initial_learning_rate = 0.1
lr_schedule = keras.optimizers.schedules.ExponentialDecay(
    initial_learning_rate, decay_steps=100000, decay_rate=0.96, staircase=True
)

optimizer = keras.optimizers.RMSprop(learning_rate=lr_schedule)

קיימים מספר לוחות זמנים מובנים: ExponentialDecay , PiecewiseConstantDecay , PolynomialDecay ו- InverseTimeDecay .

שימוש בשיחות חוזרות ליישום לוח זמנים קצב למידה דינמי

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

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

הדמיה של אובדן ומדדים במהלך האימון

הדרך הטובה ביותר לפקוח עין על המודל שלך במהלך האימון היא להשתמש ב- TensorBoard , יישום מבוסס דפדפן שתוכל להפעיל באופן מקומי המספק לך:

  • עלילות חי של האובדן והמדדים להכשרה והערכה
  • (אופציונלי) ויזואליזציות של ההיסטוגרמות של פעולות השכבה שלך
  • (אופציונלי) הדמיות תלת ממדיות של חללי ההטבעה שנלמדו על ידי שכבות Embedding שלך

אם התקנת את TensorFlow עם pip, אתה אמור להיות מסוגל להפעיל את TensorBoard משורת הפקודה:

tensorboard --logdir=/full_path_to_your_logs

שימוש בקריאה חוזרת של TensorBoard

הדרך הקלה ביותר להשתמש ב- TensorBoard עם מודל Keras ושיטת ההתאמה היא TensorBoard של TensorBoard .

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

keras.callbacks.TensorBoard(
    log_dir="/full_path_to_your_logs",
    histogram_freq=0,  # How often to log histogram visualizations
    embeddings_freq=0,  # How often to log embedding visualizations
    update_freq="epoch",
)  # How often to write logs (default: once per epoch)
<tensorflow.python.keras.callbacks.TensorBoard at 0x7fb21c22deb8>

למידע נוסף, עיין בתיעוד TensorBoard חוזרת של TensorBoard .