我目前正在开展一个项目,该项目需要我在使用 Tensorflow 进行训练期间更改模型架构的一半。添加了新的权重,并删除了其他权重。该模型需要重新编译,以便优化器识别新的权重并为它们计算梯度。
但是我注意到,在编译网络后,损失仅在再次下降后才飙升(见此处)在编译后的第一步中,损失仍然与以前一样低,但它会迅速增加。 这个问题与我的类似,但只说你应该
使用来自先前训练的列表(手动或从 Callback 获得)初始化第二次训练验证准确度。
但我找不到任何关于如何做到这一点的资源。我的尝试包括:
- 使用 SGD 代替 Adam,因为它不应该依赖于之前的状态
model.fit()
添加上一次通话的历史记录- 设置
model._train_counter
为在上一次调用中执行的 epoch 数 - 以上所有结合
我使用来自https://www.tensorflow.org/datasets/keras_example的修改示例重新创建了问题,并增加了网络复杂性,因为尖峰的高度似乎随着网络规模的增加而增加:
import tensorflow as tf
import tensorflow_datasets as tfds
import matplotlib.pyplot as plt
(ds_train, ds_test), ds_info = tfds.load(
'cifar10',
split=['train', 'test'],
shuffle_files=True,
as_supervised=True,
with_info=True,
)
def normalize_img(image, label):
"""Normalizes images: `uint8` -> `float32`."""
return tf.cast(image, tf.float32) / 255., label
ds_train = ds_train.map(
normalize_img, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds_train = ds_train.cache()
ds_train = ds_train.shuffle(ds_info.splits['train'].num_examples)
ds_train = ds_train.batch(256)
ds_train = ds_train.prefetch(tf.data.experimental.AUTOTUNE).repeat()
ds_test = ds_test.map(
normalize_img, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds_test = ds_test.batch(256)
ds_test = ds_test.cache()
ds_test = ds_test.prefetch(tf.data.experimental.AUTOTUNE)
#%% Define Model
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512,activation='relu'),
tf.keras.layers.Dense(256,activation='relu'),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(10)
])
#%% First compilation
model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
)
history1 = model.fit(
ds_train,
epochs=8,
steps_per_epoch=300,
validation_data=ds_test,
)
#%% Compile again
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
)
history2 = model.fit(
ds_train,
epochs=10,
steps_per_epoch=1,
validation_data=ds_test,
)
#%% plot results
plt.plot(history1.history['loss']+history2.history['loss'])
plt.show()
这是结果图。在此示例中,我没有更改网络,而是使用不同的优化器进行编译,无论您选择哪种组合,我都测试了损失峰值。(如果您在不更改模型的情况下使用 model.optimizer 进行编译,损失不会增加,这让我觉得我必须更改优化器。但是 SGD 也不起作用,这让我感到困惑)
model.fit()
这与使用另一个调用恢复后恢复模型训练的问题相同。
我正在使用 TensorFlow 2.5.0 版
有关如何解决或解决此问题的任何想法?