这一层比较简单:主要就是求绝对值,反传部分的代码也很简单
里头用到了caffe_abs这个函数以及caffe_cpu_sign这两个函数
需要注意的是caffe_cpu_sign在math_functions.hpp里头定义得比较特别
在math_functions.hpp里只有caffe_sign,通过一个宏定义生成了caffe_cpu_sign这个函数
整体来说没啥特别的内容,直接上代码吧。
#include <vector>
#include "caffe/layers/absval_layer.hpp"
#include "caffe/util/math_functions.hpp"
namespace caffe {
template <typename Dtype>
void AbsValLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
NeuronLayer<Dtype>::LayerSetUp(bottom, top);
CHECK_NE(top[0], bottom[0]) << this->type() << " Layer does not "
"allow in-place computation.";
}
template <typename Dtype>
void AbsValLayer<Dtype>::Forward_cpu(
const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
const int count = top[0]->count();
Dtype* top_data = top[0]->mutable_cpu_data();
caffe_abs(count, bottom[0]->cpu_data(), top_data);
}
template <typename Dtype>
void AbsValLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
const int count = top[0]->count();
// 前面一层关于本层top的偏导
const Dtype* top_diff = top[0]->cpu_diff();
if (propagate_down[0]) {
const Dtype* bottom_data = bottom[0]->cpu_data();
Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();
// 将bottom_data里头的每个元素的正负值复制到bottom_diff
caffe_cpu_sign(count, bottom_data, bottom_diff);
// 计算偏导数计算关于本层bottom的偏导
// 将关于top的偏导乘以当前层bottom中每个数据的符号
caffe_mul(count, bottom_diff, top_diff, bottom_diff);
}
}
#ifdef CPU_ONLY
STUB_GPU(AbsValLayer);
#endif
INSTANTIATE_CLASS(AbsValLayer);
REGISTER_LAYER_CLASS(AbsVal);
} // namespace caffe