หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

การฝึกอบรม & amp; การประเมินผลด้วยวิธีการในตัว

ดูใน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดสมุดบันทึก

ติดตั้ง

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

บทนำ

คู่มือนี้ครอบคลุมถึงโมเดลการฝึกอบรมการประเมินผลและการคาดคะเน (การอนุมาน) เมื่อใช้ API ในตัวสำหรับการฝึกอบรมและการตรวจสอบความถูกต้อง (เช่น model.fit() , model.evaluate() , model.predict() )

หากคุณมีความสนใจในการใช้ประโยชน์จาก fit() ในขณะที่ระบุฟังก์ชั่นขั้นตอนการฝึกอบรมของคุณเองดูคำแนะนำ "การปรับแต่งสิ่งที่เกิดขึ้นใน fit() "

หากคุณสนใจที่จะเขียนลูปการฝึกอบรมและการประเมินผลของคุณเองตั้งแต่เริ่มต้นให้ดูคำแนะนำ "การเขียนลูปการฝึกอบรมตั้งแต่เริ่มต้น"

โดยทั่วไปไม่ว่าคุณจะใช้ลูปในตัวหรือการเขียนแบบของคุณเองการฝึกอบรมและการประเมินผลจะทำงานอย่างเคร่งครัดในแบบเดียวกันกับโมเดล Keras ทุกประเภท - โมเดลซีเควนเชียลโมเดลที่สร้างขึ้นด้วย Functional API และโมเดลที่เขียนจากศูนย์ คลาสย่อยของโมเดล

คู่มือนี้ไม่ครอบคลุมการฝึกอบรมแบบกระจาย สำหรับการฝึกอบรมแบบกระจายโปรดดู คู่มือ การฝึกอบรม แบบ multi-gpu และแบบกระจาย

ภาพรวม API: ตัวอย่างจากต้นทางถึงปลายทางแรก

เมื่อส่งข้อมูลไปยังลูปการฝึกอบรมในตัวของโมเดลคุณควรใช้ อาร์เรย์ NumPy (ถ้าข้อมูลของคุณมีขนาดเล็กและพอดีกับหน่วยความจำ) หรือ วัตถุ tf.data Dataset ในสองสามย่อหน้าถัดไปเราจะใช้ชุดข้อมูล MNIST เป็นอาร์เรย์ NumPy เพื่อสาธิตวิธีใช้เครื่องมือเพิ่มประสิทธิภาพการสูญเสียและเมตริก

ลองพิจารณาโมเดลต่อไปนี้ (ที่นี่เราสร้างด้วย Functional 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)
 

นี่คือลักษณะของเวิร์กโฟลว์แบบ end-to-end โดยทั่วไปประกอบด้วย:

  • การอบรม
  • การตรวจสอบความถูกต้องของชุดการจองที่สร้างขึ้นจากข้อมูลการฝึกอบรมดั้งเดิม
  • การประเมินผลข้อมูลการทดสอบ

เราจะใช้ข้อมูล MNIST สำหรับตัวอย่างนี้

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

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

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

# Reserve 10,000 samples for validation
x_val = x_train[-10000:]
y_val = y_train[-10000:]
x_train = x_train[:-10000]
y_train = y_train[:-10000]
 
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step

เราระบุการกำหนดค่าการฝึกอบรม (เครื่องมือเพิ่มประสิทธิภาพการสูญเสียเมตริก):

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

เราเรียกว่า fit() ซึ่งจะฝึกโมเดลโดยการแบ่งข้อมูลออกเป็น "แบทช์" ขนาด "batch_size" และทำซ้ำหลายครั้งบนชุดข้อมูลทั้งหมดสำหรับ "ยุค" จำนวนหนึ่งที่กำหนด

 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 [==============================] - 2s 2ms/step - loss: 0.3476 - sparse_categorical_accuracy: 0.9005 - val_loss: 0.1868 - val_sparse_categorical_accuracy: 0.9452
Epoch 2/2
782/782 [==============================] - 2s 2ms/step - loss: 0.1622 - sparse_categorical_accuracy: 0.9517 - val_loss: 0.1334 - val_sparse_categorical_accuracy: 0.9616

อ็อบเจ็กต์ "history" ที่ส่งคืนมีบันทึกค่าการสูญเสียและค่าเมตริกระหว่างการฝึก:

 history.history
 
