当训练深度CNN时,一种常见的方法是使用 SGD,并且使用"步骤"学习率政策(例如,在不同的培训阶段,学习率设定为0.1,0.01,0.001 ..)但在MXNet下使用此策略进行培训时遇到意外现象。
这是定期训练损失值 https://user-images.githubusercontent.com/26757001/31327825-356401b6-ad04-11e7-9aeb-3f690bc50df2.png
以上是固定学习率0.01的训练损失,其中损失正常减少 https://user-images.githubusercontent.com/26757001/31327872-8093c3c4-ad04-11e7-8fbd-327b3916b278.png
然而,在第二阶段的训练中(损失为0.001),损失会定期上下波动,而这段时间恰好是一个时代
所以我认为这可能是数据改组的问题,但它无法解释为什么它不会在第一阶段发生。实际上我使用ImageRecordIter
作为DataIter
并在每个时代之后重置它,是否有任何我错过或错误设置的内容?
train_iter = mx.io.ImageRecordIter(
path_imgrec=recPath,
data_shape=dataShape,
batch_size=batchSize,
last_batch_handle='discard',
shuffle=True,
rand_crop=True,
rand_mirror=True)
培训和损失评估的代码:
while True:
train_iter.reset()
for i,databatch in enumerate(train_iter):
globalIter += 1
mod.forward(databatch,is_train=True)
mod.update_metric(metric,databatch.label)
if globalIter % 100 == 0:
loss = metric.get()[1]
metric.reset()
mod.backward()
mod.update()
实际上损失可以收敛,但需要的时间太长。 我在很长一段时间内,在不同的网络和不同的数据集上遇到了这个问题。 使用Caffe时我没有遇到这个问题。这是由于实施的差异吗?
答案 0 :(得分:1)
您的损失/学习曲线看起来非常平滑,我相信即使学习率设置为0.01,只是在较小的相对比例下(即如果您'放大'到图表中,您也可以观察到损失中的相同振荡你会看到相同的模式)。例如,您的数据迭代器传递相同的批处理可能会出现问题。并且您的训练循环看起来不对,但这可能是由于格式化(例如mod.update()仅每100批次执行不正确)。
当您穿越损失表面的山谷时,您可以观察到损失的周期性,上下两侧而不是山谷。选择较低的学习率可以帮助解决这个问题,并确保您也使用动力。