צפה בהערות מרכזיות, הפעלות מוצר, סדנאות ועוד מ- Google I / O ראה רשימת השמעה

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

צפה ב- 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]
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step

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

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 את המודל על ידי חיתוך הנתונים batch_size "בגודל batch_size , וחזר שוב ושוב על כל מערך הנתונים למספר epochs נתון.

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.5769 - sparse_categorical_accuracy: 0.8386 - val_loss: 0.1833 - val_sparse_categorical_accuracy: 0.9464
Epoch 2/2
782/782 [==============================] - 2s 2ms/step - loss: 0.1621 - sparse_categorical_accuracy: 0.9518 - val_loss: 0.1467 - val_sparse_categorical_accuracy: 0.9579

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

history.history
{'loss': [0.3323673903942108, 0.15159013867378235],
 'sparse_categorical_accuracy': [0.9050800204277039, 0.9542400240898132],
 'val_loss': [0.18328842520713806, 0.14667865633964539],
 'val_sparse_categorical_accuracy': [0.946399986743927, 0.9578999876976013]}

אנו מעריכים את המודל על נתוני הבדיקה באמצעות 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.1449 - sparse_categorical_accuracy: 0.9539
test loss, test acc: [0.14493884146213531, 0.9538999795913696]
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 [==============================] - 1s 1ms/step - loss: 0.0272
<tensorflow.python.keras.callbacks.History at 0x7fb6b01c09e8>

אם אתה זקוק לפונקציית הפסד שמקבלת פרמטרים לצד 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.0489
<tensorflow.python.keras.callbacks.History at 0x7fb6b00725f8>

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

אם אתה זקוק למדד שאינו חלק 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 [==============================] - 2s 2ms/step - loss: 0.5782 - categorical_true_positives: 22110.9323
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1737 - categorical_true_positives: 23825.8212
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1254 - categorical_true_positives: 24152.4547
<tensorflow.python.keras.callbacks.History at 0x7fb6a42a55f8>

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

את הרוב המכריע של ההפסדים והמדדים ניתן לחשב מ 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.4140
<tensorflow.python.keras.callbacks.History at 0x7fb6a4233748>

אתה יכול לעשות את אותו הדבר לרישום ערכי מדדים, באמצעות 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.5646 - std_of_activation: 0.9702
<tensorflow.python.keras.callbacks.History at 0x7fb6a40cf6a0>

בממשק ה- 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.6195 - std_of_activation: 0.0020
<tensorflow.python.keras.callbacks.History at 0x7fb6a07d42b0>

שים לב שכאשר אתה מעביר הפסדים באמצעות 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 222ms/step - loss: 0.9652 - binary_accuracy: 0.0000e+00
<tensorflow.python.keras.callbacks.History at 0x7fb6a05e01d0>

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

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

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

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

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

שים לב שאתה יכול להשתמש ב- 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 2ms/step - loss: 0.6075 - sparse_categorical_accuracy: 0.8389 - val_loss: 0.2291 - val_sparse_categorical_accuracy: 0.9322
<tensorflow.python.keras.callbacks.History at 0x7fb6a0504240>

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

בשנת הפסקאות האחרונות, ראית איך לטפל הפסדים, מדדים אופטימיזציה, ואתה ראית איך להשתמש validation_data ו validation_split הטיעונים fit() , כאשר הנתונים שלך עברו כתוצאה מערכים 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 2ms/step - loss: 0.5652 - sparse_categorical_accuracy: 0.8404
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1721 - sparse_categorical_accuracy: 0.9497
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1170 - sparse_categorical_accuracy: 0.9645
Evaluate
157/157 [==============================] - 0s 2ms/step - loss: 0.1308 - sparse_categorical_accuracy: 0.9602
{'loss': 0.13075917959213257,
 'sparse_categorical_accuracy': 0.9602000117301941}

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

אם ברצונך להפעיל אימונים רק על מספר ספציפי של קבוצות ממערך נתונים זה, תוכל להעביר את הארגומנט 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 2ms/step - loss: 1.2664 - sparse_categorical_accuracy: 0.6389
Epoch 2/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3868 - sparse_categorical_accuracy: 0.8875
Epoch 3/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3578 - sparse_categorical_accuracy: 0.8981
<tensorflow.python.keras.callbacks.History at 0x7fb6a02a5358>

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

באפשרותך להעביר מופע של 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 [==============================] - 2s 3ms/step - loss: 0.5754 - sparse_categorical_accuracy: 0.8384 - val_loss: 0.1829 - val_sparse_categorical_accuracy: 0.9465
<tensorflow.python.keras.callbacks.History at 0x7fb6a01651d0>

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

אם ברצונך להריץ אימות רק על מספר ספציפי של קבוצות ממערך נתונים זה, תוכל להעביר את הארגומנט 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 [==============================] - 2s 2ms/step - loss: 0.5503 - sparse_categorical_accuracy: 0.8507 - val_loss: 0.3296 - val_sparse_categorical_accuracy: 0.9062
<tensorflow.python.keras.callbacks.History at 0x7fb6a02e4630>

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

הארגומנט 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.6269 - sparse_categorical_accuracy: 0.8396
<tensorflow.python.keras.callbacks.History at 0x7fb6ca2479b0>

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

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

  • בעת אימון מנתוני 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.6540 - sparse_categorical_accuracy: 0.8302
<tensorflow.python.keras.callbacks.History at 0x7fb6b03db128>

