如何用 debug_info 解释 caffe 日志?

How to interpret caffe log with debug_info?

在训练过程中遇到困难时(, loss does not converge, etc.) it is sometimes useful to look at more verbose training log by setting 'solver.prototxt' 文件中。

训练日志看起来像这样:

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)

这是什么意思?

乍一看,您可以看到此日志部分分为两个部分:[Forward][Backward]。回想一下,神经网络训练是通过前向后向传播完成的:
将训练示例(批次)馈送到网络,前向传递输出当前预测。
基于此预测计算损失。 然后导出损失,并使用 chain rule.

估计梯度并向后传播

Caffe Blob数据结构
快速回顾一下。 Caffe 使用 Blob 数据结构来存储 data/weights/parameters 等。对于此讨论,重要的是要注意 Blob 有两个“部分”:datadiffBlob 的值存储在 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

"conv1" 是一个卷积层,它有 2 个参数 blob:过滤器和偏差。因此,日志有三行。过滤器 blob (param blob 0) 具有 data

 I1109 ...]     [Forward] Layer conv1, param blob 0 data: 0.00899114

即当前卷积滤波器权重的L2范数为0.00899。
当前偏差(param blob 1):

 I1109 ...]     [Forward] Layer conv1, param blob 1 data: 0

表示当前偏差设置为 0。

最后但同样重要的是,"conv1" 层有一个输出,"top" 名为 "conv1"(多么原始...)。输出的L2范数是

 I1109 ...]     [Forward] Layer conv1, top blob conv1 data: 0.0645037

请注意,[Forward] 通道的所有 L2 值均在相关 Blob 的 data 部分报告。

损失和梯度
[Forward] 遍的末尾是损失层:

I1109 ...]     [Forward] Layer loss, top blob loss data: 2031.85
I1109 ...]     [Backward] Layer loss, bottom blob fc1 diff: 0.124506

在此示例中,批量损失为 2031.85,损失的梯度 w.r.t。 fc1 被计算并传递给 fc1 Blob 的 diff 部分。梯度的L2幅度为0.1245.

向后传球
所有其余层都在这部分从上到下列出。您可以看到现在报告的 L2 幅度属于 Blob(参数和层的输入)的 diff 部分。

终于
本次迭代的最后一行日志:

[Backward] All net params (data, diff): L1 norm = (2711.42, 7086.66); L2 norm = (6.11659, 4085.07)

报告数据和梯度的总 L1 和 L2 量级。

我应该寻找什么?

  1. 如果你有,看看你的数据或差异在什么时候变成nan:在哪一层?在哪次迭代?

  2. 看梯度大小,应该是合理的。如果您开始看到 e+8 的值,您的 data/gradients 就会开始爆炸。降低你的学习率!

  3. 看到 diff 不为零。零差异意味着没有梯度 = 没有更新 = 没有学习。如果您从随机权重开始,请考虑生成具有更高方差的随机权重。

  4. 寻找变为零的激活(而不是梯度)。如果您使用 "ReLU" this means your inputs/weights lead you to regions where the ReLU gates are "not active" leading to "dead neurons". Consider normalizing your inputs to have zero mean, add "BatchNorm" 层,请在 ReLU 中设置 negative_slope