Trang này được dịch bởi Cloud Translation API.
Switch to English

Đào tạo & amp; đánh giá với các phương pháp tích hợp

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải vở

Thiết lập

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

Giới thiệu

Hướng dẫn này bao gồm các mô hình đào tạo, đánh giá và dự đoán (suy luận) khi sử dụng API tích hợp để đào tạo & xác nhận (như model.fit() , model.evaluate() , model.predict() ).

Nếu bạn quan tâm đến việc tận dụng fit() trong khi chỉ định chức năng bước đào tạo của riêng bạn, hãy xem hướng dẫn "tùy chỉnh những gì xảy ra trong fit() " .

Nếu bạn quan tâm đến việc viết các vòng lặp đào tạo và đánh giá của riêng bạn từ đầu, hãy xem hướng dẫn "viết một vòng lặp đào tạo từ đầu" .

Nói chung, cho dù bạn đang sử dụng các vòng lặp tích hợp sẵn hay tự viết, đào tạo và đánh giá mô hình hoạt động theo cùng một cách trên mọi loại mô hình Keras - Mô hình tuần tự, mô hình được xây dựng bằng API chức năng và mô hình được viết từ đầu qua phân lớp mô hình.

Hướng dẫn này không bao gồm đào tạo phân tán. Đối với đào tạo phân tán, hãy xem hướng dẫn của chúng tôi về đào tạo đa gpu & phân tán .

Tổng quan về API: ví dụ từ đầu đến cuối

Khi truyền dữ liệu đến các vòng huấn luyện tích hợp sẵn của một mô hình, bạn nên sử dụng mảng NumPy (nếu dữ liệu của bạn nhỏ và vừa với bộ nhớ) hoặc các đối tượng tf.data Dataset . Trong một vài đoạn tiếp theo, chúng tôi sẽ sử dụng bộ dữ liệu MNIST dưới dạng mảng NumPy, để trình bày cách sử dụng tối ưu hóa, tổn thất và số liệu.

Hãy xem xét mô hình sau (ở đây, chúng tôi xây dựng với API chức năng, nhưng nó cũng có thể là mô hình Tuần tự hoặc mô hình phân lớp):

 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)
 

Đây là quy trình công việc từ đầu đến cuối điển hình trông như thế nào, bao gồm:

  • Đào tạo
  • Xác thực trên một bộ nắm giữ được tạo từ dữ liệu đào tạo ban đầu
  • Đánh giá về dữ liệu thử nghiệm

Chúng tôi sẽ sử dụng dữ liệu MNIST cho ví dụ này.

 (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

Chúng tôi chỉ định cấu hình đào tạo (trình tối ưu hóa, mất mát, số liệu):

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

Chúng tôi gọi fit() , sẽ huấn luyện mô hình bằng cách cắt dữ liệu thành "lô" có kích thước "batch_size" và lặp đi lặp lại trên toàn bộ tập dữ liệu cho một số "epoch" nhất định.

 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

Đối tượng "history" được trả về giữ bản ghi các giá trị mất mát và giá trị chỉ số trong quá trình huấn luyện:

 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]}

Chúng tôi đánh giá mô hình trên dữ liệu thử nghiệm thông qua 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)

Bây giờ, hãy xem xét chi tiết từng phần của quy trình làm việc này.

Phương thức compile() : chỉ định lỗ, số liệu và trình tối ưu hóa

Để đào tạo một mô hình với fit() , bạn cần chỉ định một hàm mất mát, một trình tối ưu hóa và tùy chọn một số chỉ số cần theo dõi.

Bạn truyền những thứ này cho mô hình dưới dạng đối số cho phương thức compile() :

 model.compile(
    optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
    loss=keras.losses.SparseCategoricalCrossentropy(),
    metrics=[keras.metrics.SparseCategoricalAccuracy()],
)
 

Đối metrics phải là một danh sách - mô hình của bạn có thể có bất kỳ số lượng số liệu nào.

