التدريب والتقييم بالطرق المدمجة

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

يثبت

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

مقدمة

هذا دليل يغطي التدريب والتقييم والتنبؤ (الاستدلال) نماذج عند استخدام المدمج في واجهات برمجة التطبيقات للتدريب والتحقق من صحة (مثل Model.fit() ، Model.evaluate() و Model.predict() ).

إذا كنت مهتما في الاستفادة fit() مع تحديد الخاصة وظيفة التدريب خطوة، راجع تخصيص ما يحدث في fit() دليل .

إذا كنت مهتما في كتابة التدريب والتقييم الخاصة الحلقات الخاصة بك من الصفر، راجع دليل "كتابة حلقة التدريب من الصفر" .

بشكل عام ، سواء كنت تستخدم حلقات مدمجة أو تكتب نموذجًا خاصًا بك ، فإن تدريب وتقييم النموذج يعمل بشكل صارم بنفس الطريقة عبر كل نوع من نماذج Keras - النماذج المتسلسلة ، والنماذج التي تم إنشاؤها باستخدام واجهة برمجة التطبيقات الوظيفية ، والنماذج المكتوبة من البداية عبر تصنيف فرعي للنموذج.

هذا الدليل لا يغطي التدريب الموزعة، والتي تتناول في لدينا دليل متعددة GPU والتدريب توزيعها .

نظرة عامة على API: مثال أول شامل

عند تمرير البيانات إلى المدمج في تدريب الحلقات نموذج، يجب عليك إما استخدام المصفوفات نمباي (إذا كانت البيانات الخاص بك هو صغير ويناسب في الذاكرة) أو tf.data Dataset الكائنات. في الفقرات القليلة التالية ، سنستخدم مجموعة بيانات MNIST كمصفوفات NumPy ، من أجل توضيح كيفية استخدام أدوات تحسين الأداء ، والخسائر ، والمقاييس.

دعنا نفكر في النموذج التالي (هنا ، قمنا ببناء واجهة برمجة التطبيقات الوظيفية ، ولكن يمكن أن يكون نموذجًا تسلسليًا أو نموذجًا مصنفًا فرعيًا أيضًا):

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 ، وبشكل متكرر بالتكرار عبر مجموعة البيانات بأكملها لعدد معين من 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

تتوفر العديد من أدوات التحسين المضمنة والخسائر والمقاييس

بشكل عام ، لن تضطر إلى إنشاء خسائر أو مقاييس أو أدوات تحسين خاصة بك من البداية ، لأن ما تحتاجه من المحتمل أن يكون بالفعل جزءًا من Keras API:

المُحسِّنون:

  • 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، يمكنك بسهولة إنشاء مقاييس مخصصة شاء subclasses ترث من 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() ). إليك مثال بسيط يضيف تنظيمًا للنشاط (لاحظ أن تنظيم النشاط مدمج في جميع طبقات 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: 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) صفائف نمباي (x_val, y_val) إلى نموذج لتقييم خسارة التحقق من صحة والمقاييس التحقق من صحة في نهاية كل حقبة.

وهنا خيار آخر: حجة validation_split يسمح لك جزء الاحتياط تلقائيا من بيانات التدريب للحصول على التحقق من الصحة. وتمثل قيمة وسيطة جزء من البيانات التي يمكن محفوظة للمصادقة عليها، لذلك يجب تعيين لعدد أكبر من 0 وأقل من 1. على سبيل المثال، validation_split=0.2 وسيلة "استخدام 20٪ من البيانات اللازمة للتحقق"، و validation_split=0.6 وسيلة "استخدام 60٪ من البيانات اللازمة للتحقق".

طريقة احتساب التحقق من الصحة بأخذ عينات٪ خ الأخير من المصفوفات التي تلقى fit() المكالمة، قبل أي خلط.

لاحظ أنه يمكنك فقط استخدام validation_split عندما التدريب مع البيانات نمباي.

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

في الفقرات القليلة الماضية، كنت قد رأيت كيفية التعامل مع الخسائر والمقاييس، وأبتيميزر، وكنت قد رأيت كيفية استخدام validation_data و validation_split الحجج في fit() ، عندما يتم تمرير البيانات الخاصة بك كما صفائف نمباي.

دعونا الآن نلقي نظرة على الحالة التي يكون فيها يأتي البيانات الخاصة بك في شكل 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.

