因为项目需要作点的定位所以需要用到euclidean_loss_layer 层,这里特别的看了一下该层的实现源码,位置
E:\Caffe\caffe-windows\include\caffe\layers\euclidean_loss_layer.hpp和E:\Caffe\caffe-windows\src\caffe\layers\euclidean_loss_layer.cpp
一、损失函数公式
Euclidean loss layer 计算两个输入的差的平方和:
二、代码具体实现
Euclidean loss layer是通过EuclideanLossLayer类实现,该类主要继承LossLayer类
1、构造函数
explicit EuclideanLossLayer(const LayerParameter& param): LossLayer<Dtype>(param), diff_() {}
2、 变维函数
template <typename Dtype>
void EuclideanLossLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
LossLayer<Dtype>::Reshape(bottom, top);
CHECK_EQ(bottom[0]->count(1), bottom[1]->count(1))//保证输入维度相同
<< "Inputs must have the same dimension.";
diff_.ReshapeLike(*bottom[0]);
}
3、前向传播和反向传播
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());//预测和标签的差值
Dtype dot = caffe_cpu_dot(count, diff_.cpu_data(), diff_.cpu_data());//diff_增量的平方
Dtype loss = dot / bottom[0]->num() / Dtype(2);//损失函数的值,除以总数再除以2
top[0]->mutable_cpu_data()[0] = loss;
}
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]) {//对于输入的第i个Blob propagate_dowm 为1(该变量即为该Blob输入后是否要向前面的层提供反向传播的梯度)
const Dtype sign = (i == 0) ? 1 : -1;
const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num();//对输入求导loss/N
caffe_cpu_axpby(
bottom[i]->count(), // count
alpha, // alpha
diff_.cpu_data(), // a
Dtype(0), // beta
bottom[i]->mutable_cpu_diff()); // b
}//结果:b=alpha*a+beta*b
}
}