@nrailgun
2015-09-19T17:10:18.000000Z
字数 2127
阅读 3972
机器学习
Caffe 以 loss_layer
为基类,派生各种损失层:
通常不需要实现神经元层,只需要实现 data_layer
和 loss_layer
。loss_layer
的实现简单一些,但是要考虑一些微积分求导数问题。
反向传播的数学形式定义为:
定义:
回到 Caffe,在 Caffe 的 loss_layer
,你必须计算其
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());
Dtype loss = dot / bottom[0]->num() / Dtype(2);
top[0]->mutable_cpu_data()[0] = loss;
}
Forward_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]) {
const Dtype sign = (i == 0) ? 1 : -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
}
}
}
恩,稍微不那么直观,则表示的含义是:
大体上,Caffe 的反向实现便是如此。称不上神秘;但是贾杨清的思路如此清晰,确实非常厉害。但是还是存在一些疑问,没读过神经元层的实现,对反向整体实现过程还有不解,不过暂时可以实现损失层了,哈哈。