دعم صيغ الإدخال الأخرى

وإلى جانب صفائف نمباي، التنسورات حريصة، وTensorFlow Datasets ، فمن الممكن لتدريب نموذج Keras باستخدام dataframes الباندا، أو من مولدات بيثون أن دفعات العائد من البيانات والعلامات.

على وجه الخصوص، keras.utils.Sequence العروض الطبقة واجهة بسيطة لبناء مولدات البيانات بيثون التي متعدد المعالجة علم ويمكن تعديلا.

بشكل عام ، نوصي باستخدام:

  • بيانات إدخال NumPy إذا كانت بياناتك صغيرة وتناسب الذاكرة
  • Dataset كائنات إذا كان لديك مجموعات البيانات الكبيرة والتي تحتاج إليها للقيام التدريب توزيعها
  • Sequence الكائنات إذا كان لديك مجموعات البيانات الكبيرة وتحتاج إلى القيام بالكثير من العرف معالجة من جانب بيثون التي لا يمكن القيام به في TensorFlow (على سبيل المثال إذا كنت تعتمد على المكتبات الخارجية لتحميل البيانات أو تجهيزها).

باستخدام keras.utils.Sequence الكائن كمدخل

keras.utils.Sequence هو الأداة التي يمكنك فئة فرعية للحصول على مولد بيثون مع اثنين من الخصائص الهامة:

  • يعمل بشكل جيد مع المعالجة المتعددة.
  • ويمكن تعديلا (على سبيل المثال عند تمرير shuffle=True في fit() ).

A 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>

أوزان العينة

للتحكم الدقيق في الحبيبات ، أو إذا لم تكن بصدد إنشاء مصنف ، يمكنك استخدام "أوزان العينات".

  • عندما التدريب من البيانات نمباي: تمرير sample_weight حجة ل 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 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()],
    },
)

نوصي باستخدام الأسماء والإرشادات الصريحة إذا كان لديك أكثر من ناتجين.

فمن الممكن أن يعطي أوزان مختلفة لمختلف خسائر الانتاج محددة (على سبيل المثال، يمكن للمرء أن ترغب في امتياز خسارة "النتيجة" في مثالنا، بإعطاء إلى 2x أهمية فقدان الطبقة)، وذلك باستخدام 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() يعمل بطريقة مماثلة لتحديد وظيفة الخسارة في الترجمة: يمكنك تمرير القوائم صفائف نمباي (مع 1: 1 تعيين إلى المخرجات التي تلقى وظيفة الخسارة ) أو dicts رسم أسماء الإخراج إلى صفائف نمباي.

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 حالة الاستخدام: وبالمثل كما ما فعلناه للصفائف نمباي، و 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>

استخدام عمليات الاسترجاعات

عمليات الاسترجاعات في 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 . A الاستدعاء لديه حق الوصول إلى النموذج المرتبط بها من خلال الخاصية الطبقة 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 .

استخدام عمليات الاسترجاعات لتنفيذ جدول معدل التعلم الديناميكي

لا يمكن تحقيق جدول معدل التعلم الديناميكي (على سبيل المثال ، تقليل معدل التعلم عندما لا تتحسن خسارة التحقق) باستخدام كائنات الجدول هذه ، نظرًا لأن المُحسِّن لا يمكنه الوصول إلى مقاييس التحقق من الصحة.

ومع ذلك ، فإن عمليات رد الاتصال لديها حق الوصول إلى جميع المقاييس ، بما في ذلك مقاييس التحقق من الصحة! يمكنك بالتالي تحقيق هذا النمط باستخدام رد الاتصال الذي يعدل معدل التعلم الحالي على المحسن. في الواقع، وهذا هو حتى المدمج في مثل ReduceLROnPlateau رد.

تصور الخسارة والمقاييس أثناء التدريب

أفضل طريقة لإبقاء العين على النموذج الخاص بك أثناء التدريب لاستخدام TensorBoard - تطبيق يستند إلى مستعرض التي يمكن تشغيلها محليا والذي يوفر لك:

  • قطع حية من الخسارة ومقاييس للتدريب والتقييم
  • (اختياريًا) تصورات الرسوم البيانية لعمليات تنشيط الطبقة
  • (اختياريا) 3D تصورات المساحات تضمين المستفادة من قبل الطبيب Embedding طبقات

إذا قمت بتثبيت TensorFlow with 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 رد .