להלן דוגמא 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 2ms/step - loss: 0.6052 - sparse_categorical_accuracy: 0.8477
<tensorflow.python.keras.callbacks.History at 0x7fb6a40cc908>

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

בדוגמאות הקודמות שקלנו מודל עם קלט יחיד (טנסור של צורה (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()},
)

העברת נתונים למודל רב קלט או רב פלט fit() פועלת באופן דומה לציון פונקציית הפסד בקומפילציה: ניתן להעביר רשימות של מערכי 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 [==============================] - 10s 10ms/step - loss: 12.4255 - score_output_loss: 0.7638 - class_output_loss: 11.6617
4/4 [==============================] - 0s 5ms/step - loss: 11.1176 - score_output_loss: 0.6303 - class_output_loss: 10.4873
<tensorflow.python.keras.callbacks.History at 0x7fb6a02ed828>

הנה מקרה השימוש 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 27ms/step - loss: 10.9011 - score_output_loss: 0.4919 - class_output_loss: 10.4092
<tensorflow.python.keras.callbacks.History at 0x7fb6b00ae9e8>

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

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

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

ניתן להעביר שיחות 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.6076 - sparse_categorical_accuracy: 0.8350 - val_loss: 0.2323 - val_sparse_categorical_accuracy: 0.9306
Epoch 2/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1925 - sparse_categorical_accuracy: 0.9436 - val_loss: 0.1828 - val_sparse_categorical_accuracy: 0.9446
Epoch 3/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1310 - sparse_categorical_accuracy: 0.9616 - val_loss: 0.1580 - val_sparse_categorical_accuracy: 0.9510
Epoch 4/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0967 - sparse_categorical_accuracy: 0.9700 - val_loss: 0.1681 - val_sparse_categorical_accuracy: 0.9490
Epoch 5/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0841 - sparse_categorical_accuracy: 0.9742 - val_loss: 0.1482 - val_sparse_categorical_accuracy: 0.9568
Epoch 00005: early stopping
<tensorflow.python.keras.callbacks.History at 0x7fb63c5945c0>

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

ישנם הרבה שיחות חוזרות מובנות שקיימות כבר ב- Keras, כגון:

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

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

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

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

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

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

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 2ms/step - loss: 0.6397 - sparse_categorical_accuracy: 0.8210 - val_loss: 0.2310 - val_sparse_categorical_accuracy: 0.9326

Epoch 00001: val_loss improved from inf to 0.23098, saving model to mymodel_1
INFO:tensorflow:Assets written to: mymodel_1/assets
Epoch 2/2
625/625 [==============================] - 1s 2ms/step - loss: 0.1885 - sparse_categorical_accuracy: 0.9454 - val_loss: 0.1851 - val_sparse_categorical_accuracy: 0.9435

Epoch 00002: val_loss improved from 0.23098 to 0.18510, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets
<tensorflow.python.keras.callbacks.History at 0x7fb6a04271d0>

ניתן להשתמש 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
  85/1563 [>.............................] - ETA: 2s - loss: 1.4465 - sparse_categorical_accuracy: 0.5717INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.93/assets
 185/1563 [==>...........................] - ETA: 5s - loss: 1.1118 - sparse_categorical_accuracy: 0.6784INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.69/assets
 284/1563 [====>.........................] - ETA: 5s - loss: 0.9495 - sparse_categorical_accuracy: 0.7266INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.58/assets
 385/1563 [======>.......................] - ETA: 5s - loss: 0.8464 - sparse_categorical_accuracy: 0.7569INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.52/assets
 485/1563 [========>.....................] - ETA: 5s - loss: 0.7749 - sparse_categorical_accuracy: 0.7776INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.47/assets
 585/1563 [==========>...................] - ETA: 4s - loss: 0.7210 - sparse_categorical_accuracy: 0.7930INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.44/assets
 685/1563 [============>.................] - ETA: 4s - loss: 0.6788 - sparse_categorical_accuracy: 0.8050INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.42/assets
 785/1563 [==============>...............] - ETA: 4s - loss: 0.6445 - sparse_categorical_accuracy: 0.8149INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.40/assets
 883/1563 [===============>..............] - ETA: 3s - loss: 0.6165 - sparse_categorical_accuracy: 0.8229INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.38/assets
 984/1563 [=================>............] - ETA: 3s - loss: 0.5917 - sparse_categorical_accuracy: 0.8299INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.37/assets
1082/1563 [===================>..........] - ETA: 2s - loss: 0.5709 - sparse_categorical_accuracy: 0.8358INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.35/assets
1185/1563 [=====================>........] - ETA: 1s - loss: 0.5517 - sparse_categorical_accuracy: 0.8413INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1282/1563 [=======================>......] - ETA: 1s - loss: 0.5356 - sparse_categorical_accuracy: 0.8459INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1384/1563 [=========================>....] - ETA: 0s - loss: 0.5202 - sparse_categorical_accuracy: 0.8503INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1484/1563 [===========================>..] - ETA: 0s - loss: 0.5065 - sparse_categorical_accuracy: 0.8542INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.31/assets
1563/1563 [==============================] - 9s 5ms/step - loss: 0.4965 - sparse_categorical_accuracy: 0.8570
<tensorflow.python.keras.callbacks.History at 0x7fb6a036f5c0>

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

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

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

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

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

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

אתה יכול להשתמש בלוח זמנים של ריקבון קצב למידה סטטי בקלות על ידי העברת אובייקט לוח זמנים כארגומנט 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 ובשיטת fit() היא 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 0x7fb6a422a748>

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