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:
-
template <
typename Dtype>
-
void EuclideanLossLayer<Dtype>::Forward_cpu(
const
vector<Blob<Dtype>*>& bottom,
-
const
vector<Blob<Dtype>*>& top) {
-
int count = bottom[
0]->count();
-
caffe_sub(
-
count,
-
bottom[
0]->cpu_data(),
-
bottom[
1]->cpu_data(),
-
diff_.mutable_cpu_data());
//diff_ = bottom[0] - bottom[1]
-
Dtype dot = caffe_cpu_dot(count, diff_.cpu_data(), diff_.cpu_data());
// dot = ||diff_||^2
-
Dtype loss = dot / bottom[
0]->num() / Dtype(
2);
//输出的loss
-
top[
0]->mutable_cpu_data()[
0] = loss;
-
}
backward_cpu:
-
template <
typename Dtype>
-
void EuclideanLossLayer<Dtype>::Backward_cpu(
const
vector<Blob<Dtype>*>& top,
-
const
vector<
bool>& propagate_down,
const
vector<Blob<Dtype>*>& bottom) {
-
for (
int i =
0; i <
2; ++i) {
-
if (propagate_down[i]) {
//对于输入的label bottom propagate_dowm 为0
-
const Dtype sign = (i ==
0) ?
1 :
-1;
//由于diff_ = bottom[0] - bottom[1]
-
const Dtype alpha = sign * top[
0]->cpu_diff()[
0] / bottom[i]->num();
-
caffe_cpu_axpby(
-
bottom[i]->count(),
// count
-
alpha,
// alpha
-
diff_.cpu_data(),
// a
-
Dtype(
0),
// beta
-
bottom[i]->mutable_cpu_diff());
// b
-
}
//bottom[i]->mutable_cpu_diff()) = alpha*diff_.cpu_data()
-
}
-
}
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
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