caffe学习(2)前后传播,loss,solver

向前和向后传播

Forward and Backward

前后传播是Net的重要组成,如下图所示:
前后传播示意图

向前Forward

通过给定的参数计算每层的值,就像函数一样top=f(bottom)。
Forward
上图表示数据通过内积层输出,再由softmax给出损失。

向后Backward

向后是计算loss的梯度,每层梯度通过自动微分来计算整个模型梯度,即反向传播。
反向backward
从这个图上可以看出,由loss开始,通过链式法则,不断求出结果对各层的导数。
Net::Forward()Net::Backward()是针对网络,Layer::Forward()Layer::Backward()是针对每一层。同时也可以设置CPU、GPU模式。
过程大概是:solver调用forward计算输出和loss,再生成梯度,并尝试更新权重减小loss。

损失Loss

Loss

Loss

使loss变小,是学习中的一个目标。如上所说,loss是由forward计算而出。

1
2
3
4
5
6
7
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "pred"
bottom: "label"
top: "loss"
}

这一段就是上面流程图最后一层loss的表达。

Loss weights

一般的loss只是最后一层才有,其他层只是中间计算,不过每层都可以通过增加loss_weight: <float>到该层生成的每个顶(top)层中。对于后缀有loss的层都隐含着loss_weight: 1(对第一个top,其他的loss_weight: 0)。因此上面代码也等价于在最后加上loss_weight: 1
然而任何能反向传播的层都可以赋予非零loss_weight,最终的loss由网络上各层loss权重求得

1
2
3
4
loss := 0
for layer in layers:
for top, loss_weight in layer.tops, layer.loss_weights:
loss += loss_weight * sum(top)

Solver

Solver

分类

Solver通过forward和backward形成参数更新,从而改善loss。包括:

  • Stochastic Gradient Descent (type: “SGD”),
  • AdaDelta (type: “AdaDelta”),
  • Adaptive Gradient (type: “AdaGrad”),
  • Adam (type: “Adam”),
  • Nesterov’s Accelerated Gradient (type: “Nesterov”) and
  • RMSprop (type: “RMSProp”)

方法

对于数据集$D$,优化目标是使整个$|D|$的平均loss最小,即:
$$L(W) = \frac{1}{|D|} \sum_i^{|D|} f_W\left(X^{(i)}\right) + \lambda r(W)$$
其中$f_W\left(X^{(i)}\right)$是对于数据$X^{(i)}$输入的损失,$r(W)$是加权$\lambda$的权重$W$正则项。通常用于学习的数据量$|D|$很大,在学习时常常将其分为很多大小为$N$的batch,其中$N<<|D|$,可以将原式中的$|D|$换为$N$。
$$L(W) \approx \frac{1}{N} \sum_i^N f_W\left(X^{(i)}\right) + \lambda r(W)$$
模型向前计算$f_W$,向后返回梯度$\nabla f_W$。参数的更新$\Delta W$由solver从$\nabla f_W$得到,正则化梯度每种方法得到的不同。
具体每种solver,网上讲的很多,这里就不讲了。