caffe Sigmoid cross entropy loss 交叉熵损失函数

Sigmoid 交叉熵损失函数(Sigmoid Cross Entropy Loss)

caffe <wbr>study(3) <wbr>关于激活函数以及loss <wbr>function

官方: loss $ E = \frac{-1}{n} \sum\limits_{n=1}^N \left[ p_n \log \hat{p}_n + (1 - p_n) \log(1 - \hat{p}_n) \right] $,

输入:

  1. 形状:   得分  , 这个层使用 sigmoid 函数   映射到概率分布 

  2. 形状:  标签 

输出:

  1. 形状:  计算公式: 

应用场景: 
预测目标概率分布

Parameters
bottominput Blob vector (length 2)
  1. $ (N \times C \times H \times W) $ the scores $ x \in [-\infty, +\infty]$, which this layer maps to probability predictions $ \hat{p}_n = \sigma(x_n) \in [0, 1] $ using the sigmoid function $ \sigma(.) $ (see SigmoidLayer).
  2. $ (N \times C \times H \times W) $ the targets $ y \in [0, 1] $
topoutput Blob vector (length 1)
  1. $ (1 \times 1 \times 1 \times 1) $ the computed cross-entropy loss: $ E = \frac{-1}{n} \sum\limits_{n=1}^N \left[ p_n \log \hat{p}_n + (1 - p_n) \log(1 - \hat{p}_n) \right] $


Computes the sigmoid cross-entropy loss error gradient w.r.t. the predictions.

Gradients cannot be computed with respect to the target inputs (bottom[1]), so this method ignores bottom[1] and requires !propagate_down[1], crashing if propagate_down[1] is set.

Parameters
topoutput Blob vector (length 1), providing the error gradient with respect to the outputs
  1. $ (1 \times 1 \times 1 \times 1) $ This Blob's diff will simply contain the loss_weight* $ \lambda $, as $ \lambda $ is the coefficient of this layer's output $\ell_i$ in the overall Netloss $ E = \lambda_i \ell_i + \mbox{other loss terms}$; hence $ \frac{\partial E}{\partial \ell_i} = \lambda_i $. (*Assuming that this top Blob is not used as a bottom (input) by any other layer of the Net.)
propagate_downsee Layer::Backward. propagate_down[1] must be false as gradient computation with respect to the targets is not implemented.
bottominput Blob vector (length 2)
  1. $ (N \times C \times H \times W) $ the predictions $x$; Backward computes diff $ \frac{\partial E}{\partial x} = \frac{1}{n} \sum\limits_{n=1}^N (\hat{p}_n - p_n) $
  2. $ (N \times 1 \times 1 \times 1) $ the labels – ignored as we can't compute their error gradients
