在TensorFlow中,我试图构建一个模型来执行图像超分辨率(即回归任务)并使用TensorBoard分析结果。在训练过程中,我发现均方误差(MSE)大部分时间在100到200之间波动(甚至从一开始就是这样),并且从未收敛。我希望将以下变量添加到tf.summary
中,并分析是什么问题导致了这种情况。
graph_loss = get_graph_mean_square_error()tf.summary.scalar('graph_loss', graph_loss)regularization_loss = tf.add_n([tf.nn.l2_loss(weight) for weight in weights]) * regularization_paramtf.summary.scalar('reg_loss', regularization_loss)tf.summary.scalar('overall_loss', regularization_loss + graph_loss)for index in range(len(weights)): tf.summary.histogram("weight[%02d]" % index, weights[index])optimizer = tf.train.AdamOptimizer()capped_grad_and_vars = [(tf.clip_by_value(grad, -clip_value, clip_value), var) for grad, var in grad_and_vars if grad is not None]train_optimizer = optimizer.apply_gradients(capped_grad_and_vars, global_step)for grad, var in grad_and_vars: tf.summary.histogram(var.name + '/gradient', grad)for grad, var in capped_grad_and_vars: tf.summary.histogram(var.name + '/capped_gradient', grad)
该模型是一个带有跳跃连接的ResNET,其中包含几个重复的[卷积 -> 批量归一化 -> ReLU]层。在“分布”选项卡中,我可以看到添加了以下模式的几个图表:
- BatchNorm_[number]/beta0/capped_gradient
- BatchNorm_[number]/beta0/gradient
- BatchNorm_[number]/gamma0/capped_gradient
- BatchNorm_[number]/gamma0/gradient
- bias[number]_0/capped_gradient
- bias[number]_0/gradient
- weight_[number]_
- weight_[number]_0/capped_gradient
- weight_[number]_0/gradient
我注意到了一些事情,希望有人能对此提供一些见解:
使用L2损失进行正则化
regularization_param
的值被设置为0.0001,reg_loss
图表显示其从1.5(像对数一样)增加,并在3.5左右收敛。在我的情况下,graph_loss
在100到200之间,而reg_loss
在1.5到3.5之间。
reg_loss
图表的趋势是否符合我们的预期(如对数增加的函数)?reg_loss
是否太小而无法对模型进行惩罚(100-200 vs 1.5-3.5)?- 如何知道我选择的
regularization_param
是否正确?
解决梯度消失问题
我认为从头到尾的MSE波动问题可能是由于梯度消失问题引起的。我希望使用几种技术,如带跳跃连接的ResNET、批量归一化和梯度裁剪(clip_by_value
设置为0.05)来解决梯度消失问题。我不太确定如何读取图表,但在我看来,在前20K步中,前22层的权重似乎没有变化,如下图所示(我不太熟悉TensorBoard,如果我的阅读/解释有误,请纠正我):
我将训练分成几次运行,并从前一次运行中恢复检查点。这是经过66K步后最后几层的图表:
你可以看到,在前20K步中,一些层的权重仍然在变化,如橙色的weight_36_和weight_37_。然而,经过50K步后,所有的权重看起来都变得平坦,如绿色的weight_36_(非常薄)和weight_39_(几乎没有厚度)。
然后我查看了批量归一化的图表(注意,capped_gradient是clip_by_value
设置为0.05),看起来有一些变化,如下所示:
- 请问有人能解释一下上面的图表是否正确吗?(我不明白为什么每次批量归一化后有一些好的值,但权重似乎没有变化)
- 为了解决从头到尾的MSE波动问题,我应该朝哪个方向看?
欢迎任何其他建议 🙂
回答:
reg_loss
图表的趋势是否符合我们的预期(如对数增加的函数)?
是的,看起来没问题。
reg_loss
是否太小而无法对模型进行惩罚(100-200 vs 1.5-3.5)?- 如何知道我选择的
regularization_param
是否正确?
首先,我建议你将学习率从0.001调整到0.1(这是研究梯度裁剪问题的第一步),并观察平均MSE是否降低,以选择最佳学习率而不使用reg_loss
。然后你可以重新添加正则化,通过微调reg_loss
来进行调整。
- 请问有人能解释一下上面的图表是否正确吗?(我不明白为什么每次批量归一化后有一些好的值,但权重似乎没有变化)
- 为了解决从头到尾的MSE波动问题,我应该朝哪个方向看?
请仔细检查你是否对每个epoch取了平均MSE。有时候在每个子epoch中观察到波动问题可能是正常的。但如果你对每个epoch取了平均MSE,你可能会发现它会逐渐下降。