同所有的机器学习过程一样,在Caffe里,学习是由loss function损失函数驱动的(也有叫做 error,cost,或者objective function 的)。一个损失函数通过在参数(例如网络权重)和一个衡量这些参数拟合劣度的标量值(scalar)之间建立映射,指明了学习的目标。因此,学习的目标就是找到一组能够使loss fucntion最小化的参数。

Caffe里的损失是通过forward过程计算出来的。每一层都通过bottom从下面一层获取一个blob然后产生一组输出blob给top指定的上层.一些层的输出可能会在损失函数里使用。一个典型的为1对多分类任务选择的损失函数是SoftmaxWithLoss函数,使用一个如下的网络定义:

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

在一个SoftmaxWithLoss函数里,topblob是一个标量(empty shape),它是由整个minibatch的所有预测标签pred和实际标签label的差计算出来的平均误差.


损失权重

对于那些有多个输出层的网络(例如既使用了SoftmaxWithLoss又使用了EuclideanLoss),loss weight可以用来指明他们之间的相对重要度。

出于习惯,Caffe layer类型使用了后缀Loss来指明损失函数,但是其他层可假定为纯粹用来进行中间计算。但是,任何层可以用作损失函数,只要在layer定义中该层产生的的topblob添加一个loss_weight:<float>字段即可。带有后缀Loss的层定义有隐含的loss_weight属性,对于第一个topblobloss_weight=1,对于其他附加的top来说loss_weight=0;其他层有隐含的loss_weight=0给所有的top。于是,上面的SoftmaxWithLoss层可以等价的写成:

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

然而,任何可以反向传播的层都可以给定一个非零的loss_weigh,这样做可以允许我们做一些特定操作,比如,正则化一些中间层产生的激活值。对于关联着非零损失的非单个输出来说,损失仅仅是简单的把整个blob累积起来而已。
  
  
对于Caffe的最终损失,是把整个网络的加权损失累加起来计算的,例如下面的伪代码描述的那样:

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)

Comments

2016-01-14

⬆︎TOP