【caffe源碼研究】第三章:源碼篇(13) :損失層

在訓練階段有損失層,損失層需要兩個輸入的Blob,一個是網絡的預測值,一個是真實的標籤。

基類LossLayer,其他的loss繼承自這個類。

這裏以歐拉損失爲例來說明

原理

歐拉損失

E=12Nn=1N||ynyn||2

前向傳播

top:(1×1×1×1)維的歐氏距離損失E=12NNn=1||ynyn||2

反向傳播

反向計算微分E=1NNn=1(ynyn)

代碼如下

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()
  }
}
發佈了319 篇原創文章 · 獲贊 77 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章