caffe 加权交叉熵损失函数层(weighted sigmoid_cross_entropy_loss_layer)添加方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/majinlei121/article/details/78884531

用卷积神经网络实现边缘检测的论文”Holistically-Nested Edge Detection”中使用了加权交叉熵损失函数(sigmoid_cross_entropy_loss_layer),因为在边缘检测中正样本(边缘)相对于负样本(非边缘)来讲,数量是很少的,如果对正负样本的损失乘以同样的权重系数,那么网络就会把所有的像素都预测成负样本(因为正样本的数目很少,所以都预测为负样本的话,总的损失也会很小),而这是我们不想看到的,所以需要给正样本的损失加上一定的权重,当正样本分类错误的时候,乘以一个很大的权重,造成总的损失会很大。当负样本分类错的时候,乘以一个很小的权重(e.g. 1),但是由于负样本的总数比较多,所以总的损失也是符合实际情况的。
先补上上面论文的地址:https://www.cv-foundation.org/openaccess/content_iccv_2015/papers/Xie_Holistically-Nested_Edge_Detection_ICCV_2015_paper.pdf
caffe代码:https://github.com/s9xie/hed
论文中交叉熵损失函数定义为:

这里写图片描述

比如一共100个像素,边缘像素有2个,非边缘有98个,那么边缘损失的权重为0.98,非边缘损失的权重为0.02,给数量少的正样本足够大的权重,卷积网络就可训练出最后满意结果。
论文的代码使用的交叉熵损失函数是在原来caffe的SigmoidCrossEntropyLoss层上进行改进的,并没有定义新的层,在自己实际使用时还不能直接用,需要改一些东西,改过之后的文件在http://download.csdn.net/download/majinlei121/10171746,包括sigmoid_cross_entropy_loss_layer.cpp 和 sigmoid_cross_entropy_loss_layer.hpp
cpp文件的改动主要是在加权损失方面
由于只定义了cpu上运行的损失函数,没有sigmoid_cross_entropy_loss_layer.cu文件,所以需要把hpp文件中关于gpu执行的声明给注释掉,注释的代码包括:

  //virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
      //const vector<Blob<Dtype>*>& top);

  //virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
      //const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);

另外自己还在损失函数的基础上又加了一个权重lambda_, lambda_是乘在正样本的损失上的,因此需要hpp文件中加入声明(124行):

  int lambda_;

并且需要在caffe/src/caffe/proto/caffe.proto文件中加入声明(在LossParameter里)加入:

  optional int32 lambda = 6 [default = 1];

这样使用SigmoidCrossEntropyLoss层的时候为

layer {
  name: "loss"
  type: "SigmoidCrossEntropyLoss"
  bottom: "conv5"
  bottom: "prob"
  top: "loss"
  propagate_down: 1
  propagate_down: 0
  loss_weight: 1 # 1
  loss_param: {
    normalize: 1
    lambda: 1
  }
}

在论文给的sigmoid_cross_entropy_loss_layer.cpp代码中一开始调用了

#include "caffe/vision_layers.hpp"

但是在后期的caffe中vision_layers.hpp已经没有了,在下载地址http://download.csdn.net/download/majinlei121/10171746中已经将该句删除,添加为

#include "caffe/layers/sigmoid_cross_entropy_loss_layer.hpp"

按照上面的步骤修改就可以编译成功了(需要把caffe中原来的sigmoid_cross_entropy_loss_layer.cu删掉)。

猜你喜欢

转载自blog.csdn.net/majinlei121/article/details/78884531