Caffe源码(十):eltwise_layer 分析
目录
- 目录
- 简单介绍
- 主要函数
- 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 分析相关推荐
- Caffe源码中common文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中的一些重要头文件如caffe.hpp.blob.hpp等或者外部调用Caffe库使用时,一般都会in ...
- caffe源码分析--SyncedMemory 内存管理机制
caffe源码分析–SyncedMemory 内存管理机制 SyncedMemory 是caffe中用来管理内存分配和CPU.GPU数据及同步的类,只服务于Blob类.SyncedMemory 对 ...
- caffe源码深入学习6:超级详细的im2col绘图解析,分析caffe卷积操作的底层实现
在先前的两篇博客中,笔者详细解析了caffe卷积层的定义与实现,可是在conv_layer.cpp与base_conv_layer.cpp中,卷积操作的实现仍然被隐藏,通过im2col_cpu函 ...
- caffe源码分析-layer
本文主要分析caffe layer层,主要内容如下: 从整体上说明下caffe的layer层的类别,以及作用 通过proto定义与类Layer简要说明下Layer的核心成员变量; Layer类的核心成 ...
- Caffe源码中Solver文件分析
Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/solver.hpp文件的 ...
- Caffe源码中Net文件分析
Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/net.hpp文件的内容: ...
- Caffe源码中Pooling Layer文件分析
Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/vision_layers ...
- Caffe源码中layer文件分析
Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/layer.hpp文件的内 ...
- Caffe源码中io文件分析
Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/util/io.hpp文件 ...
- Caffe源码中blob文件分析
Caffe源码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/blob.hpp文件的内容 ...
最新文章
- 无法捕获的ChuckNorrisException
- java spring maven pdf 导出
- FFT和Matlab中操作FFT
- Oracle12c安装出错
- Python笔记-内置装饰器
- Linux常用命令笔记---创建私有YUM源
- nginx 多个root_dockerfile定制自己的nginx
- cf1042d 树状数组逆序对+离散化
- 书单丨724运维日,为运维人干杯
- doc.project java_GitHub - kanghaimeng/idoc: Generate doc for java maven project.(java 项目自动生成文档)...
- Atitti css transition Animation differ区别
- 【元胞自动机】基于matlab元胞自动机模拟小区车流量【含Matlab源码 358期】
- 哪个说了算?漫谈网吧网络的稳定和安全(转)
- python 修改ip地址
- C语言求等腰梯形面积,几道C语言的题目!
- oracle版本虚拟机,关于虚拟机装oracle10g64位数据库查看版本位数有趣的问题
- 实现选择文本时选中整个元素文本
- 活动现场大屏幕互动系统(微信墙)修复版完美PHP源码,带完整素材包和详细使用文档
- 早,每天都是一段全新的旅程
- 以Edge浏览器为例演示清除浏览器的缓存
热门文章
- 汇编实现两位数(包括负数)以内的输入,排序和输出
- php 替换表情符号,javascript字符串替换文本到php页面中的表情符号
- uniapp开发:uniapp之切换vue3,一直使用一直爽
- 中文拼音gun和shu以及英文字符|的区别
- Windows7旗舰版安装Pytorch(CPU版)
- RestfulCRUD 规范
- 为什么互联网企业 争做路由器?
- 王梦君 matlab,那是每个matlab程序都要有function么 “#”这个符号是什么意...
- 区块链学习笔记16——ETH交易树和收据树
- chown和chgrp和chmod的区别和使用