目录

  • 目录
  • 简单介绍
  • 主要函数
    • LayerSetUp 函数
    • Reshape 函数
    • Forward_cpu 函数
    • Backward_cpu 函数

简单介绍

eltwise_layer 实现多个blobs element-wise 的相加,相乘或者取最大值。

主要函数

1.LayerSetUp 函数:

template <typename Dtype>
void EltwiseLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {CHECK(this->layer_param().eltwise_param().coeff_size() == 0|| this->layer_param().eltwise_param().coeff_size() == bottom.size()) <<"Eltwise Layer takes one coefficient per bottom blob.";// 如果存在系数,则每个blob 对应一个系数CHECK(!(this->layer_param().eltwise_param().operation()== EltwiseParameter_EltwiseOp_PROD&& this->layer_param().eltwise_param().coeff_size())) <<"Eltwise layer only takes coefficients for summation.";op_ = this->layer_param_.eltwise_param().operation();//默认为SUM// Blob-wise coefficients for the elementwise operation.coeffs_ = vector<Dtype>(bottom.size(), 1);//将系数初始化为1if (this->layer_param().eltwise_param().coeff_size()) {for (int i = 0; i < bottom.size(); ++i) {coeffs_[i] = this->layer_param().eltwise_param().coeff(i);}//coeffs_ 存放从protobuf 传入的每个系数的值}stable_prod_grad_ = this->layer_param_.eltwise_param().stable_prod_grad();//默认true
}

2.Reshape 函数:

template <typename Dtype>
void EltwiseLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {for (int i = 1; i < bottom.size(); ++i) {CHECK(bottom[i]->shape() == bottom[0]->shape());}//输入的每个bottom要有相同的shapetop[0]->ReshapeLike(*bottom[0]);  // 输入和输出的shape相同// If max operation, we will initialize the vector index part.if (this->layer_param_.eltwise_param().operation() ==EltwiseParameter_EltwiseOp_MAX && top.size() == 1) {max_idx_.Reshape(bottom[0]->shape());//存放取最大值时的index}
}

3.Forward_cpu 函数:

