![]() | ![]() | ![]() | ![]() |
להכין
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)
בזמן ההידור, אנו יכולים לציין הפסדים שונים לתפוקות שונות, על ידי העברת פונקציות ההפסד כרשימה:
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
ההתקשרות .