接着上一篇,本篇就开始读layers下面的cpp,先看一下layers下面都有哪些cpp。

absval_layer.cpp

其中,下面这些layer是不需要反向传播的,大部分都是io类,我们就不讲了,自己去看。

threshold_layer.cpp

剩下的就是要讲的,我们先从官方的开始看,后面再看自己写的以及一些开源的。这些layers大概有这么几大类,基础数学函数类,blob shape操作类,loss类。

本节先看一些基础函数类的layer,都只有一个输入,一个输出。注意其中有一些是容许inplace 的layer,有一些是不容许的。所谓inplace,输入输出共用一块内存,在layer的传播过程中,直接覆盖,省内存。Caffe在开源框架中,是比较占内存的了。

01

absval_layer.cpp

数学定义:

由于这是第一个例子,我们说的详细些;

Forward:

template <typename Dtype>

其中,count是blob的size,等于N*C*H*W,bottom[0]是输入x,top[0]是输出f(x),利用mutable_cpu_data来写入,cpu_data来读取。

Backward:

template <typename Dtype>

根据梯度下降法和链式法则,

一次标准的梯度更新过程如下,wt+1=wt+Δwt,对于sgd算法,其中 wt=−η⋅gt ,w为参数,t为时序,Δ为更新量,η为学习率,g为梯度

其中梯度g就是

在backward中,我们只需要计算出即可,至于上面的符号,学习率等在其他地方处理,其实就是

其中其实top_diff,就是对应:

const Dtype* top_diff = top[0]->cpu_diff();

在这里我们知道了,cpu_data就是bottom的data,而cpu_diff就是它存储的梯度,有疑问可以返回上一篇。

propagate_down是一个参数,用于控制是否容许梯度下传的,

caffe_cpu_sign(count, bottom_data, bottom_diff);实际上就是计算了梯度,

再利用caffe_mul(count, bottom_diff, top_diff, bottom_diff);

就OK了

没有对应的test文件,就不解析了。

02

exp_layer.cpp

看下caffe 关于其参数的定义:

数学定义:

// Message that stores parameters used by ExpLayer

从下面的setuplayer中可以看出,如果base不是-1,则必须是大于0的数,也就是-2,-3等是不支持的。

const Dtype base = this->layer_param_.exp_param().base();

当base=-1,也就是默认时f(x)=e^{αx+β},就是我们熟悉的指数函数了

还记得指数函数求导吧;

03

log_layer.cpp

数学定义:

同样base=-1是默认值,否则必须大于0

04

power_layer.cpp

数学定义:

梯度也是很简单的,不过为了提高计算效率,caffe尽可能的复用了中间结果,尤其是在反向传播的时候,分两种case,完整的计算大家还是去看代码,这里粘代码太难受了。

05

tanh_layer.cpp

数学定义:

这一次咱们遇到有test layer,仔细说说。

在caffe/test目录下test_tanh_layer.cpp

所谓测试,就是要验证网络的正向和反向。

这个文件是这样测试的:

先定义了个tanh_naïve函数,然后利用GaussianFille初始化一个bottom,将其通过forward函数,把出来的结果和tanh_naïve的结果进行比对,完整代码如下,感受一下:

