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

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

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

להכין

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

מבוא

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

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

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

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

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

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

כאשר העברת הנתונים המובנה אימון לולאות של מודל, אתה צריך גם להשתמש במערכים numpy (אם הנתונים שלך הוא קטן ומתאים זיכרון) או 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 , שוב ושוב iterating מעל במערך כולו במשך מספר נתון 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.3387 - sparse_categorical_accuracy: 0.9050 - val_loss: 0.1957 - val_sparse_categorical_accuracy: 0.9426
Epoch 2/2
782/782 [==============================] - 2s 3ms/step - loss: 0.1543 - sparse_categorical_accuracy: 0.9548 - val_loss: 0.1425 - val_sparse_categorical_accuracy: 0.9593

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

history.history
{'loss': [0.3386789858341217, 0.1543138176202774],
 'sparse_categorical_accuracy': [0.9050400257110596, 0.9548400044441223],
 'val_loss': [0.19569723308086395, 0.14253544807434082],
 'val_sparse_categorical_accuracy': [0.9426000118255615, 0.9592999815940857]}

אנו מעריכים את המודל על נתוני הבדיקה באמצעות 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.1414 - sparse_categorical_accuracy: 0.9569
test loss, test acc: [0.14140386879444122, 0.9569000005722046]
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.0162
<keras.callbacks.History at 0x7ff8881ba250>

אם אתה צריך פונקציה אובדן שלוקח בפרמטרים ליד y_true ו y_pred , אתה יכול מכל מחלקה 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.0388
<keras.callbacks.History at 0x7ff8882130d0>

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

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

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

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

