当我多次训练一个模型时,训练迭代会减慢,即使所有相关数量都是在for
循环内创建的(因此每次都应该被覆盖,这应该足以避免创建不断增长的计算图或填满内存或任何)。
这是我使用的代码:
import numpy as np
import tensorflow as tf
import time
n_samples = 300000
n_features = 100
n_targets = 5
batch_size = 100
x = np.array(range(n_samples * n_features), dtype=np.float64).reshape((n_samples, n_features))
y = np.array(range(n_samples * n_targets), dtype=np.float64).reshape((n_samples, n_targets))
for t_idx in range(10):
dataset = [x, y]
dataset = tf.data.Dataset.from_tensor_slices(tuple(dataset)).shuffle(n_samples).repeat().batch(batch_size=batch_size).prefetch(tf.data.experimental.AUTOTUNE)
data_iterator = iter(dataset)
inputs = tf.keras.Input(shape=(n_features,), name='input')
outputs = tf.keras.layers.Dense(n_features, name='dense_1', activation=tf.keras.activations.relu)(inputs)
outputs = tf.keras.layers.Dense(n_features, name='dense_2', activation=tf.keras.activations.relu)(outputs)
outputs = tf.keras.layers.Dense(n_features, name='dense_3', activation=tf.keras.activations.relu)(outputs)
outputs = tf.keras.layers.Dense(n_features, name='dense_4', activation=tf.keras.activations.relu)(outputs)
outputs = tf.keras.layers.Dense(n_targets, name='output', activation=tf.keras.activations.linear)(outputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
trainable_variables = list(model.trainable_variables)
adam_opt = tf.optimizers.Adam(learning_rate=0.001)
@tf.function
def loss(batch):
x_, y_ = batch
y_pred_ = model(x_)
return tf.keras.losses.MSE(y_pred_, y_)
@tf.function
def optimization_step():
batch = next(data_iterator)
def f(): return loss(batch)
adam_opt.minimize(f, var_list=trainable_variables)
iterations = 50000
loop_start = time.time()
optimization_times = []
for idx in range(iterations):
optimization_step()
loop_end = time.time()
print(f'Elapsed: {loop_end - loop_start}')
我知道我可以model.fit()
用来训练模型,但这不是我的选择(上面的代码是通过剥离更复杂的代码获得的,我唯一的选择是直接调用优化器)。
输出:
Elapsed: 49.798316955566406
Elapsed: 55.18571472167969
Elapsed: 58.57510209083557
Elapsed: 64.41855955123901
Elapsed: 66.76858448982239
Elapsed: 68.3305652141571
Elapsed: 67.73438382148743
Elapsed: 69.73751258850098
Elapsed: 73.59102845191956
Elapsed: 73.14124798774719
我预计每次训练所用的时间大致相同,但有明显的上升趋势。我究竟做错了什么?
系统信息
- 操作系统:Windows 10
- 蟒蛇版本:3.7.9
- 张量流版本:2.3.1
编辑
在@Nicolas Gervais 和@M.Innat 的回复之后,我一直在不同机器上试验两个版本的代码(我的和@M.Innat 的)。这是我发现的:
- 在我测试的两台单独的 Windows 机器上(相同的 Windows 版本、相同的包版本、相同的 python 版本、在干净的 virtualenv 上),结果存在很大差异;两者中最好的仍然显示出训练时间的上升趋势,但比我最初测试的要小;两者中最好的结果如下:
WITH MY CODE:
Elapsed: 49.35429096221924
Elapsed: 52.551310777664185
Elapsed: 54.324320554733276
Elapsed: 56.53233051300049
Elapsed: 56.81632399559021
Elapsed: 58.70533752441406
Elapsed: 59.68834161758423
Elapsed: 61.419353008270264
Elapsed: 60.33834195137024
Elapsed: 62.536344051361084
WITH @M.Innat CODE:
Elapsed: 50.51127886772156
Elapsed: 53.94429612159729
Elapsed: 52.38828897476196
Elapsed: 54.5512957572937
Elapsed: 58.1543083190918
Elapsed: 61.21232509613037
Elapsed: 60.11531925201416
Elapsed: 59.95942974090576
Elapsed: 60.48531889915466
Elapsed: 59.37330341339111
- 如您所见,时间看起来比我最初在第二台 Windows 机器上发布的更稳定(但请注意,当我在用于初始测试的机器上进行测试时,它们基本相同);尽管如此,趋势仍然清晰可见;这很奇怪,因为@M.Innit 发布的结果中没有发生这种情况;
- 在 Linux 或 Mac OS 上都不会出现此问题。
我开始觉得这是 Tensorflow 中的一个错误,不知何故(即使具有相同确切配置的不同机器产生如此不同的结果很奇怪),但我真的不知道将此行为归因于什么