{'loss': [0.34755897521972656, 0.16218683123588562],
 'sparse_categorical_accuracy': [0.9004799723625183, 0.9516800045967102],
 'val_loss': [0.18684418499469757, 0.13335685431957245],
 'val_sparse_categorical_accuracy': [0.9452000260353088, 0.9616000056266785]}

เราประเมินแบบจำลองบนข้อมูลการทดสอบผ่านการ 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.1379 - sparse_categorical_accuracy: 0.9594
test loss, test acc: [0.13789668679237366, 0.9593999981880188]
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 [==============================] - 1s 1ms/step - loss: 0.0156

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

หากคุณต้องการฟังก์ชั่นการสูญเสียที่ใช้ในพารามิเตอร์ข้าง y_true และ y_pred คุณสามารถคลาสย่อยคลาส tf.keras.losses.Loss และใช้สองวิธีต่อไปนี้:

  • __init__(self) : ยอมรับพารามิเตอร์ที่จะผ่านในระหว่างการเรียกฟังก์ชั่นการสูญเสียของคุณ
  • call(self, y_true, y_pred) : ใช้เป้าหมาย (y_true) และการทำนายแบบจำลอง (y_pred) เพื่อคำนวณการสูญเสียของแบบจำลอง

สมมติว่าคุณต้องการใช้ค่าเฉลี่ยข้อผิดพลาดกำลังสอง แต่มีคำที่เพิ่มเข้ามาซึ่งจะยกเลิกการกระตุ้นค่าการคาดการณ์ที่ไกลจาก 0.5 (เราถือว่าเป้าหมายเชิงหมวดหมู่มีการเข้ารหัสเพียงจุดเดียวและรับค่าระหว่าง 0 ถึง 1) สิ่งนี้จะสร้างแรงจูงใจให้กับโมเดลที่จะไม่มั่นใจเกินไปซึ่งอาจช่วยลดการ overfitting (เราไม่รู้ว่ามันใช้งานได้จนกว่าเราจะลอง!)

นี่คือวิธีที่คุณจะทำ:

 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 [==============================] - 1s 1ms/step - loss: 0.0386

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

เมตริกที่กำหนดเอง

หากคุณต้องการตัวชี้วัดที่ไม่ได้เป็นส่วนหนึ่งของ 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_states(self) ซึ่งทำให้สถานะของเมตริกเริ่มต้นใหม่

การอัปเดตสถานะและการคำนวณผลลัพธ์จะถูกเก็บแยกต่างหาก (ใน 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_states(self):
        # The state of the metric will be reset at the start of each epoch.
        self.true_positives.assign(0.0)


model = get_uncompiled_model()
model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[CategoricalTruePositives()],
)
model.fit(x_train, y_train, batch_size=64, epochs=3)
 
Epoch 1/3
782/782 [==============================] - 1s 2ms/step - loss: 0.3406 - categorical_true_positives: 45130.0000
Epoch 2/3
782/782 [==============================] - 1s 2ms/step - loss: 0.1591 - categorical_true_positives: 47607.0000
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1140 - categorical_true_positives: 48302.0000

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

การจัดการการสูญเสียและเมตริกที่ไม่ตรงกับลายเซ็นมาตรฐาน

ส่วนใหญ่ของการสูญเสียและตัวชี้วัดที่ครอบงำสามารถคำนวณได้จาก 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 [==============================] - 1s 2ms/step - loss: 2.5240

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

คุณสามารถทำได้เช่นเดียวกันสำหรับการบันทึกค่าเมตริกโดยใช้ 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 [==============================] - 1s 2ms/step - loss: 0.3414 - std_of_activation: 1.0120

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

ใน 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 [==============================] - 1s 2ms/step - loss: 2.5604 - std_of_activation: 0.0023

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

โปรดทราบว่าเมื่อคุณส่งการสูญเสียผ่าน add_loss() มันจะเป็นไปได้ที่จะเรียก compile() โดยไม่มีฟังก์ชันการสูญเสียเนื่องจากโมเดลมีการสูญเสียที่จะลดน้อยที่สุดอยู่แล้ว

พิจารณาเลเยอร์ LogisticEndpoint ต่อไปนี้: ใช้เป็นอินพุตเป้าหมายและบันทึกและติดตามการสูญเสีย add_loss() ผ่าน add_loss() นอกจากนี้ยังติดตามความแม่นยำในการจัดหมวดหมู่ผ่าน add_metric()

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

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

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

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

 