Nếu mô hình của bạn có nhiều đầu ra, bạn có thể chỉ định tổn thất và số liệu khác nhau cho từng đầu ra và bạn có thể điều chỉnh đóng góp của từng đầu ra vào tổng tổn thất của mô hình. Bạn sẽ tìm thấy nhiều chi tiết hơn về điều này trong phần "Truyền dữ liệu cho các mô hình đa đầu vào, đa đầu ra" .

Lưu ý rằng nếu bạn hài lòng với các cài đặt mặc định, trong nhiều trường hợp, trình tối ưu hóa, mất và số liệu có thể được chỉ định thông qua số nhận dạng chuỗi dưới dạng phím tắt:

 model.compile(
    optimizer="rmsprop",
    loss="sparse_categorical_crossentropy",
    metrics=["sparse_categorical_accuracy"],
)
 

Để sử dụng lại sau này, hãy đặt định nghĩa mô hình và bước biên dịch của chúng ta trong các hàm; chúng tôi sẽ gọi chúng nhiều lần qua các ví dụ khác nhau trong hướng dẫn này.

 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

 

Nhiều trình tối ưu hóa, tổn thất và số liệu được tích hợp sẵn có sẵn

Nói chung, bạn sẽ không phải tạo ra từ đầu những mất mát, số liệu hoặc tối ưu hóa của riêng bạn, bởi vì những gì bạn cần có thể đã là một phần của API Keras:

Tối ưu hóa:

  • SGD() (có hoặc không có xung lượng)
  • RMSprop()
  • Adam()
  • Vân vân.

Lỗ vốn:

  • MeanSquaredError()
  • KLDivergence()
  • CosineSimilarity()
  • Vân vân.

Số liệu:

  • AUC()
  • Precision()
  • Recall()
  • Vân vân.

Tổn thất tùy chỉnh

Có hai cách để cung cấp tổn thất tùy chỉnh với Keras. Ví dụ đầu tiên tạo một hàm chấp nhận đầu vào y_truey_pred . Ví dụ sau đây cho thấy một hàm mất mát tính toán sai số trung bình bình phương giữa dữ liệu thực và các dự đoán:

 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>

Nếu bạn cần một hàm mất có các tham số bên cạnh y_truey_pred , bạn có thể phân lớp lớp tf.keras.losses.Loss và thực hiện hai phương thức sau:

  • __init__(self) : chấp nhận tham số để truyền trong khi gọi hàm mất của bạn
  • call(self, y_true, y_pred) : sử dụng các mục tiêu (y_true) và dự đoán mô hình (y_pred) để tính toán tổn thất của mô hình

Giả sử bạn muốn sử dụng lỗi bình phương trung bình, nhưng với một thuật ngữ được thêm vào sẽ làm giảm giá trị dự đoán xa 0,5 (chúng tôi giả định rằng các mục tiêu phân loại được mã hóa một lần và nhận các giá trị từ 0 đến 1). Điều này tạo ra một động lực cho mô hình không quá tự tin, điều này có thể giúp giảm quá mức (chúng tôi sẽ không biết nếu nó hoạt động cho đến khi chúng tôi thử!).

Đây là cách bạn sẽ làm điều đó:

 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>

Chỉ số tùy chỉnh

Nếu bạn cần một số liệu không phải là một phần của API, bạn có thể dễ dàng tạo các số liệu tùy chỉnh bằng cách phân lớp con của lớp tf.keras.metrics.Metric . Bạn sẽ cần thực hiện 4 phương pháp:

  • __init__(self) , trong đó bạn sẽ tạo các biến trạng thái cho số liệu của mình.
  • update_state(self, y_true, y_pred, sample_weight=None) , sử dụng mục tiêu y_true và dự đoán mô hình y_pred để cập nhật các biến trạng thái.
  • result(self) , sử dụng các biến trạng thái để tính kết quả cuối cùng.
  • reset_states(self) , khởi động lại trạng thái của chỉ số.

Cập nhật trạng thái và tính toán kết quả được giữ riêng biệt (tương ứng trong update_state()result() ) vì trong một số trường hợp, việc tính toán kết quả có thể rất tốn kém và chỉ được thực hiện định kỳ.

