我在从喀拉拉邦生成的TF估算器上遇到问题。我已添加一个SessionRunHook以显示正在运行的步骤。 Evaluate()和predict()都运行正确的步数,但是train()仅运行我告诉它的步数的一半,例如如果为2个时期指定足够的步骤,它将运行1。如果为4个时期指定足够的步骤,它将运行2。
这是相关的代码片段。首先是我的输入功能。我将相同的输入函数用于训练,评估和预测:
def input_function(features, labels=None, shuffle=False, batch_size=batch_size, num_epochs=1):
input_fn = tf.estimator.inputs.numpy_input_fn(
x={model.input_names[0] : features},
y=labels,
batch_size=batch_size,
num_epochs=num_epochs,
shuffle=shuffle)
return input_fn
这就是我所说的训练:
steps = np.ceil((nb_epoch * np.ceil(X_train.shape[0] / batch_size).astype(np.int32)) / num_gpus).astype(np.int32)
print(" Steps : ", steps, "\n")
time_hist = TimeHistory(num_steps = steps, stage_name='Training')
est_model.train(input_fn=input_function(X_train, y_train, shuffle=True,
num_epochs=nb_epoch), steps=steps, hooks=[time_hist])
time_hist是我的SessionRunHook,基本上可以计算步骤和打印进度。因此,当我对数据集进行训练时,我得到:
TRAINING MODEL
Training dataset size : 39209
Batch size : 128
Epochs : 2
Num GPUs : 1
Steps : 614
Begin Training ...
Step : 10 / 614
Step : 20 / 614
...
Step : 290 / 614
Step : 300 / 614
Training finished.
total time : 25.3624458313
avg batch time : 0.08234560334837282
num steps : 308
因此,它计算出(正确地)花费了614个步骤才能在39209个元素的数据集上运行128个batch_size的2个纪元。我将steps = 614传递给train(),但它只能运行308步!
当我运行评估时,它工作正常:
eval_steps = np.ceil((np.ceil(X_test.shape[0] / batch_size).astype(np.int32)) / num_gpus).astype(np.int32)
time_hist = TimeHistory(num_steps = eval_steps, stage_name='Testing')
score = est_model.evaluate(input_fn=input_function(X_test, y_test, shuffle=False), steps=eval_steps, hooks=[time_hist])
我得到:
TESTING MODEL
Test dataset size : 12630
Begin Testing ...
Step : 10 / 99
...
Step : 80 / 99
Step : 90 / 99
Testing finished. total time : 3.7828950882
avg batch time : 0.03821106149692728
num steps : 99
Test score : {'loss': 0.63948023, 'global_step': 616, 'accuracy': 0.8405659}
任何人都可以看看我在做什么错吗?使我抓狂! :)
更新:经过进一步调试(请参阅下面的注释),Tensorboard似乎告诉我它已按预期运行了616个步骤,但SessionRunHook仅计算了一半。 SessionRunHook是否可能仅每隔第二步运行一次?这里的input_fn num_epochs,火车步和张量板global_step之间确实有些混淆。嗯...
Update2:我添加了一些代码以在钩子中打印global_step_value,现在看起来像:
Begin Training ...
Step : 10 / 1228
global_step : 20
Step : 20 / 1228
global_step : 40
Step : 30 / 1228
global_step : 60
...
因此,鉴于global_step是该图看到的批次数,看来我在钩子中计算的步骤之间有些脱节。看起来该钩子仅在第二个global_step中被调用。嗯
谢谢, 保罗