Caffe 学习:Eltwise层
来源:互联网 发布:windows上安装hadoop 编辑:程序博客网 时间:2024/05/16 17:11
Caffe 学习:Eltwise层
Eltwise层的操作有三个:product(点乘), sum(相加减) 和 max(取大值),其中sum是默认操作。
1. PROD:按元素乘积
2. SUM:按元素求和(默认)
3. MAX:保存元素大者
该层还定义了 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 按位和,这里有coffs_为系数,可以通过指定某一输入的系数来完成按位加和按位减 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
假设输入(bottom)为A和B,如果要实现element_wise的A+B,即A和B的对应元素相加,prototxt文件如下:
layer { name: "eltwise_layer" type: "Eltwise" bottom: "A" bottom: "B" top: "diff" eltwise_param { operation: SUM }}
如果实现A-B,则prototxt为:
layer { name: "eltwise_layer" type: "Eltwise" bottom: "A" bottom: "B" top: "diff" eltwise_param { operation: SUM coeff: 1 coeff: -1 }}
其中A和B的系数(coefficient)都要给出!
转载链接:http://blog.csdn.net/m0_37407756/article/details/72556750
阅读全文
0 0
- Caffe 学习:Eltwise层
- Caffe 学习:Eltwise层
- Caffe 学习:Eltwise层
- caffe中Eltwise层
- caffe中的Eltwise层
- caffe学习:Eltwise Layer
- caffe 功能层之Eltwise层
- Eltwise层
- [Caffe]:关于Eltwise layer
- [Caffe]:关于Eltwise layer
- FCN网络中使用的caffe类型层汇总--Convolution/Deconvolution/Crop/Eltwise/SoftmaxWithLoss
- caffe 里eltwise layer 的用法
- caffe学习:层
- caffe 学习系列 视觉层
- caffe学习:数据层参数
- caffe学习系列--层解读
- caffe学习笔记24-Pooling层学习
- caffe学习(三):caffe视觉层参数
- Java 日期/cron表达式 转换
- android的边框设置
- test
- Java 异步机制与同步机制的区别
- IOS Swift3.0 URLSession和Json解析
- Caffe 学习:Eltwise层
- JavaScript初学者必看“箭头函数”
- 实现浏览器兼容版的window.getComputedStyle
- 数据库面试题
- Android studio 多渠道(多环境)打包grade配置详解
- Android 自定义Toast
- 一道有意思的题目Intersection of Two Linked Lists(双指针)
- SQL Server系统表sysobjects
- iOS 从0到1搭建高可用App框架