代码笔记:caffe-reid中PairEuclideanLayer源码解析

这是作者自己实现的一个caffe层,用于计算输入的bottum层中一对数据的欧式距离。

#include <vector>

#include "caffe/layers/euclidean_layer.hpp"
#include "caffe/util/math_functions.hpp"

在train.proto文件中,该层的表述是这样的。有两个输入层,两个输出层。

layer {
  name: "euclidean"
  type: "PairEuclidean"
  bottom: "fc7"
  bottom: "label"
  top: "euclidean"
  top: "label_dif"
}
namespace caffe {
(1#首先是Reshape函数,该函数用来确定输入的向量以及输出的向量
template <typename Dtype>
void PairEuclideanLayer<Dtype>::Reshape(
  const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
  if (bottom.size() == 2) this->output_labels_ = true;
  else                    this->output_labels_ = false;
  CHECK_EQ(bottom.size(), top.size());
  CHECK_EQ(bottom[0]->num()%2, 0);

  # bottom: "fc7"
  # top[0]: "euclidean",其维度是"fc7"的一半
  top[0]->Reshape(bottom[0]->num()/2, bottom[0]->channels(), bottom[0]->height(), bottom[0]->width());
  CHECK_EQ(bottom[0]->count()/2, top[0]->count());
  if (this->output_labels_) {
    CHECK_EQ(bottom[0]->num(), bottom[1]->num());
    CHECK_EQ(bottom[1]->num(), bottom[1]->count());
    vector<int> shape(1, top[0]->num());
    #top: "label_dif"
    #其长度与top[0]保持一致
    top[1]->Reshape(shape);
  }
  diff_.ReshapeLike(*top[0]);
}
(2)前向传播
template <typename Dtype>
void PairEuclideanLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
    const vector<Blob<Dtype>*>& top) {
  Dtype* top_data = top[0]->mutable_cpu_data();
  const int count = top[0]->count();
  const Dtype* A_data = bottom[0]->cpu_data();
  const Dtype* B_data = bottom[0]->cpu_data() + count;
  caffe_sub(
      count,
      A_data,
      B_data,
      diff_.mutable_cpu_data());
  caffe_mul(count, diff_.cpu_data(), diff_.cpu_data(), top_data);

  if (this->output_labels_) {
    #bottom[1]是输出的"label",每个label都是有两个维度的
    const int count_label = top[1]->count();
    const Dtype* A_label = bottom[1]->cpu_data();
    const Dtype* B_label = bottom[1]->cpu_data() + count_label;
    Dtype* top_label = top[1]->mutable_cpu_data();
    for (int i = 0; i < count_label; i++) {
      top_label[i] = A_label[i] == B_label[i];
    }
  }
}

template <typename Dtype>
void PairEuclideanLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
    const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
  if (propagate_down[0]) {
    const int count = top[0]->count();
    Dtype* diff = bottom[0]->mutable_cpu_diff();
    caffe_mul(count, top[0]->cpu_diff(), diff_.cpu_data(), diff);
    caffe_cpu_scale(count, Dtype(2), diff, diff);
    diff += count;
    caffe_mul(count, top[0]->cpu_diff(), diff_.cpu_data(), diff);
    caffe_cpu_scale(count, Dtype(-2), diff, diff);
  }
}

#ifdef CPU_ONLY
STUB_GPU(PairEuclideanLayer);
#endif

INSTANTIATE_CLASS(PairEuclideanLayer);
REGISTER_LAYER_CLASS(PairEuclidean);

}  // namespace caffe
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值