Dưới đây là một ví dụ đơn giản cho thấy cách triển khai số liệu CategoricalTruePositives , đếm số lượng mẫu đã được phân loại chính xác là thuộc một lớp nhất định:

 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>

Xử lý tổn thất và số liệu không phù hợp với chữ ký tiêu chuẩn

Phần lớn tổn thất và chỉ số có thể được tính toán từ y_truey_pred , trong đó y_pred là đầu ra của mô hình của bạn. Nhưng không phải tất cả trong số họ. Ví dụ, một mất mát chính quy có thể chỉ yêu cầu kích hoạt một lớp (không có mục tiêu trong trường hợp này) và kích hoạt này có thể không phải là đầu ra của mô hình.

Trong những trường hợp như vậy, bạn có thể gọi self.add_loss(loss_value) từ bên trong phương thức gọi của một lớp tùy chỉnh. Các tổn thất được thêm vào theo cách này được thêm vào tổn thất "chính" trong quá trình đào tạo (một mất mát được compile() ). Dưới đây là một ví dụ đơn giản bổ sung quy định hoạt động (lưu ý rằng quy định hoạt động được tích hợp sẵn trong tất cả các lớp Keras - lớp này chỉ nhằm mục đích cung cấp một ví dụ cụ thể):

 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>

Bạn có thể làm tương tự để ghi nhật ký các giá trị chỉ số, sử dụng 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>

Trong API chức năng , bạn cũng có thể gọi model.add_loss(loss_tensor) hoặc model.add_metric(metric_tensor, name, aggregation) .

Đây là một ví dụ đơn giản:

 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>

Lưu ý rằng khi bạn chuyển lỗ qua add_loss() , có thể gọi compile() mà không có hàm mất, vì mô hình đã có một tổn thất để giảm thiểu.

Hãy xem xét lớp LogisticEndpoint sau: nó lấy làm mục tiêu & logits đầu vào và nó theo dõi sự mất mát add_loss() qua add_loss() . Nó cũng theo dõi độ chính xác của phân loại thông qua 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)

 

Bạn có thể sử dụng nó trong một mô hình có hai đầu vào (dữ liệu đầu vào & mục tiêu), được biên dịch mà không có đối số loss , như sau:

 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>

Để biết thêm thông tin về đào tạo các mô hình đa đầu vào, hãy xem phần Truyền dữ liệu cho các mô hình đa đầu vào, đa đầu ra .

Tự động thiết lập riêng một bộ lưu trữ xác thực

Trong lần đầu tiên dụ end-to-end bạn đã thấy, chúng tôi sử dụng validation_data lập luận để thông qua một tuple của mảng NumPy (x_val, y_val) với mô hình để đánh giá thiệt hại và số liệu xác nhận xác nhận ở phần cuối của mỗi thời đại.

Đây là một tùy chọn khác: đối số validation_split cho phép bạn tự động dự trữ một phần dữ liệu đào tạo của mình để xác thực. Giá trị đối số biểu thị phần dữ liệu được dành riêng để xác thực, do đó, nó phải được đặt thành một số cao hơn 0 và thấp hơn 1. Ví dụ: validation_split=0.2 có nghĩa là "sử dụng 20% ​​dữ liệu để xác thực" và validation_split=0.6 có nghĩa là "sử dụng 60% dữ liệu để xác thực".

Cách xác thực được tính là bằng cách lấy các mẫu x% cuối cùng của các mảng nhận được bởi lệnh gọi phù hợp, trước khi xáo trộn.

Lưu ý rằng bạn chỉ có thể sử dụng validation_split khi đào tạo với dữ liệu 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>

Đào tạo và đánh giá từ Bộ dữ liệu tf.data

Trong một vài đoạn văn vừa qua, bạn đã nhìn thấy làm thế nào để xử lý các khoản lỗ, số liệu, và tối ưu, và bạn đã nhìn thấy làm thế nào để sử dụng validation_datavalidation_split luận trong phù hợp, khi dữ liệu của bạn được thông qua như là mảng NumPy.

Bây giờ chúng ta hãy xem xét trường hợp dữ liệu của bạn có dạng đối tượng tf.data.Dataset .