template <typename Dtype>
void EltwiseLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {int* mask = NULL;const Dtype* bottom_data_a = NULL;const Dtype* bottom_data_b = NULL;const int count = top[0]->count();Dtype* top_data = top[0]->mutable_cpu_data();switch (op_) {case EltwiseParameter_EltwiseOp_PROD:    caffe_mul(count, bottom[0]->cpu_data(), bottom[1]->cpu_data(), top_data);//输出top为输入的两个bottom的element-wise乘积 for (int i = 2; i < bottom.size(); ++i) {caffe_mul(count, top_data, bottom[i]->cpu_data(), top_data);} //将所有输入的bottom做element-wise乘积break;case EltwiseParameter_EltwiseOp_SUM:caffe_set(count, Dtype(0), top_data);// TODO(shelhamer) does BLAS optimize to sum for coeff = 1?for (int i = 0; i < bottom.size(); ++i) {caffe_axpy(count, coeffs_[i], bottom[i]->cpu_data(), top_data);}// 输出top 为 所有输入bottom乘以对应系数之和break;case EltwiseParameter_EltwiseOp_MAX:// Initializemask = max_idx_.mutable_cpu_data();caffe_set(count, -1, mask);//初始化mask所有elements 为-1caffe_set(count, Dtype(-FLT_MAX), top_data);// 初始化top所有element 为负无穷// bottom 0 & 1bottom_data_a = bottom[0]->cpu_data();bottom_data_b = bottom[1]->cpu_data();for (int idx = 0; idx < count; ++idx) {if (bottom_data_a[idx] > bottom_data_b[idx]) {top_data[idx] = bottom_data_a[idx];  // maxvalmask[idx] = 0;  // maxid } else {top_data[idx] = bottom_data_b[idx];  // maxvalmask[idx] = 1;  // maxid}}//bottom 0 和bottom 1 做比较// bottom 2++for (int blob_idx = 2; blob_idx < bottom.size(); ++blob_idx) {bottom_data_b = bottom[blob_idx]->cpu_data();for (int idx = 0; idx < count; ++idx) {if (bottom_data_b[idx] > top_data[idx]) {top_data[idx] = bottom_data_b[idx];  // maxvalmask[idx] = blob_idx;  // maxid 更新为当前最大值的bottom id}//}}break;default:LOG(FATAL) << "Unknown elementwise operation.";}
}

4.Backward_cpu 函数:

template <typename Dtype>
void EltwiseLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {const int* mask = NULL;const int count = top[0]->count();const Dtype* top_data = top[0]->cpu_data();const Dtype* top_diff = top[0]->cpu_diff();for (int i = 0; i < bottom.size(); ++i) {if (propagate_down[i]) {const Dtype* bottom_data = bottom[i]->cpu_data();Dtype* bottom_diff = bottom[i]->mutable_cpu_diff();switch (op_) {case EltwiseParameter_EltwiseOp_PROD:if (stable_prod_grad_) {bool initialized = false;for (int j = 0; j < bottom.size(); ++j) {if (i == j) { continue; }if (!initialized) {caffe_copy(count, bottom[j]->cpu_data(), bottom_diff);initialized = true;} else {caffe_mul(count, bottom[j]->cpu_data(), bottom_diff,bottom_diff);}//对于bottom[i]导数为除了自己外输入bottom的element-wise 乘积}} else {5caffe_div(count, top_data, bottom_data, bottom_diff);}caffe_mul(count, bottom_diff, top_diff, bottom_diff);//乘以上一层传下来的导数top_diffbreak;case EltwiseParameter_EltwiseOp_SUM:if (coeffs_[i] == Dtype(1)) {caffe_copy(count, top_diff, bottom_diff);} else {caffe_cpu_scale(count, coeffs_[i], top_diff, bottom_diff);}break;case EltwiseParameter_EltwiseOp_MAX:mask = max_idx_.cpu_data();for (int index = 0; index < count; ++index) {Dtype gradient = 0;if (mask[index] == i) {gradient += top_diff[index];}bottom_diff[index] = gradient;}//当该bottom的index值取为最大时,继承top_diff在该index的值,其他位置为0;break;default:LOG(FATAL) << "Unknown elementwise operation.";}}}
}

Caffe源码(十):eltwise_layer 分析相关推荐

  1. Caffe源码中common文件分析

    Caffe源码(caffe version:09868ac , date: 2015.08.15)中的一些重要头文件如caffe.hpp.blob.hpp等或者外部调用Caffe库使用时,一般都会in ...

  2. caffe源码分析--SyncedMemory 内存管理机制

    caffe源码分析–SyncedMemory 内存管理机制 ​ SyncedMemory 是caffe中用来管理内存分配和CPU.GPU数据及同步的类,只服务于Blob类.SyncedMemory 对 ...

  3. caffe源码深入学习6:超级详细的im2col绘图解析,分析caffe卷积操作的底层实现

       在先前的两篇博客中,笔者详细解析了caffe卷积层的定义与实现,可是在conv_layer.cpp与base_conv_layer.cpp中,卷积操作的实现仍然被隐藏,通过im2col_cpu函 ...

  4. caffe源码分析-layer

    本文主要分析caffe layer层,主要内容如下: 从整体上说明下caffe的layer层的类别,以及作用 通过proto定义与类Layer简要说明下Layer的核心成员变量; Layer类的核心成 ...

  5. Caffe源码中Solver文件分析

    Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/solver.hpp文件的 ...

  6. Caffe源码中Net文件分析

    Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/net.hpp文件的内容: ...

  7. Caffe源码中Pooling Layer文件分析

    Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/vision_layers ...

  8. Caffe源码中layer文件分析

    Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/layer.hpp文件的内 ...

  9. Caffe源码中io文件分析

    Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/util/io.hpp文件 ...

  10. Caffe源码中blob文件分析

    Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/blob.hpp文件的内容 ...

最新文章

  1. SAP WebClient UI界面元素ID生成的逻辑分析
  2. laravel mysql视图,在 Laravel 视图文件中引入 bootstrap
  3. 简单介绍WaitForSingleObject / WaitForMultipleObjects
  4. 创建和使用约束Constraint
  5. HTML CSS JS 特殊字符(转义)表
  6. elementUI压缩图片和将图片转成base64格式
  7. Unit Testing with JUnit - Tutorial
  8. 使用Flash绘制曲线动画
  9. Arduino Uno 实验7——SG90舵机
  10. 【考研数学】二. 一元函数积分学
  11. sessionStorage和localStorage
  12. 写得太好了,大约《越狱》批评(发布)
  13. Python TIN网生成(Delaunay三角形)
  14. CI/CD---使用新版云效流水线自动部署Java项目
  15. Codeforces-1487 D. Pythagorean Triples(数学)
  16. 前端——知乎APP“我的收藏”勾选优化想法
  17. Adobe或QQ的oxc000007b错误解决方案.
  18. (附源码)计算机毕业设计SSM语言学习系统
  19. 中文文本纠错神器Pycorrector是如何收获2000 Star的?
  20. GYM 100285 I. The old Padawan(二分+简单模拟)

热门文章

  1. 邓正平:智能硬件大众化任务交给京东
  2. 小长假出游攻略之新加坡圣淘沙
  3. 【推荐】比IPH5更爱疯的G5
  4. 解决winrar解压出现crc校验错误的一个方法
  5. UDS-协议数据单元介绍
  6. 购买php,购买 · 【正版】PHP小程序拼团 · 看云
  7. 高德地图 判断打的点是否在圈内
  8. 特权容器以及安全隐患的规避
  9. windows开机密码问题
  10. 沧州一中高考2021成绩查询,沧州一中2019高考喜报成绩、一本二本上线人数情况...