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