API tf.data là một tập hợp các tiện ích trong TensorFlow 2.0 để tải và tiền xử lý dữ liệu theo cách nhanh và có thể mở rộng.

Để có hướng dẫn đầy đủ về cách tạo Tập Datasets , hãy xem tài liệu tf.data .

Bạn có thể truyền trực tiếp một thể hiện Dataset cho các phương thức 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}

Lưu ý rằng Tập dữ liệu được đặt lại ở cuối mỗi kỷ nguyên, do đó, nó có thể được sử dụng lại trong kỷ nguyên tiếp theo.

Nếu bạn chỉ muốn chạy đào tạo trên một số lô cụ thể từ Tập dữ liệu này, bạn có thể chuyển đối số steps_per_epoch , đối số này chỉ định số bước đào tạo mà mô hình sẽ chạy bằng cách sử dụng Tập dữ liệu này trước khi chuyển sang kỷ nguyên tiếp theo.

Nếu bạn làm điều này, bộ dữ liệu sẽ không được đặt lại vào cuối mỗi epoch, thay vào đó chúng tôi chỉ tiếp tục vẽ các lô tiếp theo. Tập dữ liệu cuối cùng sẽ hết dữ liệu (trừ khi nó là tập dữ liệu lặp lại vô hạn).

 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>

Sử dụng tập dữ liệu xác thực

Bạn có thể chuyển một cá thể Dataset làm đối số validation_data trong 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>

Vào cuối mỗi kỷ nguyên, mô hình sẽ lặp lại tập dữ liệu xác thực và tính toán các chỉ số xác thực và mất xác thực.

Nếu bạn chỉ muốn chạy xác thực trên một số lô cụ thể từ tập dữ liệu này, bạn có thể chuyển đối số validation_steps , đối số này chỉ định số bước xác thực mà mô hình sẽ chạy với tập dữ liệu xác thực trước khi gián đoạn xác thực và chuyển sang kỷ nguyên tiếp theo:

 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>

Lưu ý rằng tập dữ liệu xác thực sẽ được đặt lại sau mỗi lần sử dụng (để bạn luôn đánh giá trên các mẫu giống nhau từ kỷ nguyên này sang kỷ nguyên khác).

Đối số validation_split (tạo tập hợp lưu trữ từ dữ liệu huấn luyện) không được hỗ trợ khi đào tạo từ các đối tượng Dataset , vì tính năng này yêu cầu khả năng lập chỉ mục các mẫu của bộ dữ liệu, không thể nói chung với API Dataset .

Các định dạng đầu vào khác được hỗ trợ

Bên cạnh mảng NumPy, tenxơ háo hức và Datasets TensorFlow, có thể đào tạo một mô hình Keras bằng cách sử dụng các tệp dữ liệu Pandas hoặc từ các trình tạo Python tạo ra các lô dữ liệu & nhãn.

Đặc biệt, lớp keras.utils.Sequence cung cấp một giao diện đơn giản để xây dựng trình tạo dữ liệu Python có khả năng nhận biết đa xử lý và có thể xáo trộn.

Nói chung, chúng tôi khuyên bạn nên sử dụng:

  • NumPy dữ liệu đầu vào nếu dữ liệu của bạn nhỏ và vừa trong bộ nhớ
  • Đối tượng bộ Dataset nếu bạn có bộ dữ liệu lớn và bạn cần thực hiện đào tạo phân tán
  • Đối tượng Sequence nếu bạn có bộ dữ liệu lớn và bạn cần thực hiện nhiều xử lý phía Python tùy chỉnh mà không thể thực hiện được trong TensorFlow (ví dụ: nếu bạn dựa vào thư viện bên ngoài để tải dữ liệu hoặc xử lý trước).

Sử dụng một đối tượng keras.utils.Sequence làm đầu vào

keras.utils.Sequence là một tiện ích mà bạn có thể phân lớp để có được trình tạo Python với hai thuộc tính quan trọng:

  • Nó hoạt động tốt với đa xử lý.
  • Nó có thể được xáo trộn (ví dụ: khi truyền shuffle=True in fit() ).