הנה דוגמה פשוטה מראה כיצד ליישם 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_state(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 3ms/step - loss: 0.3404 - categorical_true_positives: 45217.0000
Epoch 2/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1588 - categorical_true_positives: 47606.0000
Epoch 3/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1168 - categorical_true_positives: 48278.0000
<keras.callbacks.History at 0x7ff8880a3610>

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

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

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

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: 2.4545
<keras.callbacks.History at 0x7ff87c53f310>

אתה יכול לעשות את אותו הדבר עבור כניסת ערכים מטרי, באמצעות 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.3461 - std_of_activation: 0.9929
<keras.callbacks.History at 0x7ff87c3d5bd0>

בשנות ה 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 3ms/step - loss: 2.4647 - std_of_activation: 0.0017
<keras.callbacks.History at 0x7ff87c216f90>

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

שקול את הנקודות הבאות LogisticEndpoint השכבה: זה לוקח כמטרות תשומות & logits, וזה עוקב פסד crossentropy באמצעות 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 414ms/step - loss: 0.9889 - binary_accuracy: 0.0000e+00
<keras.callbacks.History at 0x7ff87c0848d0>

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

הפרדה אוטומטית של ערכת החזקת אימות

בדוגמה מקצה לקצה הראשונה שראית, השתמשנו validation_data טיעון להעביר tuple של מערכים numpy (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 3ms/step - loss: 0.3682 - sparse_categorical_accuracy: 0.8957 - val_loss: 0.2276 - val_sparse_categorical_accuracy: 0.9301
<keras.callbacks.History at 0x7ff81c680890>

הדרכה והערכה מ-tf.data Datasets

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

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

tf.data API הוא סט של כלי עזר ב 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.3372 - sparse_categorical_accuracy: 0.9047
Epoch 2/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1596 - sparse_categorical_accuracy: 0.9523
Epoch 3/3
782/782 [==============================] - 2s 3ms/step - loss: 0.1171 - sparse_categorical_accuracy: 0.9655
Evaluate
157/157 [==============================] - 0s 2ms/step - loss: 0.1211 - sparse_categorical_accuracy: 0.9648
{'loss': 0.12107347697019577,
 'sparse_categorical_accuracy': 0.9648000001907349}

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

אם אתה רוצה לרוץ מתאמן רק על מספר מסוים של קבוצות ממאגר נתון הזה, אתה יכול להעביר את 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: 0.7937 - sparse_categorical_accuracy: 0.7894
Epoch 2/3
100/100 [==============================] - 0s 3ms/step - loss: 0.3699 - sparse_categorical_accuracy: 0.8938
Epoch 3/3
100/100 [==============================] - 0s 3ms/step - loss: 0.3155 - sparse_categorical_accuracy: 0.9061
<keras.callbacks.History at 0x7ff81c587e90>

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

אתה יכול לעבור 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.3380 - sparse_categorical_accuracy: 0.9035 - val_loss: 0.2015 - val_sparse_categorical_accuracy: 0.9405
<keras.callbacks.History at 0x7ff81c30e450>

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

אם אתה רוצה לרוץ אימות רק על מספר מסוים של קבוצות ממאגר נתון הזה, אתה יכול להעביר את 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.3369 - sparse_categorical_accuracy: 0.9036 - val_loss: 0.2953 - val_sparse_categorical_accuracy: 0.9187
<keras.callbacks.History at 0x7ff81c30e310>

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

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

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

מלבד מערכים numpy, להוט tensors, ו TensorFlow Datasets , אפשר לאמן מודל Keras באמצעות dataframes פנדה, או מן גנרטורים Python כי אצוות תשואה של נתונים & תוויות.

בפרט, keras.utils.Sequence הצעות בכיתה ממשק פשוט לבנות גנרטורים נתונים פיתון אשר multiprocessing-מודע וניתן דשדש.

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

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

באמצעות 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 3ms/step - loss: 0.3708 - sparse_categorical_accuracy: 0.9032
<keras.callbacks.History at 0x7ff80c7ddd10>

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

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

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

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

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

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 3ms/step - loss: 0.3806 - sparse_categorical_accuracy: 0.9000
<keras.callbacks.History at 0x7ff80c650350>

הנה התאמת 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 [==============================] - 3s 3ms/step - loss: 0.3588 - sparse_categorical_accuracy: 0.9070
<keras.callbacks.History at 0x7ff80c51cb50>

העברת נתונים לדגמי ריבוי כניסות, ריבוי פלטים

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

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

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 פלטים.

אפשר לתת משקל שונות פסדי פלט ספציפיים שונים (למשל, אחד שירצה פריבילגיה אובדן "הציון" בדוגמא שלנו, על ידי מתן פי 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 מיפוי ליציאות כי קבלו פונקצית פסד ) או dicts מיפוי שמות פלט למערכי 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 9ms/step - loss: 5.6917 - score_output_loss: 0.1031 - class_output_loss: 5.5886
4/4 [==============================] - 0s 6ms/step - loss: 4.4108 - score_output_loss: 0.0999 - class_output_loss: 4.3109
<keras.callbacks.History at 0x7ff80c3b4110>

הנה Dataset במקרה שימוש: דומה כמו מה שעשינו עבור מערכים numpy, את Dataset צריך להחזיר tuple של dicts.

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 21ms/step - loss: 4.2451 - score_output_loss: 0.0993 - class_output_loss: 4.1458
<keras.callbacks.History at 0x7ff80c3ed450>

שימוש בהתקשרויות חוזרות

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

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

התקשרויות חוזרות ניתן להעביר כרשימה לקריאה שלך 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.3725 - sparse_categorical_accuracy: 0.8939 - val_loss: 0.2314 - val_sparse_categorical_accuracy: 0.9321
Epoch 2/20
625/625 [==============================] - 2s 3ms/step - loss: 0.1805 - sparse_categorical_accuracy: 0.9471 - val_loss: 0.2012 - val_sparse_categorical_accuracy: 0.9379
Epoch 3/20
625/625 [==============================] - 2s 3ms/step - loss: 0.1346 - sparse_categorical_accuracy: 0.9603 - val_loss: 0.1651 - val_sparse_categorical_accuracy: 0.9505
Epoch 4/20
625/625 [==============================] - 2s 3ms/step - loss: 0.1065 - sparse_categorical_accuracy: 0.9684 - val_loss: 0.1510 - val_sparse_categorical_accuracy: 0.9571
Epoch 5/20
625/625 [==============================] - 2s 3ms/step - loss: 0.0884 - sparse_categorical_accuracy: 0.9734 - val_loss: 0.1505 - val_sparse_categorical_accuracy: 0.9538
Epoch 6/20
625/625 [==============================] - 2s 3ms/step - loss: 0.0746 - sparse_categorical_accuracy: 0.9778 - val_loss: 0.1508 - val_sparse_categorical_accuracy: 0.9575
Epoch 00006: early stopping
<keras.callbacks.History at 0x7ff80c64cad0>

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

ישנן התקשרויות מובנות רבות שכבר זמינות ב-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
613/625 [============================>.] - ETA: 0s - loss: 0.3693 - sparse_categorical_accuracy: 0.8972
Epoch 00001: val_loss improved from inf to 0.23508, saving model to mymodel_1
2021-11-12 20:11:50.182298: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: mymodel_1/assets
625/625 [==============================] - 3s 4ms/step - loss: 0.3660 - sparse_categorical_accuracy: 0.8979 - val_loss: 0.2351 - val_sparse_categorical_accuracy: 0.9273
Epoch 2/2
620/625 [============================>.] - ETA: 0s - loss: 0.1659 - sparse_categorical_accuracy: 0.9507
Epoch 00002: val_loss improved from 0.23508 to 0.16898, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.1657 - sparse_categorical_accuracy: 0.9507 - val_loss: 0.1690 - val_sparse_categorical_accuracy: 0.9482
<keras.callbacks.History at 0x7ff8b577cc90>

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
  88/1563 [>.............................] - ETA: 3s - loss: 1.1203 - sparse_categorical_accuracy: 0.6911INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=1.04/assets
 185/1563 [==>...........................] - ETA: 6s - loss: 0.7768 - sparse_categorical_accuracy: 0.7858INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.75/assets
 286/1563 [====>.........................] - ETA: 6s - loss: 0.6382 - sparse_categorical_accuracy: 0.8211INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.63/assets
 383/1563 [======>.......................] - ETA: 6s - loss: 0.5584 - sparse_categorical_accuracy: 0.8433INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.55/assets
 484/1563 [========>.....................] - ETA: 6s - loss: 0.5032 - sparse_categorical_accuracy: 0.8578INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.50/assets
 586/1563 [==========>...................] - ETA: 5s - loss: 0.4644 - sparse_categorical_accuracy: 0.8684INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.46/assets
 685/1563 [============>.................] - ETA: 5s - loss: 0.4356 - sparse_categorical_accuracy: 0.8762INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.43/assets
 783/1563 [==============>...............] - ETA: 5s - loss: 0.4127 - sparse_categorical_accuracy: 0.8825INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.41/assets
 883/1563 [===============>..............] - ETA: 4s - loss: 0.3958 - sparse_categorical_accuracy: 0.8868INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.39/assets
 985/1563 [=================>............] - ETA: 3s - loss: 0.3766 - sparse_categorical_accuracy: 0.8918INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.38/assets
1086/1563 [===================>..........] - ETA: 3s - loss: 0.3624 - sparse_categorical_accuracy: 0.8958INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.36/assets
1184/1563 [=====================>........] - ETA: 2s - loss: 0.3498 - sparse_categorical_accuracy: 0.8994INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.35/assets
1283/1563 [=======================>......] - ETA: 1s - loss: 0.3383 - sparse_categorical_accuracy: 0.9029INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1386/1563 [=========================>....] - ETA: 1s - loss: 0.3265 - sparse_categorical_accuracy: 0.9058INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1485/1563 [===========================>..] - ETA: 0s - loss: 0.3184 - sparse_categorical_accuracy: 0.9081INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1563/1563 [==============================] - 11s 7ms/step - loss: 0.3122 - sparse_categorical_accuracy: 0.9097
<keras.callbacks.History at 0x7ff8b53e1dd0>

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

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

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

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

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

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

אתה יכול בקלות להשתמש בלוח זמני ריקבון שיעור למידה סטטי על ידי העברת אובייקט לוח זמנים כמו 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 .

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

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

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

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

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

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

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

tensorboard --logdir=/full_path_to_your_logs

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

הדרך הקלה ביותר לשימוש TensorBoard עם מודל Keras ואת fit() השיטה היא 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)
<keras.callbacks.TensorBoard at 0x7ff88c8c04d0>

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