我有一个Keras模型,可以在单个GPU上进行很好的训练,但是当我在多个GPU上进行训练时,返回的所有验证损失都是NaN。
我正在使用fit_generator并调用验证生成器。当在一个GPU上进行训练时,返回的训练损失和验证损失值都是有效的,并且我的模型收敛了,但是在2个或更多GPU上,训练损失很好且有效,但验证损失均为NaN。这是任何人以前遇到过的问题吗?是否有人对如何解决该问题有任何建议?我已经在多台计算机上尝试了该代码,每台计算机上都具有与Keras / Tensorflow兼容的CUDA GPU数量和种类不同,但是没有用。即使仅使用一个GPU,我也可以在任何计算机上成功训练。
model = multi_gpu_model(Model(inputs=inputs, outputs=outputs),gpus=number_of_gpus, cpu_merge=True, cpu_relocation=False)
hist = model.fit_generator(generator=training_generator,
callbacks=callbacks,
max_queue_size=max_queue_size,
steps_per_epoch=steps_per_epoch,
workers=number_of_workers,
validation_data = validation_generator,
validation_steps=validation_steps,
shuffle=False)
我的期望是该模型将返回有效的验证损失,但是每个验证损失都是NaN,因此我无法在多GPU机器上准确地对我的训练进行基准测试,这非常不方便,因为我希望加快训练速度
答案 0 :(得分:0)
据我所知(启发式),在进行分布式训练/评估时,数据集中的元素数量必须能被批处理大小和GPU数量均匀地整除。即telegramPost = '%23id' + str(discount['id'])
。如果不是这种情况,则会将空批次传递给损失函数,根据损失函数,可能会将NaN损失注入聚合器。
(在评论中,OP提到其批处理大小可被GPU的数量均匀地整除,这与元素的数量可整除的数量不同取决于GPU的数量和批量大小。)
我在编写自定义Keras模型并每晚使用TF2时遇到了此问题。我的解决方法(已解决了我的问题)是修改所有损失函数,以便它们显式检查批处理的大小。例如。假设某些错误函数名为nelements / ngpus / batch_size == 0
:
fn
另一种解决方法是截断数据集。