คุณสามารถใช้ในรูปแบบที่มีสองอินพุต (ข้อมูล & เป้าหมาย) รวบรวมโดยไม่มีอาร์กิวเมนต์ loss เช่นนี้:

 import numpy as np

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

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

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

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

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการฝึกโมเดลมัลติอินพุตโปรดดูส่วนการ ส่งผ่านข้อมูลไปยังโมเดลมัลติอินพุตหลายเอาต์พุต

การตั้งค่าแยกชุดการระงับการตรวจสอบความถูกต้องโดยอัตโนมัติ

ในตัวอย่าง end-to-end แรกที่คุณเห็นเราใช้อาร์กิวเมนต์ validation_data เพื่อส่ง tuple ของอาร์เรย์ NumPy (x_val, y_val) ให้กับแบบจำลองสำหรับการประเมินการสูญเสียการตรวจสอบและการตรวจสอบความถูกต้องที่ส่วนท้ายของแต่ละยุค

นี่คืออีกทางเลือกหนึ่ง: อาร์กิวเมนต์ validation_split ช่วยให้คุณสามารถจองส่วนหนึ่งของข้อมูลการฝึกอบรมของคุณโดยอัตโนมัติสำหรับการตรวจสอบความถูกต้อง ค่าอาร์กิวเมนต์แสดงถึงเศษส่วนของข้อมูลที่จะสงวนไว้สำหรับการตรวจสอบความถูกต้องดังนั้นควรตั้งค่าเป็นตัวเลขที่สูงกว่า 0 และต่ำกว่า 1 ตัวอย่างเช่น validation_split=0.2 หมายถึง "ใช้ 20% ของข้อมูลเพื่อการตรวจสอบความถูกต้อง" และ validation_split=0.6 หมายถึง "ใช้ 60% ของข้อมูลสำหรับการตรวจสอบความถูกต้อง"

วิธีคำนวณการตรวจสอบความถูกต้องคือการรับตัวอย่าง x% สุดท้ายของอาร์เรย์ที่ได้รับจากการโทรแบบพอดีก่อนที่จะทำการสับ

โปรดทราบว่าคุณสามารถใช้ validation_split เมื่อฝึกอบรมกับข้อมูล NumPy เท่านั้น

 model = get_compiled_model()
model.fit(x_train, y_train, batch_size=64, validation_split=0.2, epochs=1)
 
625/625 [==============================] - 1s 2ms/step - loss: 0.3745 - sparse_categorical_accuracy: 0.8950 - val_loss: 0.2279 - val_sparse_categorical_accuracy: 0.9333

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

การฝึกอบรมและการประเมินผลจากชุดข้อมูล tf.data

ในวรรคสามที่ผ่านมาคุณเคยเห็นวิธีการจัดการกับความสูญเสียที่ตัวชี้วัดและเพิ่มประสิทธิภาพและคุณได้เห็นวิธีการใช้ validation_data และ validation_split ข้อโต้แย้งในพอดีเมื่อข้อมูลของคุณจะถูกส่งเป็นอาร์เรย์ 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 2ms/step - loss: 0.3373 - sparse_categorical_accuracy: 0.9045
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1582 - sparse_categorical_accuracy: 0.9528
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1146 - sparse_categorical_accuracy: 0.9658
Evaluate
157/157 [==============================] - 0s 1ms/step - loss: 0.1300 - sparse_categorical_accuracy: 0.9601

{'loss': 0.12998636066913605, 'sparse_categorical_accuracy': 0.960099995136261}

โปรดทราบว่าชุดข้อมูลจะถูกรีเซ็ตเมื่อสิ้นสุดแต่ละยุคดังนั้นจึงสามารถนำกลับมาใช้ในยุคถัดไปได้

หากคุณต้องการเรียกใช้การฝึกอบรมเฉพาะกลุ่มที่กำหนดจากชุดข้อมูลนี้คุณสามารถส่งอาร์กิวเมนต์ 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 [==============================] - 0s 2ms/step - loss: 0.7669 - sparse_categorical_accuracy: 0.8027
Epoch 2/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3694 - sparse_categorical_accuracy: 0.8947
Epoch 3/3
100/100 [==============================] - 0s 2ms/step - loss: 0.3178 - sparse_categorical_accuracy: 0.9080

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

การใช้ชุดข้อมูลการตรวจสอบความถูกต้อง

