梳理caffe代码loss(二十二)






下面是一个博友对于NG课程的翻译:





接下来偷懒一下直接上传图片,caffe中的常用的loss函数(后面文章会梳理每一个Loss):




loss有一个细节问题就是Loss weights(损失权重),用来表征不同Layer产生的loss的重要性,Layer名称中以Loss结尾表示这是一个会产生loss的Layer,其他的Layer只是单纯的用于中间计算。任何一个Layer都可以被用于产生loss。反向迭代时,一个Layer可以赋予一个非零的loss weight,用于调整中间Layer产生的一些数据、参数。对于不止一个输出(top)的Layer(对应的有非零的loss weight),输出的loss是对所有输出blob的loss的和。Caffe最后输出的loss,是由Net中所有的loss加权得到的。对于loss Layer,loss_weight为非0,对于非loss Layer,loss_weight都是0所以Layer对网络loss的贡献值也为0

Pseudocode:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. loss := 0  
  2. for layer in layers:  
  3.   for top, loss_weight in layer.tops, layer.loss_weights:  
  4.     loss += loss_weight * sum(top)  
这个设置在layer.hpp文件中, 一个protected函数, SetLossWeight()

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.    * 初始化损失权重---<strong>为每个top blob设置loss weight multiplier blobs(损失权重乘子blobs)</strong>,非LossLayer的top blob的loss weight值为零 
  3.    * =====!!!! Store non-zero loss weights in the diff blob !!!!=== 
  4.    */  
  5.   inline void SetLossWeights(const vector<Blob<Dtype>*>& top) {  
  6.     const int num_loss_weights = layer_param_.loss_weight_size();//message Layerparameter中的repeated float loss_weight = 5;表示的是“The amount of weight to assign each top blob in the objective”</strong></em>  
  7.     if (num_loss_weights) {  
  8.       CHECK_EQ(top.size(), num_loss_weights) << "loss_weight must be "  
  9.           "unspecified or specified once per top blob.";  
  10.       for (int top_id = 0; top_id < top.size(); ++top_id) {  
  11.         const Dtype loss_weight = layer_param_.loss_weight(top_id);  
  12.         if (loss_weight == Dtype(0)) { continue; }  
  13.         this->set_loss(top_id, loss_weight);//修改Layer的数据成员loss_,其存储的是loss_weight  
  14.         const int count = top[top_id]->count();  
  15.         Dtype* loss_multiplier = top[top_id]->mutable_cpu_diff();//返回指向某块Blob的diff所对应的内存空间的指针,并且由于mutable_cpu_diff返回的是void*指针,还有一个类型转换过程  
  16.         caffe_set(count, loss_weight, loss_multiplier);//loss_multiplier是一个void指针,caffe_set函数表示用loss_weight初始化这块内存,使其能够存储count个loss_weight(when loss_weight!=0),if loss_weight=0,则用0值来初始化.-----这里为blob的每个元素都初始化了一个loss_weight, 那么在后面计算loss时,只要sum(top)就可以了.  
  17.       }  
  18.     }  
  19.   }  

caffe_set函数在math_function中有实现,对参数进行的初始化,

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. template <typename Dtype>  
  2. void caffe_set(const int N, const Dtype alpha, Dtype* Y) {  
  3.   if (alpha == 0) {  
  4.     memset(Y, 0, sizeof(Dtype) * N);  // NOLINT(caffe/alt_fn)  
  5.     return;  
  6.   }  
  7.   for (int i = 0; i < N; ++i) {  
  8.     Y[i] = alpha;   
  9.   }  
  10. }  
功能:用常数 alpha 对 Y 进行初始化 

函数 void *memset(void *buffer, char c, unsigned count) 一般为新申请的内存做初始化,功能是将buffer所指向内存中的每个字节的内容全部设置为c指定的ASCII值, count为块的大小。

配置文件protxt中的形式:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. layer {  
  2.   name: "loss"  
  3.   type: "XXXXXXXXXXXLoss"  
  4.   bottom: "predict"  
  5.   bottom: "label1"  
  6.   bottom: "label2"  
  7.   top: "loss"  
  8.   loss_weight: xxxxx  
  9. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值