Một Sequence phải triển khai hai phương pháp:

  • __getitem__
  • __len__

Phương thức __getitem__ sẽ trả về một lô hoàn chỉnh. Nếu bạn muốn sửa đổi tập dữ liệu của mình giữa các kỷ nguyên, bạn có thể triển khai on_epoch_end .

Đây là một ví dụ nhanh:

 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)
 

Sử dụng trọng số mẫu và trọng số lớp

Với cài đặt mặc định, trọng lượng của một mẫu được quyết định bởi tần suất của nó trong tập dữ liệu. Có hai phương pháp để cân dữ liệu, không phụ thuộc vào tần số mẫu:

  • Trọng lượng hạng
  • Trọng lượng mẫu

Trọng lượng lớp

Này được thiết lập bằng cách thông qua một cuốn từ điển với class_weight lập luận để Model.fit() . Từ điển này ánh xạ các chỉ số của lớp với trọng lượng sẽ được sử dụng cho các mẫu thuộc lớp này.

Điều này có thể được sử dụng để cân bằng các lớp mà không cần lấy mẫu lại hoặc để huấn luyện một mô hình có tầm quan trọng hơn đối với một lớp cụ thể.

Ví dụ: nếu lớp "0" được biểu thị bằng một nửa dưới dạng lớp "1" trong dữ liệu của bạn, bạn có thể sử dụng Model.fit(..., class_weight={0: 1., 1: 0.5}) .

Dưới đây là ví dụ NumPy trong đó chúng tôi sử dụng trọng số lớp hoặc trọng số mẫu để có tầm quan trọng hơn đối với việc phân loại chính xác của lớp 5 (là chữ số "5" trong bộ dữ liệu của 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>

Trọng lượng mẫu

Để kiểm soát chi tiết hoặc nếu bạn không xây dựng bộ phân loại, bạn có thể sử dụng "trọng số mẫu".

  • Khi huấn luyện từ dữ liệu NumPy: sample_weight đối số Model.fit() đến Model.fit() .
  • Khi đào tạo từ tf.data hoặc bất kỳ loại trình lặp nào khác: Bộ giá trị Yield (input_batch, label_batch, sample_weight_batch) .

Mảng "trọng lượng mẫu" là một mảng số chỉ định khối lượng mỗi mẫu trong một lô phải có để tính toán tổng hao hụt. Nó thường được sử dụng trong các bài toán phân loại không cân bằng (ý tưởng là tạo thêm trọng số cho các lớp hiếm gặp).

Khi trọng số được sử dụng là một và số không, mảng có thể được sử dụng như một mặt nạ cho hàm mất mát (loại bỏ hoàn toàn sự đóng góp của một số mẫu nhất định vào tổng tổn thất).

 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>

Dưới đây là ví dụ về Dataset phù hợp:

 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>

Truyền dữ liệu cho các mô hình đa đầu vào, đa đầu ra

Trong các ví dụ trước, chúng ta đang xem xét một mô hình với một đầu vào duy nhất (một tenxơ hình dạng (764,) ) và một đầu ra duy nhất (một tenxơ dự đoán hình dạng (10,) ). Nhưng những mô hình có nhiều đầu vào hoặc đầu ra thì sao?

Hãy xem xét mô hình sau, có đầu vào hình ảnh có hình dạng (32, 32, 3) (đó là (height, width, channels) ) và đầu vào hình thời gian (None, 10) (đó là (timesteps, features) ). Mô hình của chúng tôi sẽ có hai đầu ra được tính toán từ sự kết hợp của các đầu vào này: "điểm" (của hình dạng (1,) ) và phân phối xác suất trên năm lớp (hình dạng (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]
)
 

Hãy vẽ mô hình này, để bạn có thể thấy rõ những gì chúng tôi đang làm ở đây (lưu ý rằng các hình thể hiện trong biểu đồ là hình dạng lô, chứ không phải hình dạng từng mẫu).

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

png

Tại thời điểm biên dịch, chúng tôi có thể chỉ định các tổn thất khác nhau cho các đầu ra khác nhau, bằng cách chuyển các hàm tổn thất dưới dạng danh sách:

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

Nếu chúng ta chỉ truyền một hàm mất duy nhất cho mô hình, thì hàm mất tương tự sẽ được áp dụng cho mọi đầu ra (không phù hợp ở đây).

Tương tự như vậy đối với số liệu:

 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()],
    ],
)
 