คุณสามารถส่งผ่านอินสแตนซ์ Dataset เป็นอาร์กิวเมนต์ validation_data fit() :

 model = get_compiled_model()

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

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

model.fit(train_dataset, epochs=1, validation_data=val_dataset)
 
782/782 [==============================] - 2s 2ms/step - loss: 0.3401 - sparse_categorical_accuracy: 0.9047 - val_loss: 0.1726 - val_sparse_categorical_accuracy: 0.9521

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

ในตอนท้ายของแต่ละยุคโมเดลจะวนซ้ำบนชุดข้อมูลการตรวจสอบความถูกต้องและคำนวณเมตริกการสูญเสียการตรวจสอบความถูกต้องและการตรวจสอบความถูกต้อง

หากคุณต้องการเรียกใช้การตรวจสอบความถูกต้องเฉพาะในจำนวนชุดข้อมูลที่ระบุจากชุดข้อมูลนี้คุณสามารถส่งผ่านอาร์กิวเมนต์ validation_steps ซึ่งระบุจำนวนขั้นตอนการตรวจสอบที่โมเดลควรรันด้วยชุดข้อมูลการตรวจสอบความถูกต้องก่อนที่จะขัดจังหวะการตรวจสอบความถูกต้องและไปยังยุคถัดไป:

 model = get_compiled_model()

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

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

model.fit(
    train_dataset,
    epochs=1,
    # Only run validation using the first 10 batches of the dataset
    # using the `validation_steps` argument
    validation_data=val_dataset,
    validation_steps=10,
)
 
782/782 [==============================] - 2s 2ms/step - loss: 0.3402 - sparse_categorical_accuracy: 0.9024 - val_loss: 0.3108 - val_sparse_categorical_accuracy: 0.9250

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

โปรดทราบว่าชุดข้อมูลการตรวจสอบความถูกต้องจะถูกรีเซ็ตหลังจากการใช้งานแต่ละครั้ง (ดังนั้นคุณจะได้รับการประเมินจากตัวอย่างเดียวกันตั้งแต่ยุคจนถึงยุค)

ไม่รองรับอาร์กิวเมนต์ validation_split (การสร้างชุดการระงับจากข้อมูลการฝึกอบรม) เมื่อฝึกจากออบเจ็กต์ Dataset เนื่องจากคุณลักษณะนี้ต้องการความสามารถในการทำดัชนีตัวอย่างของชุดข้อมูลซึ่งโดยทั่วไปไม่สามารถทำได้ด้วย Dataset API

รองรับรูปแบบการป้อนข้อมูลอื่น ๆ

นอกจากอาร์เรย์ NumPy, เทนเซอร์ที่กระตือรือร้นและ Datasets TensorFlow แล้วยังสามารถฝึกโมเดล Keras โดยใช้ดาต้าเฟรมของ Pandas หรือจากเครื่องกำเนิด Python ที่ให้ข้อมูลและป้ายกำกับเป็นชุด

โดยเฉพาะอย่างยิ่งคลาส keras.utils.Sequence มีอินเทอร์เฟซที่เรียบง่ายในการสร้างตัวสร้างข้อมูล Python ที่รับรู้การประมวลผลหลายขั้นตอนและสามารถสับเปลี่ยนได้

โดยทั่วไปเราแนะนำให้คุณใช้:

  • ข้อมูลอินพุต NumPy ถ้าข้อมูลของคุณมีขนาดเล็กและพอดีกับหน่วยความจำ
  • วัตถุ Dataset ถ้าคุณมีชุดข้อมูลขนาดใหญ่และคุณจำเป็นต้องทำการฝึกอบรมแบบกระจาย
  • วัตถุ Sequence หากคุณมีชุดข้อมูลขนาดใหญ่และคุณต้องทำการประมวลผลด้านหลามแบบกำหนดเองจำนวนมากที่ไม่สามารถทำได้ใน TensorFlow (เช่นถ้าคุณพึ่งพาไลบรารีภายนอกสำหรับการโหลดข้อมูลหรือการประมวลผลล่วงหน้า)

ใช้ออบเจ็กต์ keras.utils.Sequence เป็นอินพุต

