【caffe】如何借助debug_info阅读caffe日志

在中文互联网中没有找到合适的文章,翻译此文以供参考。

提问

在训练模型陷入困境(比如出现nansloss不收敛)时,查看冗长的日志有时候会有意外收获,为了得到日志,需要在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)

这是什么意思?

回答

前向传播

大看一眼,首先日志分为[Forward]和[Backward]两部分,考虑到网络的学习由前向推断和后向传播组成:
训练样本(或者batch)输入样本,前向传播得到预测值,由预测值计算loss并求导,估计梯度并按照链式法则后向传播。
我们知道caffe利用Blob来处理data/weights/parameters等数据,这里我们需要明确,一个Blob由data和diff两部分组成,data储存数据,diff储存梯度。(类似于PyTorch中的Tensor)
前向传播:
你可以看到日志中展示了所有层从bottom到top的传播过程。每一层如下:

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层有两个Blob参数:卷积核filter和偏置bias,加上数据一共有3行。

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

当前conv1卷积核权重的L2范数是0.00899,bias值(para blob 1)为0:

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

啰嗦一句,conv1层有个输出,叫“conv1”(…),这个输出的L2范数是0.0645

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

需要注意的是所有[Forward]中报告的L2范数对象都是blob的data部分。

loss和梯度

[Forward]的最后一层是loss

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

传入的该batch的loss是2031.85,loss对应于fc1的梯度保存在fc1的Blob中(我们知道fc1的data和diff应该是shape相同的),且L2范数幅度是0.1245。

后向传播

[backward]中的计算的是对应层Blob的diff的L2范数

最后

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

最后报告了网络所有参数(data和diff)的L1范数和L2范数

我应该怎么找?

  1. 如果loss中含有nan,找找哪一层、哪一次迭代中开始产生nan。
  2. 观察梯度的幅度,这些数据应该很好看,如果出现了e+8,那说明产生了梯度爆炸,不妨减小学习率。
  3. diff不可能为0,否则0梯度->无更新->无学习,所以随机初始化权重时应当设置为高方差。
  4. 比起报0的梯度层,尤其要注意报0的激活层。对于ReLU来说,报0意味着你来到了一个没有激活的"死神经元"区域,不妨试试normalizrtion、batch normalization或leaky ReLU。

猜你喜欢

转载自blog.csdn.net/tfcy694/article/details/84028896