Vì chúng tôi đã đặt tên cho các lớp đầu ra của mình, chúng tôi cũng có thể chỉ định các số liệu và tổn thất trên mỗi đầu ra thông qua một mệnh lệnh:

 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()],
    },
)
 

Chúng tôi khuyên bạn nên sử dụng tên và ký hiệu rõ ràng nếu bạn có nhiều hơn 2 đầu ra.

Có thể đưa ra các trọng số khác nhau cho các tổn thất cụ thể đầu ra khác nhau (ví dụ: người ta có thể muốn ưu tiên tổn thất "điểm số" trong ví dụ của chúng tôi, bằng cách đưa ra mức độ quan trọng của tổn thất lớp loss_weights 2 lần), bằng cách sử dụng đối số 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},
)
 

Bạn cũng có thể chọn không tính toán tổn thất cho các đầu ra nhất định, nếu các đầu ra này có ý nghĩa dự đoán nhưng không phải để đào tạo:

 # 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()},
)
 

Việc truyền dữ liệu đến mô hình nhiều đầu vào hoặc nhiều đầu ra phù hợp hoạt động theo cách tương tự như chỉ định hàm mất trong biên dịch: bạn có thể chuyển danh sách các mảng NumPy (với ánh xạ 1: 1 tới các đầu ra nhận được hàm mất) hoặc dicts ánh xạ tên đầu ra thành mảng 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>

Đây là trường hợp sử dụng Dataset : tương tự như những gì chúng ta đã làm cho mảng NumPy, Dataset sẽ trả về một 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 8ms/step - loss: 9.7058 - score_output_loss: 0.3508 - class_output_loss: 9.3550

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

Sử dụng gọi lại

Callback trong Keras là các đối tượng được gọi tại các điểm khác nhau trong quá trình huấn luyện (khi bắt đầu một kỷ nguyên, cuối một lô, cuối một kỷ nguyên, v.v.) và có thể được sử dụng để thực hiện các hành vi như:

  • Thực hiện xác nhận tại các điểm khác nhau trong quá trình đào tạo (ngoài xác thực tích hợp theo từng epoch)
  • Kiểm tra mô hình theo các khoảng thời gian đều đặn hoặc khi nó vượt quá ngưỡng chính xác nhất định
  • Thay đổi tốc độ học tập của mô hình khi đào tạo dường như là cao nguyên
  • Làm tốt các lớp trên cùng khi đào tạo dường như là cao nguyên
  • Gửi email hoặc thông báo tin nhắn tức thời khi kết thúc đào tạo hoặc khi vượt quá ngưỡng hiệu suất nhất định
  • Vân vân.

Các lệnh gọi lại có thể được chuyển dưới dạng danh sách đến lệnh gọi của bạn để 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>

Nhiều cuộc gọi lại tích hợp sẵn

  • ModelCheckpoint : Lưu mô hình định kỳ.
  • EarlyStopping : Dừng đào tạo khi đào tạo không còn cải thiện các số liệu xác nhận.
  • TensorBoard : định kỳ ghi nhật ký mô hình có thể được trực quan hóa trong TensorBoard (chi tiết hơn trong phần "Hình ảnh hóa").
  • CSVLogger : truyền dữ liệu số liệu và mất mát vào tệp CSV.
  • Vân vân.

Xem tài liệu gọi lại để biết danh sách đầy đủ.

Viết cuộc gọi lại của riêng bạn

Bạn có thể tạo một lệnh gọi lại tùy chỉnh bằng cách mở rộng lớp cơ sở keras.callbacks.Callback . Một lệnh gọi lại có quyền truy cập vào mô hình được liên kết của nó thông qua thuộc tính lớp self.model .

Đảm bảo đọc hướng dẫn đầy đủ để viết lệnh gọi lại tùy chỉnh .