keras.utils.Sequence เป็นยูทิลิตี้ที่คุณสามารถซับคลาสเพื่อรับตัวสร้าง Python ที่มีคุณสมบัติสำคัญสองประการ:

  • ทำงานได้ดีกับการประมวลผลหลายขั้นตอน
  • สามารถสับได้ (เช่นเมื่อผ่านการ 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 [==============================] - 1s 2ms/step - loss: 0.3811 - sparse_categorical_accuracy: 0.8999

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

น้ำหนักตัวอย่าง

สำหรับการควบคุมแบบละเอียดหรือถ้าคุณไม่ได้สร้างลักษณนามคุณสามารถใช้ "น้ำหนักตัวอย่าง"

  • เมื่อการฝึกอบรมจากข้อมูล NumPy: ผ่าน sample_weight อาร์กิวเมนต์ Model.fit()
  • เมื่อฝึกอบรมจาก tf.data หรือตัวเรียงลำดับอื่น ๆ : ผลผลิต (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 [==============================] - 1s 2ms/step - loss: 0.3763 - sparse_categorical_accuracy: 0.9000

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

นี่คือตัวอย่าง Dataset ตรงกัน:

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

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

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

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

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

การส่งผ่านข้อมูลไปยังแบบหลายอินพุตหลายเอาต์พุต

ในตัวอย่างก่อนหน้านี้เรากำลังพิจารณาโมเดลที่มีอินพุตเดียว (เทนเซอร์ของรูปร่าง (764,) ) และเอาท์พุตเดียว (การคาดคะเนรูปร่างเทนเซอร์ (10,) ) แต่รุ่นที่มีอินพุตหรือเอาต์พุตหลายตัวล่ะ?

พิจารณารูปแบบต่อไปนี้ซึ่งมีการป้อนข้อมูลของรูปทรง (32, 32, 3) (นั่นคือ (height, width, channels) ) และการป้อนรูปร่างของชุดเวลา (None, 10) (นั่นคือ (timesteps, features) ) แบบจำลองของเราจะมีสองเอาต์พุตที่คำนวณจากการรวมกันของอินพุตเหล่านี้: "คะแนน" (ของรูปร่าง (1,) ) และการแจกแจงความน่าจะเป็นในห้าคลาส (ของรูปร่าง (5,) )

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

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

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

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

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

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

ลองพล็อตโมเดลนี้เพื่อให้คุณเห็นได้อย่างชัดเจนว่าเรากำลังทำอะไรที่นี่ (โปรดทราบว่ารูปร่างที่แสดงในพล็อตคือรูปร่างแบทช์แทนที่จะเป็นรูปร่างต่อตัวอย่าง)

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

PNG

ในเวลาคอมไพล์เราสามารถระบุการสูญเสียที่แตกต่างกันไปยังเอาต์พุตที่แตกต่างกันได้โดยส่งผ่านฟังก์ชันการสูญเสียเป็นรายการ:

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

หากเราส่งผ่านฟังก์ชันการสูญเสียเพียงครั้งเดียวไปยังแบบจำลองฟังก์ชันการสูญเสียเดียวกันจะถูกนำไปใช้กับทุกเอาต์พุต (ซึ่งไม่เหมาะสมที่นี่)

ในทำนองเดียวกันสำหรับเมตริก:

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

เนื่องจากเราตั้งชื่อให้กับเลเยอร์เอาต์พุตของเราเราจึงสามารถระบุการสูญเสียและเมตริกต่อเอาต์พุตผ่านคำสั่ง:

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

เราขอแนะนำให้ใช้ชื่อที่ชัดเจนและเขียนตามคำบอกหากคุณมีมากกว่า 2 เอาต์พุต

เป็นไปได้ที่จะให้น้ำหนักที่แตกต่างกันสำหรับการสูญเสียเฉพาะเอาต์พุตที่แตกต่างกัน (ตัวอย่างเช่นอาจต้องการให้สิทธิ์การสูญเสีย "คะแนน" ในตัวอย่างของเราโดยให้ความสำคัญกับการสูญเสียคลาสเป็น 2 เท่า) โดยใช้อาร์กิวเมนต์ loss_weights :

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

คุณยังสามารถเลือกที่จะไม่คำนวณการสูญเสียสำหรับผลลัพธ์บางอย่างได้หากผลลัพธ์เหล่านี้มีไว้สำหรับการคาดการณ์ แต่ไม่ใช่สำหรับการฝึกอบรม:

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

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

การส่งผ่านข้อมูลไปยังโมเดลหลายอินพุตหรือหลายเอาต์พุตแบบพอดีจะทำงานในลักษณะเดียวกันกับการระบุฟังก์ชันการสูญเสียในการคอมไพล์: คุณสามารถส่งผ่าน รายการอาร์เรย์ NumPy (ด้วยการแมป 1: 1 ไปยังเอาต์พุตที่ได้รับฟังก์ชันการสูญเสีย) หรือ กำหนดการแมปชื่อเอาต์พุตกับอาร์เรย์ NumPy

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

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

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

# Alternatively, fit on dicts
model.fit(
    {"img_input": img_data, "ts_input": ts_data},
    {"score_output": score_targets, "class_output": class_targets},
    batch_size=32,
    epochs=1,
)
 
4/4 [==============================] - 0s 6ms/step - loss: 11.1192 - score_output_loss: 0.5547 - class_output_loss: 10.5645
4/4 [==============================] - 0s 4ms/step - loss: 9.9594 - score_output_loss: 0.4204 - class_output_loss: 9.5390

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

นี่คือกรณีการใช้งาน Dataset : เช่นเดียวกับสิ่งที่เราทำกับอาร์เรย์ NumPy Dataset ควรส่งคืน tuple ของคำสั่ง

 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 8ms/step - loss: 9.7058 - score_output_loss: 0.3508 - class_output_loss: 9.3550

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

ใช้การโทรกลับ

การเรียกกลับใน 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 [==============================] - 1s 2ms/step - loss: 0.3744 - sparse_categorical_accuracy: 0.8949 - val_loss: 0.2301 - val_sparse_categorical_accuracy: 0.9336
Epoch 2/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1762 - sparse_categorical_accuracy: 0.9485 - val_loss: 0.1818 - val_sparse_categorical_accuracy: 0.9463
Epoch 3/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1292 - sparse_categorical_accuracy: 0.9616 - val_loss: 0.1620 - val_sparse_categorical_accuracy: 0.9524
Epoch 4/20
625/625 [==============================] - 1s 2ms/step - loss: 0.1014 - sparse_categorical_accuracy: 0.9699 - val_loss: 0.1486 - val_sparse_categorical_accuracy: 0.9566
Epoch 5/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0847 - sparse_categorical_accuracy: 0.9751 - val_loss: 0.1612 - val_sparse_categorical_accuracy: 0.9533
Epoch 6/20
625/625 [==============================] - 1s 2ms/step - loss: 0.0699 - sparse_categorical_accuracy: 0.9788 - val_loss: 0.1447 - val_sparse_categorical_accuracy: 0.9600
Epoch 00006: early stopping

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

มีการโทรกลับในตัวมากมาย

  • 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
617/625 [============================>.] - ETA: 0s - loss: 0.3784 - sparse_categorical_accuracy: 0.8940
Epoch 00001: val_loss improved from inf to 0.22038, saving model to mymodel_1
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.
INFO:tensorflow:Assets written to: mymodel_1/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.3766 - sparse_categorical_accuracy: 0.8946 - val_loss: 0.2204 - val_sparse_categorical_accuracy: 0.9363
Epoch 2/2
595/625 [===========================>..] - ETA: 0s - loss: 0.1721 - sparse_categorical_accuracy: 0.9498
Epoch 00002: val_loss improved from 0.22038 to 0.18707, saving model to mymodel_2
INFO:tensorflow:Assets written to: mymodel_2/assets
625/625 [==============================] - 2s 3ms/step - loss: 0.1708 - sparse_categorical_accuracy: 0.9501 - val_loss: 0.1871 - val_sparse_categorical_accuracy: 0.9453

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

การเรียกกลับ 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
  83/1563 [>.............................] - ETA: 2s - loss: 1.0490 - sparse_categorical_accuracy: 0.7165INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.97/assets
 185/1563 [==>...........................] - ETA: 5s - loss: 0.7407 - sparse_categorical_accuracy: 0.7959INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.72/assets
 286/1563 [====>.........................] - ETA: 5s - loss: 0.6176 - sparse_categorical_accuracy: 0.8253INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.60/assets
 385/1563 [======>.......................] - ETA: 5s - loss: 0.5432 - sparse_categorical_accuracy: 0.8475INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.53/assets
 485/1563 [========>.....................] - ETA: 5s - loss: 0.4909 - sparse_categorical_accuracy: 0.8607INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.48/assets
 585/1563 [==========>...................] - ETA: 4s - loss: 0.4531 - sparse_categorical_accuracy: 0.8713INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.45/assets
 684/1563 [============>.................] - ETA: 4s - loss: 0.4262 - sparse_categorical_accuracy: 0.8788INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.42/assets
 784/1563 [==============>...............] - ETA: 3s - loss: 0.4066 - sparse_categorical_accuracy: 0.8845INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.40/assets
 882/1563 [===============>..............] - ETA: 3s - loss: 0.3863 - sparse_categorical_accuracy: 0.8902INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.38/assets
 985/1563 [=================>............] - ETA: 2s - loss: 0.3682 - sparse_categorical_accuracy: 0.8954INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.37/assets
1084/1563 [===================>..........] - ETA: 2s - loss: 0.3532 - sparse_categorical_accuracy: 0.8993INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.35/assets
1185/1563 [=====================>........] - ETA: 1s - loss: 0.3407 - sparse_categorical_accuracy: 0.9028INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.34/assets
1284/1563 [=======================>......] - ETA: 1s - loss: 0.3287 - sparse_categorical_accuracy: 0.9063INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.33/assets
1385/1563 [=========================>....] - ETA: 0s - loss: 0.3171 - sparse_categorical_accuracy: 0.9095INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.32/assets
1485/1563 [===========================>..] - ETA: 0s - loss: 0.3090 - sparse_categorical_accuracy: 0.9116INFO:tensorflow:Assets written to: ./ckpt/ckpt-loss=0.31/assets
1563/1563 [==============================] - 8s 5ms/step - loss: 0.3018 - sparse_categorical_accuracy: 0.9136

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

นอกจากนี้คุณยังเขียนการโทรกลับของคุณเองเพื่อบันทึกและกู้คืนโมเดล

สำหรับคำแนะนำที่สมบูรณ์เกี่ยวกับการทำให้เป็นอนุกรมและการประหยัดให้ดู คำแนะนำเกี่ยวกับการบันทึกและการทำให้เป็นอนุกรมรุ่น

การใช้ตารางอัตราการเรียนรู้

รูปแบบทั่วไปในการฝึกโมเดลการเรียนรู้เชิงลึกคือการค่อยๆลดการเรียนรู้ลงเมื่อการฝึกดำเนินไป สิ่งนี้เป็นที่รู้จักกันโดยทั่วไปในชื่อ "การลดอัตราการเรียนรู้"

กำหนดการสลายการเรียนรู้อาจเป็นแบบคงที่ (กำหนดไว้ล่วงหน้าเป็นฟังก์ชันของยุคปัจจุบันหรือดัชนีชุดงานปัจจุบัน) หรือแบบไดนามิก (ตอบสนองต่อพฤติกรรมปัจจุบันของโมเดลโดยเฉพาะอย่างยิ่งการสูญเสียการตรวจสอบความถูกต้อง)

ส่งต่อกำหนดการไปยังเครื่องมือเพิ่มประสิทธิภาพ

คุณสามารถใช้กำหนดการสลายอัตราการเรียนรู้แบบคงที่ได้อย่างง่ายดายโดยส่งวัตถุกำหนดการเป็นอาร์กิวเมนต์ 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 ซึ่งเป็นแอปพลิเคชันบนเบราว์เซอร์ที่คุณสามารถเรียกใช้ภายในเครื่องที่ให้คุณ:

  • แปลงสดของการสูญเสียและตัวชี้วัดสำหรับการฝึกอบรมและการประเมินผล
  • (เป็นทางเลือก) การแสดงภาพฮิสโตแกรมของการเปิดใช้งานเลเยอร์ของคุณ
  • (เป็นทางเลือก) การแสดงภาพ 3 มิติของพื้นที่การฝังที่เรียนรู้โดยเลเยอร์การ Embedding ของคุณ

หากคุณติดตั้ง TensorFlow ด้วย pip คุณควรจะสามารถเปิดใช้ TensorBoard จากบรรทัดคำสั่ง:

 tensorboard --logdir=/full_path_to_your_logs
 

ใช้การเรียกกลับ TensorBoard

วิธีที่ง่ายที่สุดในการใช้ TensorBoard กับรุ่น Keras และวิธีการที่พอดีคือการโทรกลับ TensorBoard

ในกรณีที่ง่ายที่สุดเพียงระบุตำแหน่งที่คุณต้องการให้ติดต่อกลับเพื่อเขียนบันทึกและคุณก็พร้อมที่จะไป:

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

สำหรับข้อมูลเพิ่มเติมดู เอกสารประกอบสำหรับการโทรกลับ TensorBoard