[Caffe]:关于Eltwise layer
来源:互联网 发布:matlab求解优化问题 编辑:程序博客网 时间:2024/06/04 19:49
Eltwise : element-wise
eltwise layer是caffe提供的按元素操作层。它支持3种基本操作:
1. PROD:按元素乘积
2. SUM:按元素求和(默认)
3. MAX:保存元素大者
进行何种操作可以在layer里面通过定义EltwiseOp : x #x:=0,1,2
除此之外,该层还定义了
coeff
参数,该参数只对SUM操作起作用。
最后,caffe还设定了stable_prod_grad #[default = true ]
来选择是否渐进较慢的梯度计算方法,该方法只适用于PROD操作,对SUM操作无效。
更多细节参见下面的源码。
eltwise_layer 源码
#include <cfloat>#include <vector>#include "caffe/layers/eltwise_layer.hpp"#include "caffe/util/math_functions.hpp"namespace caffe {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."; 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(); // Blob-wise coefficients for the elementwise operation. coeffs_ = vector<Dtype>(bottom.size(), 1); if (this->layer_param().eltwise_param().coeff_size()) { for (int i = 0; i < bottom.size(); ++i) { coeffs_[i] = this->layer_param().eltwise_param().coeff(i); } } stable_prod_grad_ = this->layer_param_.eltwise_param().stable_prod_grad();}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()); } top[0]->ReshapeLike(*bottom[0]); // 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()); }}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_) { //choose different operations according to op_ case EltwiseParameter_EltwiseOp_PROD: //PROD,按位乘 caffe_mul(count, bottom[0]->cpu_data(), bottom[1]->cpu_data(), top_data); for (int i = 2; i < bottom.size(); ++i) { caffe_mul(count, top_data, bottom[i]->cpu_data(), top_data); } break; case EltwiseParameter_EltwiseOp_SUM: //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); } break; case EltwiseParameter_EltwiseOp_MAX: //按位取大数 // Initialize mask = max_idx_.mutable_cpu_data(); caffe_set(count, -1, mask); caffe_set(count, Dtype(-FLT_MAX), top_data); // bottom 0 & 1 bottom_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]; // maxval mask[idx] = 0; // maxid } else { top_data[idx] = bottom_data_b[idx]; // maxval mask[idx] = 1; // maxid } } // 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]; // maxval mask[idx] = blob_idx; // maxid } } } break; default: LOG(FATAL) << "Unknown elementwise operation."; }}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); } } } else { caffe_div(count, top_data, bottom_data, bottom_diff); } caffe_mul(count, bottom_diff, top_diff, bottom_diff); break; 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; } break; default: LOG(FATAL) << "Unknown elementwise operation."; } } }}#ifdef CPU_ONLYSTUB_GPU(EltwiseLayer);#endifINSTANTIATE_CLASS(EltwiseLayer);REGISTER_LAYER_CLASS(Eltwise);} // namespace caffe
0 0
- [Caffe]:关于Eltwise layer
- [Caffe]:关于Eltwise layer
- caffe学习:Eltwise Layer
- caffe 里eltwise layer 的用法
- Caffe 学习:Eltwise层
- Caffe 学习:Eltwise层
- Caffe 学习:Eltwise层
- caffe中Eltwise层
- caffe中的Eltwise层
- [Caffe]:关于SPP Layer
- [Caffe]: 关于Scale layer
- [Caffe]: 关于concat layer
- [Caffe]:关于编写specific layer
- caffe 功能层之Eltwise层
- [Caffe]:关于ReLU、LeakyReLU 、PReLU layer
- caffe中关于layer定义的笔记
- caffe layer
- caffe layer
- 蓝桥杯 历届试题 兰顿蚂蚁
- NSURLSession与NSURLConnection区别
- java使用fat.jar 打成架包
- 闲谈Objective-C编程语言(内含不包含任何框架的Objective-C代码)
- 第四章 案例研究 javascript图片库
- [Caffe]:关于Eltwise layer
- FragmentPagerAdapter与FragmentStatePagerAdapter区别
- 指针对数组排序选择法和冒泡法
- ssl 2374 NOIP2014提高组第一天第三题 飞扬的小鸟
- 固定窗体大小
- 使用libimobiledevice在linux上挂载iphone6
- 互联网企业的敏捷开发之道
- 设计模式之装饰者模式
- 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?