Dưới đây là một ví dụ đơn giản lưu danh sách các giá trị tổn thất theo lô trong quá trình đào tạo:

 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"))

 

Mô hình điểm kiểm tra

Khi bạn đang đào tạo mô hình trên các tập dữ liệu tương đối lớn, điều quan trọng là phải lưu các điểm kiểm tra của mô hình của bạn thường xuyên.

Cách dễ nhất để đạt được điều này là với ModelCheckpoint gọi lại 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 gọi lại ModelCheckpoint có thể được sử dụng để thực hiện khả năng chịu lỗi: khả năng khởi động lại quá trình huấn luyện từ trạng thái đã lưu cuối cùng của mô hình trong trường hợp quá trình huấn luyện bị gián đoạn ngẫu nhiên. Đây là một ví dụ cơ bản:

 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>

Bạn cũng có thể viết lệnh gọi lại của riêng mình để lưu và khôi phục các mô hình.

Để có hướng dẫn đầy đủ về tuần tự hóa và lưu, hãy xem hướng dẫn để lưu và tuần tự hóa Mô hình .

Sử dụng lịch trình tỷ lệ học tập

Mô hình phổ biến khi đào tạo mô hình học sâu là giảm dần việc học khi quá trình đào tạo tiến triển. Điều này thường được gọi là "giảm tốc độ học tập".

Lịch trình phân rã học tập có thể là tĩnh (cố định trước, như là một chức năng của kỷ nguyên hiện tại hoặc chỉ số lô hiện tại) hoặc động (phản ứng với hành vi hiện tại của mô hình, đặc biệt là mất xác thực).

Chuyển lịch trình cho trình tối ưu hóa

Bạn có thể dễ dàng sử dụng lịch phân rã tốc độ học tập tĩnh bằng cách chuyển một đối tượng lịch biểu làm đối số learning_rate trong trình tối ưu hóa của bạn:

 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)
 

Một số lịch trình tích hợp có sẵn: ExponentialDecay , PiecewiseConstantDecay , PolynomialDecayInverseTimeDecay .

Sử dụng các cuộc gọi lại để thực hiện một lịch trình tỷ lệ học tập năng động

Không thể đạt được lịch biểu tốc độ học tập động (ví dụ: giảm tốc độ học tập khi mất xác thực không còn được cải thiện) với các đối tượng lịch biểu này vì trình tối ưu hóa không có quyền truy cập vào số liệu xác thực.

Tuy nhiên, các lệnh gọi lại có quyền truy cập vào tất cả các chỉ số, bao gồm cả chỉ số xác thực! Do đó, bạn có thể đạt được mô hình này bằng cách sử dụng một cuộc gọi lại sửa đổi tốc độ học tập hiện tại trên trình tối ưu hóa. Trong thực tế, điều này thậm chí còn được tích hợp dưới dạng gọi lại ReduceLROnPlateau .

Hình dung tổn thất và các số liệu trong quá trình đào tạo

Cách tốt nhất để theo dõi mô hình của bạn trong quá trình đào tạo là sử dụng TensorBoard , một ứng dụng dựa trên trình duyệt mà bạn có thể chạy cục bộ cung cấp cho bạn:

  • Âm mưu sống của sự mất mát và số liệu cho đào tạo và đánh giá
  • (tùy chọn) Trực quan hóa biểu đồ kích hoạt lớp của bạn
  • (tùy chọn) trực quan hóa 3D các không gian nhúng được học bởi các lớp Embedding của bạn

Nếu bạn đã cài đặt TensorFlow bằng pip, bạn sẽ có thể khởi chạy TensorBoard từ dòng lệnh:

 tensorboard --logdir=/full_path_to_your_logs
 

Sử dụng hàm gọi lại TensorBoard

Cách dễ nhất để sử dụng TensorBoard với mô hình Keras và phương thức phù hợp là gọi lại TensorBoard .

Trong trường hợp đơn giản nhất, chỉ cần xác định nơi bạn muốn gọi lại để ghi nhật ký và bạn sẽ ổn:

 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>

Để biết thêm thông tin, hãy xem tài liệu cho cuộc gọi lại TensorBoard .