在培训期间遇到困难时(nan
s,loss does not converge等),通过在'solver.prototxt'
文件中设置debug_info: true
来查看更详细的培训日志有时很有用
培训日志看起来像是:
I1109 ...] [Forward] Layer data, top blob data data: 0.343971 I1109 ...] [Forward] Layer conv1, top blob conv1 data: 0.0645037 I1109 ...] [Forward] Layer conv1, param blob 0 data: 0.00899114 I1109 ...] [Forward] Layer conv1, param blob 1 data: 0 I1109 ...] [Forward] Layer relu1, top blob conv1 data: 0.0337982 I1109 ...] [Forward] Layer conv2, top blob conv2 data: 0.0249297 I1109 ...] [Forward] Layer conv2, param blob 0 data: 0.00875855 I1109 ...] [Forward] Layer conv2, param blob 1 data: 0 I1109 ...] [Forward] Layer relu2, top blob conv2 data: 0.0128249 . . . I1109 ...] [Forward] Layer fc1, top blob fc1 data: 0.00728743 I1109 ...] [Forward] Layer fc1, param blob 0 data: 0.00876866 I1109 ...] [Forward] Layer fc1, param blob 1 data: 0 I1109 ...] [Forward] Layer loss, top blob loss data: 2031.85 I1109 ...] [Backward] Layer loss, bottom blob fc1 diff: 0.124506 I1109 ...] [Backward] Layer fc1, bottom blob conv6 diff: 0.00107067 I1109 ...] [Backward] Layer fc1, param blob 0 diff: 0.483772 I1109 ...] [Backward] Layer fc1, param blob 1 diff: 4079.72 . . . I1109 ...] [Backward] Layer conv2, bottom blob conv1 diff: 5.99449e-06 I1109 ...] [Backward] Layer conv2, param blob 0 diff: 0.00661093 I1109 ...] [Backward] Layer conv2, param blob 1 diff: 0.10995 I1109 ...] [Backward] Layer relu1, bottom blob conv1 diff: 2.87345e-06 I1109 ...] [Backward] Layer conv1, param blob 0 diff: 0.0220984 I1109 ...] [Backward] Layer conv1, param blob 1 diff: 0.0429201 E1109 ...] [Backward] All net params (data, diff): L1 norm = (2711.42, 7086.66); L2 norm = (6.11659, 4085.07)
这是什么意思?
答案 0 :(得分:15)
乍一看,您可以看到此日志部分分为两部分:[Forward]
和[Backward]
。回想一下神经网络训练是通过前向 - 后向传播完成的:
训练示例(批处理)被馈送到网络,正向传递输出当前预测
基于该预测,计算损失。
然后导出损失,并使用chain rule估计梯度并向后传播。
Caffe Blob
数据结构
快速重新上限。 Caffe使用Blob
数据结构来存储数据/权重/参数等。对于此讨论,请务必注意Blob
有两个"部分":data
和{ {1}}。 diff
的值存储在Blob
部分中。 data
部分用于存储反向传播步骤的逐元素渐变。
正向传递
您将在日志的这一部分中看到从下到上列出的所有图层。对于每个图层,您都会看到:
diff
图层I1109 ...] [Forward] Layer conv1, top blob conv1 data: 0.0645037
I1109 ...] [Forward] Layer conv1, param blob 0 data: 0.00899114
I1109 ...] [Forward] Layer conv1, param blob 1 data: 0
是一个卷积层,有2个参数blob:过滤器和偏差。因此,日志有三行。过滤器blob("conv1"
)具有param blob 0
data
这是卷积滤波器权重的当前L2范数是0.00899
目前的偏见( I1109 ...] [Forward] Layer conv1, param blob 0 data: 0.00899114
):
param blob 1
表示当前偏差设为0。
最后但并非最不重要的是, I1109 ...] [Forward] Layer conv1, param blob 1 data: 0
图层有一个名为"conv1"
的{{1}}输出(原始...)。输出的L2范数是
"top"
请注意,"conv1"
传递的所有L2值都会在相关Blob的 I1109 ...] [Forward] Layer conv1, top blob conv1 data: 0.0645037
部分报告。
损失和渐变
在[Forward]
传递结束时出现了损失层:
data
在这个例子中,批次损失是2031.85,损失的梯度是w.r.t.计算[Forward]
并将其传递给I1109 ...] [Forward] Layer loss, top blob loss data: 2031.85
I1109 ...] [Backward] Layer loss, bottom blob fc1 diff: 0.124506
Blob的 fc1
部分。梯度的L2幅度为0.1245。
向后传递
其余所有层都从上到下列在此部分中。您可以看到现在报告的L2幅度属于Blob的diff
部分(参数和图层'输入)。
<强>最后强>
此迭代的最后一个日志行:
fc1
报告数据和梯度的总L1和L2大小。
我应该寻找什么?
如果您有nan
s in your loss,请查看您的数据或差异在什么时候变成diff
:在哪一层?在哪次迭代?
看看渐变幅度,它们应该是合理的。如果您开始看到[Backward] All net params (data, diff): L1 norm = (2711.42, 7086.66); L2 norm = (6.11659, 4085.07)
的值,您的数据/渐变开始爆炸。降低你的学习率!
看到nan
不是零。零差异意味着没有渐变=没有更新=没有学习。如果您从随机权重开始,请考虑生成方差较大的随机权重。
寻找激活(而不是渐变)为零。如果您使用的是"ReLU"
,这意味着您的输入/权重将引导您到ReLU门是&#34;未激活的区域&#34;导致"dead neurons"。考虑将输入规范化为零均值,在ReLU中添加[e+8
negative_slope`。