[cpp]  view plain  copy
  1. #include <algorithm>  
  2. #include <cfloat>  
  3. #include <vector>  
  4.   
  5. #include "caffe/layer.hpp"  
  6. #include "caffe/util/math_functions.hpp"  
  7. #include "caffe/vision_layers.hpp"  
  8.   
  9. // Computes the cross-entropy (logistic) loss ,it is often used for predicting targets interpreted   
  10. // as probabilities. Detailed reference to the official document:  
  11. // http://caffe.berkeleyvision.org/doxygen/classcaffe_1_1SigmoidCrossEntropyLossLayer.html  
  12.   
  13.   
  14. namespace caffe {  
  15.   
  16. template <typename Dtype>  
  17. void SigmoidCrossEntropyLossLayer<Dtype>::LayerSetUp(  
  18.     const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {  
  19.   LossLayer<Dtype>::LayerSetUp(bottom, top);  
  20.   sigmoid_bottom_vec_.clear();  
  21.   sigmoid_bottom_vec_.push_back(bottom[0]);  
  22.   sigmoid_top_vec_.clear();  
  23.   sigmoid_top_vec_.push_back(sigmoid_output_.get());  
  24.   sigmoid_layer_->SetUp(sigmoid_bottom_vec_, sigmoid_top_vec_);  
  25. }  
  26.   
  27. template <typename Dtype>  
  28. void SigmoidCrossEntropyLossLayer<Dtype>::Reshape(  
  29.     const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {  
  30.   LossLayer<Dtype>::Reshape(bottom, top);  
  31.   CHECK_EQ(bottom[0]->count(), bottom[1]->count()) <<  
  32.       "SIGMOID_CROSS_ENTROPY_LOSS layer inputs must have the same count.";  
  33.   sigmoid_layer_->Reshape(sigmoid_bottom_vec_, sigmoid_top_vec_);  
  34. }  
  35.   
  36. template <typename Dtype>  
  37. void SigmoidCrossEntropyLossLayer<Dtype>::Forward_cpu(  
  38.     const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {  
  39.   // The forward pass computes the sigmoid outputs.  
  40.   sigmoid_bottom_vec_[0] = bottom[0];  
  41.   sigmoid_layer_->Forward(sigmoid_bottom_vec_, sigmoid_top_vec_);  
  42.   // Compute the loss (negative log likelihood)  
  43.   const int count = bottom[0]->count();  
  44.   const int num = bottom[0]->num();  
  45.   // Stable version of loss computation from input data  
  46.   const Dtype* input_data = bottom[0]->cpu_data();  
  47.   const Dtype* target = bottom[1]->cpu_data();  
  48.   Dtype loss = 0;  
  49.   for (int i = 0; i < count; ++i) {  
  50.     loss -= input_data[i] * (target[i] - (input_data[i] >= 0)) -  
  51.         log(1 + exp(input_data[i] - 2 * input_data[i] * (input_data[i] >= 0)));  
  52.   }  
  53.   top[0]->mutable_cpu_data()[0] = loss / num;  
  54. }  
  55.   
  56. template <typename Dtype>  
  57. void SigmoidCrossEntropyLossLayer<Dtype>::Backward_cpu(  
  58.     const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down,  
  59.     const vector<Blob<Dtype>*>& bottom) {  
  60.   if (propagate_down[1]) {  
  61.     LOG(FATAL) << this->type()  
  62.                << " Layer cannot backpropagate to label inputs.";  
  63.   }  
  64.   if (propagate_down[0]) {  
  65.     // First, compute the diff  
  66.     const int count = bottom[0]->count();  
  67.     const int num = bottom[0]->num();  
  68.     const Dtype* sigmoid_output_data = sigmoid_output_->cpu_data();  
  69.     const Dtype* target = bottom[1]->cpu_data();  
  70.     Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();  
  71.     caffe_sub(count, sigmoid_output_data, target, bottom_diff);  
  72.     // Scale down gradient  
  73.     const Dtype loss_weight = top[0]->cpu_diff()[0];  
  74.     caffe_scal(count, loss_weight / num, bottom_diff);  
  75.   }  
  76. }  
  77.   
  78. #ifdef CPU_ONLY  
  79. STUB_GPU_BACKWARD(SigmoidCrossEntropyLossLayer, Backward);  
  80. #endif  
  81.   
  82. INSTANTIATE_CLASS(SigmoidCrossEntropyLossLayer);  
  83. REGISTER_LAYER_CLASS(SigmoidCrossEntropyLoss);  
  84.   
  85. }  // namespace caffe  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用Python层Caffe实现Bhattacharyya损失函数前,需要先了解Bhattacharyya距离和Bhattacharyya系数,它们是计算Bhattacharyya损失函数的基础。 Bhattacharyya距离是一种用于度量两个概率分布相似性的方法,其定义为: ![](https://cdn.jsdelivr.net/gh/1076827098/CDN/blog/nlp-chatbot/bhattacharyya_distance.png) 其中,P(x)和Q(x)分别为两个概率分布函数,x为概率变量。 Bhattacharyya系数是Bhattacharyya距离的指数形式,其定义为: ![](https://cdn.jsdelivr.net/gh/1076827098/CDN/blog/nlp-chatbot/bhattacharyya_coefficient.png) 在了解了Bhattacharyya距离和Bhattacharyya系数后,我们可以开始实现Bhattacharyya损失函数。下面是一个使用Python层Caffe实现Bhattacharyya损失函数的示例代码: ```python import caffe import numpy as np class BhattacharyyaLossLayer(caffe.Layer): def setup(self, bottom, top): if len(bottom) != 2: raise Exception("Need two inputs to compute Bhattacharyya loss.") # 检查输入数据维度是否匹配 if bottom[0].count != bottom[1].count: raise Exception("Inputs must have the same dimension.") self.diff = np.zeros_like(bottom[0].data, dtype=np.float32) self.epsilon = 1e-6 # 避免除数为0 def reshape(self, bottom, top): top[0].reshape(1) def forward(self, bottom, top): # 计算Bhattacharyya系数 self.diff[...] = bottom[0].data - bottom[1].data self.distance = np.sum(np.sqrt(np.abs(self.diff))) + self.epsilon self.bc = np.exp(-self.distance) # 计算Bhattacharyya损失 self.loss = -np.log(self.bc + self.epsilon) top[0].data[...] = self.loss def backward(self, top, propagate_down, bottom): if propagate_down: bottom[0].diff[...] = -(1 / (self.bc + self.epsilon)) * np.sign(self.diff) * np.exp(-self.distance / 2) / np.sqrt(np.abs(self.diff)) bottom[1].diff[...] = (1 / (self.bc + self.epsilon)) * np.sign(self.diff) * np.exp(-self.distance / 2) / np.sqrt(np.abs(self.diff)) ``` 在上面的代码中,我们定义了一个名为BhattacharyyaLossLayer的自定义层,实现了Bhattacharyya损失函数。在setup()函数中,我们首先检查输入的数据维度是否匹配,然后初始化diff和epsilon变量。在reshape()函数中,我们指定输出数据的维度。在forward()函数中,我们计算了Bhattacharyya系数和Bhattacharyya损失,并将损失值保存到top[0]中。在backward()函数中,我们计算了梯度,并将梯度值保存到bottom[0]和bottom[1]中。 需要注意的是,在计算梯度时,我们使用了符号函数和指数函数,这是由于Bhattacharyya距离的定义中包含了绝对值,导致其不可导。因此,我们使用了符号函数来代替导数的符号,使用指数函数来代替导数的大小。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值