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

#include

#include "caffe/layers/eltwise_layer.hpp"

#include "caffe/util/math_functions.hpp"

namespace caffe {

template

void EltwiseLayer::LayerSetUp(const vector*>& bottom,

const vector*>& 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(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

void EltwiseLayer::Reshape(const vector*>& bottom,

const vector*>& 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

void EltwiseLayer::Forward_cpu(

const vector*>& bottom, const vector*>& 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;

caseEltwiseParameter_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

void EltwiseLayer::Backward_cpu(const vector*>& top,

const vector& propagate_down, const vector*>& 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_ONLY

STUB_GPU(EltwiseLayer);

#endif

INSTANTIATE_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:1coeff:-1}

}​

其中A和B的系数(coefficient)都要给出!

caffe data层_Caffe 学习:Eltwise层相关推荐

  1. YOLO 卷积层代码学习

    YOLO 卷积层代码学习 卷积层的初始化 void im2col_cpu(float* data_im,int channels, int height, int width,int ksize, i ...

  2. 网络OSI七层模型学习

    网络OSI七层模型学习 七层模型概要 七层模型详解 1.应用层 定义 功能 2.表示层 定义 功能 3.会话层 定义 功能 4.传输层 定义 功能 5.网络层 定义 功能 6.数据链路层 定义 功能 ...

  3. caffe中的batchNorm层(caffe 中为什么bn层要和scale层一起使用)

    caffe中的batchNorm层 链接: http://blog.csdn.net/wfei101/article/details/78449680 caffe 中为什么bn层要和scale层一起使 ...

  4. python中digits什么意思_在Caffe中使用 DIGITS自定义Python层

    Caffe 使得我们有了使用Python自定义层的能力,而不是通常的C++/CUDA.这是一个非常有用的特性,但它的文档记录不足,难以正确实现本演练将向您展示如何使用DIGHT来学习实现Python层 ...

  5. 通过一款早期代码抽取壳入门学习 so 层分析

    1. 前言 文章开始需要提下的就是,在如今看雪论坛的用户一发关于安卓加固的文章动辄就是有关脱壳机.vmp.函数级指令抽取或者各大厂商的加固等技术的情况下,为何我要发一个代码抽取壳的分析,并且还是早期的 ...

  6. 动手学深度学习——卷积层

    从全连接到卷积 1.简单例子:分类猫和狗的图片 使用一个还不错的相机采集图片(12M像素) RGB图片有36M元素 使用100大小的单隐藏层MLP,模型有3.6B元素,远多于世界上所有猫和狗总数(90 ...

  7. (pytorch-深度学习系列)pytorch卷积层与池化层输出的尺寸的计算公式详解

    pytorch卷积层与池化层输出的尺寸的计算公式详解 要设计卷积神经网络的结构,必须匹配层与层之间的输入与输出的尺寸,这就需要较好的计算输出尺寸 先列出公式: 卷积后,池化后尺寸计算公式: (图像尺寸 ...

  8. 1.9 池化层-深度学习第四课《卷积神经网络》-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 1.8 简单卷积网络示例 回到目录 1.10 卷积神经网络示例 池化层 (Pooling Layers) 除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度, ...

  9. 转:卷积神经网络_(1)卷积层和池化层学习

    博主总结的很好,学习中.转载:http://www.cnblogs.com/zf-blog/p/6075286.htm 卷积神经网络_(1)卷积层和池化层学习 卷积神经网络(CNN)由输入层.卷积层. ...

最新文章

  1. Centos 下安装Docker 遇到的一些错误
  2. 高手进阶:/etc/profile环境变量配置解析
  3. 本科主要数学科目的页数统计
  4. .Net Core小技巧 - Hosted Services + Quartz实现定时任务调度
  5. mysql57数据库命令_MySQL 5.7 mysql command line client 使用命令详解
  6. 这6大核心技能,程序员升职加薪的利器
  7. 组态软件运行在云服务器_能在云服务器上运行软件吗
  8. python运算符讲解_举例讲解Python中的算数运算符的用法
  9. 程序员如何帮助公司快速上市、获得分红?
  10. 在oracle中 生成大规模数据 500万条 (使用导入数据方式 sqlldr 导入命令 *.ctl文件)
  11. 绝对位置,但相对于父位置
  12. 步进电机选型计算实例_滚珠丝杠选型和电机选型计算
  13. VBS基础篇 - 对象(5) - File对象
  14. 「TJOI 2013」攻击装置
  15. try-catch(C# 参考)
  16. mapxtreme 常用实例
  17. 基于Java Web的图书管理系统
  18. Java视频教程免费分享
  19. Java基础教程——字符流
  20. 数学中几种积:点积(数量积/标量积/内积)、叉积(叉乘/向量积)、外积(张量积/Kronecker积)、哈达玛积(元素积)

热门文章

  1. c++ 异常处理(2)
  2. git push代码时的‘git did not exit cleanly (exit code 1)‘问题解决
  3. 什么!在CSS中的重要意义? [重复]
  4. netty-客户端.group()方法 源码分析.md
  5. supervisor守护进程的安装配置使用
  6. [原创]浅谈对华为34岁以上员工“退休”
  7. 【Go】语法基础之结构体
  8. iOS开发UI篇—UITableviewcell的性能优化和缓存机制
  9. VS013的单元测试去哪里了
  10. Android 关于Handler