回调函数:
inputs = tf.keras.Input(shape=(32,)) #(batch_size=32,数据维度32),shape为改成接受的数据的维度
x = tf.keras.layers.Dense(64, activation='relu')(inputs) #(64个神经元,)
x = tf.keras.layers.Dense(64, activation='relu')(x)#(63个神经元)
predictions = tf.keras.layers.Dense(10)(x) #(输出是10类)
#- inputs(模型输入)
#- output(模型输出)
model = tf.keras.Model(inputs=inputs, outputs=predictions)
#指定损失函数 (loss) tf.keras.optimizers.RMSprop
#优化器 (optimizer) tf.keras.losses.SparseCategoricalCrossentropy
#指标 (metrics) ['accuracy']
model.compile(optimizer=tf.keras.optimizers.Adam(0.001), #优化器
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), #损失函数
metrics=['accuracy']) #评估函数
常用的优化器和损失函数:
https://www.tensorflow.org/guide/keras/train_and_evaluate#many_built-in_optimizers_losses_and_metrics_are_availablewww.tensorflow.org优化器:
损失:
指标:
另外,如果想用上述的默认设置,那么在很多情况下,可以通过字符串标识符指定优化器,损失和指标:
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
构建数据集:
import numpy as np
x_train = np.random.random((1000, 32))
y_train = np.random.randint(10, size=(1000, ))
x_val = np.random.random((200, 32))
y_val = np.random.randint(10, size=(200, ))
x_test = np.random.random((200, 32))
y_test = np.random.randint(10, size=(200, ))
model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data= (x_val, y_val))
Help on method fit in module tensorflow.python.keras.engine.training:
fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None, validation_freq=1, max_queue_size=10, workers=1, use_multiprocessing=False, **kwargs) method of tensorflow.python.keras.engine.training.Model instance
模型验证:
# Evaluate the model on the test data using `evaluate`
print('n# 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('n# Generate predictions for 3 samples')
predictions = model.predict(x_test[:3])
print('predictions shape:', predictions.shape)
输出信息:
sample - loss: 2.3384 - accuracy: 0.0800
test loss, test acc: [2.3240616512298584, 0.08]
# Generate predictions for 3 samples
predictions shape: (3, 10)
Optional dictionary mapping class indices (integers) to a weight (float) value, used for weighting the loss function (during training only). This can be useful to tell the model to "pay more attention" to samples from an under-represented class.
除了输入数据和目标数据外,还可以在使用时将样本权重或类权重传递给模型fit:
从Numpy数据进行训练时:通过sample_weight和class_weight参数。 从数据集训练时:通过使数据集返回一个元组(input_batch, target_batch, sample_weight_batch)。 “样本权重”数组是一个数字数组,用于指定批次中每个样本在计算总损失时应具有的权重。它通常用于不平衡的分类问题中(这种想法是为很少见的班级赋予更多的权重)。当所使用的权重为1和0时,该数组可用作损失函数的掩码(完全丢弃某些样本对总损失的贡献)。
“类别权重”字典是同一概念的一个更具体的实例:它将类别索引映射到应该用于属于该类别的样本的样本权重。例如,如果在数据中类“ 0”的表示量比类“ 1”的表示量少两倍,则可以使用class_weight={0: 1., 1: 0.5}。
这是一个Numpy示例,其中我们使用类权重或样本权重来更加 重视第5类的正确分类。
先构建模型:
def get_uncompiled_model():
inputs = tf.keras.Input(shape=(32,), name='digits')
x = tf.keras.layers.Dense(64, activation='relu', name='dense_1')(inputs)
x = tf.keras.layers.Dense(64, activation='relu', name='dense_2')(x)
outputs = tf.keras.layers.Dense(10, name='predictions')(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
return model
def get_compiled_model():
model = get_uncompiled_model()
model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-3),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['sparse_categorical_accuracy'])
return model
模型训练:
import numpy as np
#类别5:加权
class_weight = {0: 1., 1: 1., 2: 1., 3: 1., 4: 1.,
5: 2.,
6: 1., 7: 1., 8: 1., 9: 1.}
print('Fit with class weight')
model = get_compiled_model()
model.fit(x_train, y_train,
class_weight=class_weight,
batch_size=64,
epochs=4)
样本加权:
# Here's the same example using `sample_weight` instead:
sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.
print('nFit with sample weight')
model = get_compiled_model()
model.fit(x_train, y_train,
sample_weight=sample_weight,
batch_size=64,
epochs=4)
Keras中的回调是 在训练期间(在某个时期开始时,在批处理结束时,在某个时期结束时等)在不同时间点调用的对象,这些对象可用于实现以下行为:
在训练过程中的不同时间点进行验证(除了内置的按时间段验证)
定期或在超过特定精度阈值时对模型进行检查
当训练似乎停滞不前时,更改模型的学习率
当训练似乎停滞不前时,对顶层进行微调
在训练结束或超出特定性能阈值时发送电子邮件或即时消息通知 等等。 回调可以作为列表传递给model.fit:
model = get_compiled_model()
#list
callbacks = [
tf.keras.callbacks.EarlyStopping(
# 当‘val_loss’不再下降时候停止训练
monitor='val_loss',
# “不再下降”被定义为“减少不超过1e-2”
min_delta=1e-2,
# “不再改善”进一步定义为“至少2个epoch”
patience=2,
verbose=1)
]
model.fit(x_train, y_train,
epochs=20,
batch_size=64,
callbacks=callbacks,
validation_split=0.2)
在相对较大的数据集上训练模型时,至关重要的是要定期保存模型的checkpoint。
最简单的方法是使用ModelCheckpoint回调:
model = get_compiled_model()
callbacks = [
tf.keras.callbacks.ModelCheckpoint(
filepath='mymodel_{epoch}',
# 模型保存路径
#
# 下面的两个参数意味着当且仅当`val_loss`分数提高时,我们才会覆盖当前检查点。
save_best_only=True,
monitor='val_loss',
#加入这个仅仅保存模型权重
save_weights_only=True,
verbose=1)
]
model.fit(x_train, y_train,
epochs=3,
batch_size=64,
callbacks=callbacks,
validation_split=0.2)
使用回调实现动态学习率调整:
由于优化程序无法访问验证指标,因此无法使用这些计划对象来实现动态学习率计划(例如,当验证损失不再改善时降低学习率)。
但是,回调确实可以访问所有指标,包括验证指标!因此,可以通过使用回调来修改优化程序上的当前学习率,从而实现此模式。实际上,它是作为ReduceLROnPlateau回调内置的。
ReduceLROnPlateau参数
model = get_compiled_model()
callbacks = [
tf.keras.callbacks.ModelCheckpoint(
filepath='mymodel_{epoch}',
# 模型保存路径
# 下面的两个参数意味着当且仅当`val_loss`分数提高时,我们才会覆盖当前检查点。
save_best_only=True,
monitor='val_loss',
#加入这个仅仅保存模型权重
save_weights_only=True,
verbose=1),
tf.keras.callbacks.ReduceLROnPlateau(monitor="val_sparse_categorical_accuracy",
verbose=1,
mode='max',
factor=0.5,
patience=3)
]
model.fit(x_train, y_train,
epochs=30,
batch_size=64,
callbacks=callbacks,
validation_split=0.2
)
在前面的示例中,我们正在考虑一个具有单个输入(shape的张量(32,))和单个输出(shape的预测张量(10,))的模型。但是具有多个输入或输出的模型呢?
考虑以下模型,该模型具有形状的图像输入(32, 32, 3)(即(height, width, channels))和形状的时间序列输入(None, 10)(即(timesteps, features))。我们的模型将具有根据这些输入的组合计算出的两个输出:“得分”(形状(1,))和五类(形状(5,))的概率分布。
image_input = tf.keras.Input(shape=(32, 32, 3), name='img_input')
timeseries_input = tf.keras.Input(shape=(20, 10), name='ts_input')
x1 = tf.keras.layers.Conv2D(3, 3)(image_input)
x1 = tf.keras.layers.GlobalMaxPooling2D()(x1)
x2 = tf.keras.layers.Conv1D(3, 3)(timeseries_input)
x2 = tf.keras.layers.GlobalMaxPooling1D()(x2)
x = tf.keras.layers.concatenate([x1, x2])
score_output = tf.keras.layers.Dense(1, name='score_output')(x)
class_output = tf.keras.layers.Dense(5, name='class_output')(x)
model = tf.keras.Model(inputs=[image_input, timeseries_input],
outputs=[score_output, class_output])
接下来在编译时,通过将损失函数作为列表传递,我们可以为不同的输出指定不同的损失:
metrics列表包含评估模型在训练和测试时的性能指标,可以是:
tensorflow.python.keras.metrics.AUC
tensorflow.python.keras.metrics.MeanIoU
tensorflow.python.keras.metrics.MeanTensor
tensorflow.python.keras.metrics.Precision
tensorflow.python.keras.metrics.Recall
tensorflow.python.keras.metrics.Accuracy
tensorflow.python.keras.metrics.BinaryAccuracy
tensorflow.python.keras.metrics.BinaryCrossentropy
tensorflow.python.keras.metrics.CategoricalAccuracy
tensorflow.python.keras.metrics.CategoricalCrossentropy
tensorflow.python.keras.metrics.CategoricalHinge
tensorflow.python.keras.metrics.CosineSimilarity
tensorflow.python.keras.metrics.Hinge
tensorflow.python.keras.metrics.KLDivergence
等。
还可以为它们加上名字,以字典形式表示:
model.compile(
optimizer=tf.keras.optimizers.RMSprop(1e-3),
loss={'score_output': tf.keras.losses.MeanSquaredError(),
'class_output': tf.keras.losses.CategoricalCrossentropy(from_logits=True)},
metrics={'score_output': [tf.keras.metrics.MeanAbsolutePercentageError(),
tf.keras.metrics.MeanAbsoluteError()],
'class_output': [tf.keras.metrics.CategoricalAccuracy()]},
loss_weights={'score_output': 2., 'class_output': 1.})
也可以选择不为某些输出计算损失,如果这些输出仅用于预测而不是训练:
# List loss version
model.compile(
optimizer=tf.keras.optimizers.RMSprop(1e-3),
loss=[None, tf.keras.losses.CategoricalCrossentropy(from_logits=True)])
# Or dict loss version
model.compile(
optimizer=tf.keras.optimizers.RMSprop(1e-3),
loss={'class_output':tf.keras.losses.CategoricalCrossentropy(from_logits=True)})
定义模型:
image_input = tf.keras.Input(shape=(32, 32, 3), name='img_input')
timeseries_input = tf.keras.Input(shape=(20, 10), name='ts_input')
x1 = tf.keras.layers.Conv2D(3, 3)(image_input)
x1 = tf.keras.layers.GlobalMaxPooling2D()(x1)
x2 = tf.keras.layers.Conv1D(3, 3)(timeseries_input)
x2 = tf.keras.layers.GlobalMaxPooling1D()(x2)
x = tf.keras.layers.concatenate([x1, x2])
score_output = tf.keras.layers.Dense(1, name='score_output')(x)
class_output = tf.keras.layers.Dense(5, name='class_output')(x)
model = tf.keras.Model(inputs=[image_input, timeseries_input],
outputs=[score_output, class_output])
编译和训练:
model.compile(
optimizer=tf.keras.optimizers.RMSprop(1e-3),
loss=[tf.keras.losses.MeanSquaredError(),
tf.keras.losses.CategoricalCrossentropy(from_logits=True)])
# Generate dummy Numpy data
import numpy as np
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=3)
# 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=3)
# Alternatively, fit on dicts
model.fit((img_data, ts_data),
(score_targets, class_targets),
batch_size=32,
epochs=3)