void TestForward(Dtype filler_std) {

EXPECT_NEAR函数就会检查梯度是否正确,如果过不了,就得回去看forward函数是否有错了。

反向验证:

void TestBackward(Dtype filler_std) {

其中GradientChecker(const Dtype stepsize, const Dtype threshold,

const unsigned int seed = 1701, const Dtype kink = 0.,const Dtype kink_range = -1)

可以设置stepwise和误差阈值,CheckGradientEltwise是逐个像素检查。

06

sigmoid_layer.cpp

数学定义:

07

relu_layer.cpp

数学定义:

其中negative_slope a默认=0,退化为f(x)=max(x,0)

上面的relu其实包含了我们常说的relu和ReLU和LeakyReLU

08

prelu_layer.cpp

与LeakyReLU不同的是,负号部分的参数a是可学习的并不固定。所以,在反向传播时,该参数需要求导,默认a=0.25。

数学定义

此处的a是个变量。

首先,对x也就是bottom的求导

代码如下

if (propagate_down[0]) {

而scale参数的求导,则会稍微复杂些,如下

if (this->param_propagate_down_[0]) {

因为对于blob中第i个数据, 当i不等于k时,yi 与xk是没有关系的,但是a却与blob中的所有数据有关系。

我们重新表述一下

09

elu_layer.cpp

数学定义:

10

bnll_layer.cpp

数学定义:

这次就先这样。

同时,在我的知乎专栏也会开始同步更新这个模块,欢迎来交流

https://zhuanlan.zhihu.com/c_151876233

注:部分图片来自网络

—END—

打一个小广告,我的摄影中的图像基础技术公开课程《AI 程序员码说摄影图像基础》上线了,主要从一个图像处理工程师的角度来说说摄影中的基础技术和概念,欢迎大家订阅交流。

加入我们做点趣事

往期精彩

[caffe解读] caffe从数学公式到代码实现1-导论。

如何步入深度学习刷榜第一重境界。

为了压榨CNN模型,这几年大家都干了什么。

[caffe解读] caffe从数学公式到代码实现2-基础函数类相关推荐

  1. 【caffe解读】 caffe从数学公式到代码实现2-基础函数类

    文章首发于微信公众号<与有三学AI> [caffe解读] caffe从数学公式到代码实现2-基础函数类 接着上一篇,本篇就开始读layers下面的cpp,先看一下layers下面都有哪些c ...

  2. [caffe解读] caffe从数学公式到代码实现4-认识caffe自带的7大loss

    本节说caffe中常见loss的推导,具体包含下面的cpp. multinomial_logistic_loss_layer.cpp 01 multinomial_logistic_loss_laye ...

  3. [caffe解读] caffe从数学公式到代码实现5-caffe中的卷积

    今天要讲的就是跟卷积相关的一些layer了 im2col_layer.cpp base_conv_layer.cpp conv_layer.cpp deconv_layer.cpp inner_pro ...

  4. [caffe解读] caffe从数学公式到代码实现3-shape相关类

    接着上一篇说,本篇开始读layers下面的一些与blob shape有关的layer,比如flatten_layer.cpp等,具体包括的在下面: flatten_layer.cpp conv与dec ...

  5. [caffe解读] caffe从数学公式到代码实现1-导论

    新板块说明 今天开一个新板块,目标是死磕现有的几大机器学习框架的代码,给想入门的小白们一些帮助. 作为一个在图像行业战斗了几年的程序员,深知入门一个框架,和真的能用好一个框架是有很大的区别的,而要想走 ...

  6. JS代码规范和基础函数的使用

    JS中的一切都区分大小写(变量名,函数名,操作符) 标识符(变量名,函数名,属性名,函数的参数)按下列规则组合 就是如果要给某物起名字,按下述规则来 首字符必须是字母,下划线(_)或符号$ 其他字符可 ...

  7. 【caffe解读】 caffe从数学公式到代码实现3-shape相关类

    文章首发于微信公众号<与有三学AI> [caffe解读] caffe从数学公式到代码实现3-shape相关类 接着上一篇说,本篇开始读layers下面的一些与blob shape有关的la ...

  8. 【caffe解读】 caffe从数学公式到代码实现4-认识caffe自带的7大loss

    文章首发于微信公众号<与有三学AI> [caffe解读] caffe从数学公式到代码实现4-认识caffe自带的7大lossz 本节说caffe中常见loss的推导,具体包含下面的cpp. ...

  9. 【caffe解读】 caffe从数学公式到代码实现5-caffe中的卷积

    文章首发于微信公众号<与有三学AI> [caffe解读] caffe从数学公式到代码实现5-caffe中的卷积 今天要讲的就是跟卷积相关的一些layer了 im2col_layer.cpp ...

最新文章

  1. setTimeOut()和setInterval()的用法
  2. 《新一代SDN——VMware NSX 网络原理与实践》——导读
  3. MHA管理所有数据库服务器
  4. 20170429,上市公司2016年报全出炉(附最新排行榜)
  5. R中统计假设检验总结(一)
  6. POJ 3928 amp; HDU 2492 Ping pong(树阵评价倒数)
  7. 团队博客 第三周 设计类图
  8. 原生开发什么意思_原生APP是什么?选原生开发有哪些优势?
  9. 《那些年啊,那些事——一个程序员的奋斗史》——113
  10. 我的世界服务器mcyc.win怎么验证,RTX 2060 光线追踪效果逆天,让《我的世界》变仙境!华硕天选游戏笔记本体验教程...
  11. FFmpeg —— 15.示例程序(九):音频编码器(PCM编码为MP3)
  12. 【上古秘籍】之Eclipse的秘籍 转
  13. 查看本机mac地址/ ipconfig /all 的一点笔记
  14. 用VUE实现注册页(短信验证码登录)
  15. ngrok私有服务搭建(docker交叉编译)
  16. SpringBoot——入门(HelloWorld和探究HelloWorld)
  17. On the Factory Floor: ML Engineering for Industrial-Scale Ads Recommendation Models笔记
  18. acwing 846. 树的重心
  19. JS十进制转换16进制
  20. java写病毒_java编写小病毒程序

热门文章

  1. 面试又挂了,你理解了 Java 8 的 Consumer、Supplier、Predicate和Function吗?
  2. java大公司后端多线程面试题最强分享
  3. 玩转springboot:实现springboot自定义拦截器
  4. 蓝桥杯-区间k大数查询(java)
  5. 怎么看python环境变量配置是否好了验证图片_简述验证Anaconda是否安装成功的两种方式和Anaconda环境变量配置过程...
  6. chrome自动调节窗口大小插件_高效使用Chrome浏览器,教你10个小技巧!
  7. Java设计模式——迭代器模式
  8. Haskell语言实现判断一个整数是否是质数的代码及运行结果
  9. P1525关押罪犯(并查集补集)
  10. 微信小程序 与后台服务器交互,微信小程序 与后台交互----传递和回传时间