caffe源码——Euclidean Loss是怎么实现的,C++,以及python

https://blog.csdn.net/h_jlwg6688/article/details/71453590 c++

caffe源码——Euclidean Loss是怎么实现的

                版权声明:本文为博主原创文章,欢迎转载                    https://blog.csdn.net/h_jlwg6688/article/details/71453590                </div>
                      <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-cd6c485e8b.css">
                          <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-cd6c485e8b.css">
      <div class="htmledit_views" id="content_views">

引用:

http://blog.csdn.net/fangjin_kl/article/details/54131144

损失函数:


的偏导:

的偏导:-

forward_cpu:


 
 
  1. template < typename Dtype>
  2. void EuclideanLossLayer<Dtype>::Forward_cpu( const vector<Blob<Dtype>*>& bottom,
  3. const vector<Blob<Dtype>*>& top) {
  4. int count = bottom[ 0]->count();
  5. caffe_sub(
  6. count,
  7. bottom[ 0]->cpu_data(),
  8. bottom[ 1]->cpu_data(),
  9. diff_.mutable_cpu_data()); //diff_ = bottom[0] - bottom[1]
  10. Dtype dot = caffe_cpu_dot(count, diff_.cpu_data(), diff_.cpu_data()); // dot = ||diff_||^2
  11. Dtype loss = dot / bottom[ 0]->num() / Dtype( 2); //输出的loss
  12. top[ 0]->mutable_cpu_data()[ 0] = loss;
  13. }

backward_cpu:


 
 
  1. template < typename Dtype>
  2. void EuclideanLossLayer<Dtype>::Backward_cpu( const vector<Blob<Dtype>*>& top,
  3. const vector< bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
  4. for ( int i = 0; i < 2; ++i) {
  5. if (propagate_down[i]) { //对于输入的label bottom propagate_dowm 为0
  6. const Dtype sign = (i == 0) ? 1 : -1; //由于diff_ = bottom[0] - bottom[1]
  7. const Dtype alpha = sign * top[ 0]->cpu_diff()[ 0] / bottom[i]->num();
  8. caffe_cpu_axpby(
  9. bottom[i]->count(), // count
  10. alpha, // alpha
  11. diff_.cpu_data(), // a
  12. Dtype( 0), // beta
  13. bottom[i]->mutable_cpu_diff()); // b
  14. } //bottom[i]->mutable_cpu_diff()) = alpha*diff_.cpu_data()
  15. }
  16. }
forward_cpu里就是按照损失函数的样式计算损失,并且将损失保存到top[0]->cpu_data()[0]中。其中有用的是计算得到的diff_->cpu_data()。

backward_cpu里的两个for循环就是就是分别计算对的偏导和对对的偏导,其中sign是正负号,用于控制是对还是对求偏导,而top[0]->cpu_diff()[0]是在网络的定义中(即prototxt文件中),loss层的定义中设置的loss_weight:1.0,即top[0]->cpu_diff()[0]=1.0,则alpha就是1/n或者-1/n,而diff_.cpu_data()=-,caffe_cpu_axpby()得到了1*(-)/n即对的偏导,和-1*(-)/n即对的偏导,并把结果存到bottom[i]->cpu_diff()中,用以传向前面的层。


更多参考:

http://blog.csdn.net/seashell_9/article/details/68064294

***python代码## *** https://github.com/BVLC/caffe/blob/master/examples/pycaffe/layers/pyloss.py

import caffe
import numpy as np
class EuclideanLossLayer(caffe.Layer):
“”"
Compute the Euclidean Loss in the same manner as the C++ EuclideanLossLayer
to demonstrate the class interface for developing layers in Python.
“”"

def setup(self, bottom, top):
    # check input pair
    if len(bottom) != 2:
        raise Exception("Need two inputs to compute distance.")

def reshape(self, bottom, top):
    # check input dimensions match
    if bottom[0].count != bottom[1].count:
        raise Exception("Inputs must have the same dimension.")
    # difference is shape of inputs
    self.diff = np.zeros_like(bottom[0].data, dtype=np.float32)
    # loss output is scalar
    top[0].reshape(1)

def forward(self, bottom, top):
    self.diff[...] = bottom[0].data - bottom[1].data
    top[0].data[...] = np.sum(self.diff**2) / bottom[0].num / 2.

def backward(self, top, propagate_down, bottom):
    for i in range(2):
        if not propagate_down[i]:
            continue
        if i == 0:
            sign = 1
        else:
            sign = -1

bottom[i].diff[…] = sign * self.diff / bottom[i].num

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值