当训练深度CNN时,常见的方法是使用 SGD with momentum with a "step" learning rate policy (例如,在训练的不同阶段学习率设置为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时我没有遇到这个问题 . 这是由于实施的差异吗?
1 回答
您的损失/学习曲线看起来非常平滑,我相信即使学习率设置为0.01,只是在较小的相对比例下,您也可以观察到相同的振荡(即如果您'放大'到图表中看到相同的模式) . 例如,您的数据迭代器传递相同的批处理可能会出现问题 . 并且您的训练循环看起来不对,但这可能是由于格式化(例如mod.update()仅每100个批次执行不正确) .
当您穿越损失表面的山谷时,您可以观察到损失的周期性,在两侧上下而不是在山谷中 . 选择较低的学习率可以帮助解决这个问题,并确保您也使用动力 .