目录

  • 目录
  • 简单介绍
  • 主要函数
    • 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. 无法捕获的ChuckNorrisException
  2. java spring maven pdf 导出
  3. FFT和Matlab中操作FFT
  4. Oracle12c安装出错
  5. Python笔记-内置装饰器
  6. Linux常用命令笔记---创建私有YUM源
  7. nginx 多个root_dockerfile定制自己的nginx
  8. cf1042d 树状数组逆序对+离散化
  9. 书单丨724运维日,为运维人干杯
  10. doc.project java_GitHub - kanghaimeng/idoc: Generate doc for java maven project.(java 项目自动生成文档)...
  11. Atitti  css   transition Animation differ区别
  12. 【元胞自动机】基于matlab元胞自动机模拟小区车流量【含Matlab源码 358期】
  13. 哪个说了算?漫谈网吧网络的稳定和安全(转)
  14. python 修改ip地址
  15. C语言求等腰梯形面积,几道C语言的题目!
  16. oracle版本虚拟机,关于虚拟机装oracle10g64位数据库查看版本位数有趣的问题
  17. 实现选择文本时选中整个元素文本
  18. 活动现场大屏幕互动系统(微信墙)修复版完美PHP源码,带完整素材包和详细使用文档
  19. 早,每天都是一段全新的旅程
  20. 以Edge浏览器为例演示清除浏览器的缓存

热门文章

  1. 汇编实现两位数(包括负数)以内的输入,排序和输出
  2. php 替换表情符号,javascript字符串替换文本到php页面中的表情符号
  3. uniapp开发:uniapp之切换vue3,一直使用一直爽
  4. 中文拼音gun和shu以及英文字符|的区别
  5. Windows7旗舰版安装Pytorch(CPU版)
  6. RestfulCRUD 规范
  7. 为什么互联网企业 争做路由器?
  8. 王梦君 matlab,那是每个matlab程序都要有function么 “#”这个符号是什么意...
  9. 区块链学习笔记16——ETH交易树和收据树
  10. chown和chgrp和chmod的区别和使用