tiny_cnn源码阅读(2)-激活函数
2016-05-29 14:46
447 查看
激活函数概述
identiti函数
sigmoid函数
relu函数
leaky_relu
elu
softmax
tanh
tanh p1m2
源码阅读
参考
数据”经过一个神经网络时,经过卷积或池化等运算后,最终输出的一个值。这个“输出值”就是经过激活函数计算的来的,反向求导,也是对激活函数来求导的。
激活函数通常有以下性质:
非线性:如果激活函数都为线性,那么神经网络的最终输出都是和输入呈线性关系;显然这不符合事实。
可导性:神经网络的优化都是基于梯度的,求解梯度时需要确保函数可导。
单调性:激活函数是单调的,否则不能保证神经网络抽象的优化问题为凸优化问题了。
输出范围有限:激活函数的输出值的范围是有限时,基于梯度的方法会更加稳定。输入值范围为(−∞,+∞),如果输出范围不加限制,虽然训练会更加高效,但是learning rate将会更小,且给工程实现带来许多困难。
f(x)≈x(x≈0):当x≈0时,需要满足这个条件。这样权重初始化为很小的值时,训练神经网络会更加高效。否则需要细心设置权重的初始值。
f(x)=1(1+e−x)
它是是连续、光滑、严格单调的非线性函数,它把数值(-inf, +inf)映射到了(0 , 1)。它的导数
df(y)=y(1−y)
f(x)=max(0,x)
当信号小于0时,输出为0;信号大于0时,输出值为信号的值。rule函数计算非常简单,只需要一个阀值就可以得到激活值,不用进行复杂的计算。使用SGD时,用rule代替sigmod/tanh的话,收敛速度会快很多。
f(x)={ax,x<0x,x≥0
使用rule时,如果一个很大的梯度经过relu神经元,那么这个神经元可能不会再对其他数据起作用了,这会造成部分这个神经元“死掉”,使用leaky_relu可以解决这个问题。a的值很小,这样可以保留部分负值信息。
定义为:当x<0时,f(x)=(e^x-x)
f(x)={a(ex−1),x<0x,x≥0
elu全称为exponential linear unit。
1、求出集合中最大的值alpha。
2、使用指数,将数值转换为0-1之间的数exp(v[i]-alpha)。
3、归一化,即将上步求得的数值求和sum,所求结果为exp(v[i]-alpha)/sum。
f(x)=ex−e−xex+e−x
它的形状和sigmod有点像,但是它是0均值的,取值范围为(-1,1)。
f(x)=exex+e−x
首先定义了基类
函数
前向传播和反向传播都是虚函数,在其派生类中有实现。
identiti函数
sigmoid函数
relu函数
leaky_relu
elu
softmax
tanh
tanh p1m2
源码阅读
参考
激活函数概述
神经网络都有各个层组成,在不同的层中,用到不同的激活函数。在看layer之前,先了解一下定义的激活函数。数据”经过一个神经网络时,经过卷积或池化等运算后,最终输出的一个值。这个“输出值”就是经过激活函数计算的来的,反向求导,也是对激活函数来求导的。
激活函数通常有以下性质:
非线性:如果激活函数都为线性,那么神经网络的最终输出都是和输入呈线性关系;显然这不符合事实。
可导性:神经网络的优化都是基于梯度的,求解梯度时需要确保函数可导。
单调性:激活函数是单调的,否则不能保证神经网络抽象的优化问题为凸优化问题了。
输出范围有限:激活函数的输出值的范围是有限时,基于梯度的方法会更加稳定。输入值范围为(−∞,+∞),如果输出范围不加限制,虽然训练会更加高效,但是learning rate将会更小,且给工程实现带来许多困难。
f(x)≈x(x≈0):当x≈0时,需要满足这个条件。这样权重初始化为很小的值时,训练神经网络会更加高效。否则需要细心设置权重的初始值。
identiti函数
从名字看出,这是个“相等”学习函数,数据通过这个函数不会有任何变化。所以其函数float_t f(const vec_t& v, cnn_size_t i)返回变量的值,求导时导数为
1。
sigmoid函数
sigmoid函数定义为:f(x)=1(1+e−x)
它是是连续、光滑、严格单调的非线性函数,它把数值(-inf, +inf)映射到了(0 , 1)。它的导数
df(y)=y(1−y)
relu函数
relu函数定义为f(x)=max(0,x)
当信号小于0时,输出为0;信号大于0时,输出值为信号的值。rule函数计算非常简单,只需要一个阀值就可以得到激活值,不用进行复杂的计算。使用SGD时,用rule代替sigmod/tanh的话,收敛速度会快很多。
leaky_relu
leaky_relu定义为:f(x)={ax,x<0x,x≥0
使用rule时,如果一个很大的梯度经过relu神经元,那么这个神经元可能不会再对其他数据起作用了,这会造成部分这个神经元“死掉”,使用leaky_relu可以解决这个问题。a的值很小,这样可以保留部分负值信息。
定义为:当x<0时,f(x)=(e^x-x)
elu
elu定义为:f(x)={a(ex−1),x<0x,x≥0
elu全称为exponential linear unit。
softmax
softmax用来归一化,把输出值归一化为(0,1)之间的值,且总和为1。对于SoftMax输出,可以理解为概率。计算过程为:1、求出集合中最大的值alpha。
2、使用指数,将数值转换为0-1之间的数exp(v[i]-alpha)。
3、归一化,即将上步求得的数值求和sum,所求结果为exp(v[i]-alpha)/sum。
tanh
tanh的定义为f(x)=ex−e−xex+e−x
它的形状和sigmod有点像,但是它是0均值的,取值范围为(-1,1)。
tanh p1m2
这是tanh的变形,定义为:f(x)=exex+e−x
源码阅读
激活函数在tiny-cnn-master/tiny_cnn/activations/activation_function.h中。首先定义了基类
function
class function { public: function() = default; function(const function &) = default; #ifndef CNN_DEFAULT_MOVE_CONSTRUCTOR_UNAVAILABLE function(function &&) = default; #endif function &operator =(const function &) = default; #ifndef CNN_DEFAULT_ASSIGNMENT_OPERATOR_UNAVAILABLE function &operator =(function &&) = default; #endif virtual ~function() = default; virtual float_t f(const vec_t& v, cnn_size_t index) const = 0;//前向传播 // dfi/dyi virtual float_t df(float_t y) const = 0;//反向求导 // dfi/dyk (k=0,1,..n) virtual vec_t df(const vec_t& y, cnn_size_t i) const { vec_t v(y.size(), 0); v[i] = df(y[i]); return v; } // target value range for learning virtual std::pair<float_t, float_t> scale() const = 0;//输出值的范围 };
函数
float_t f(const vec_t&, cnn_size_t index)为前向传播,
float_t df(float_t y)和
vec_t df(const vec_t& y, cnn_size_t i)为求导,前者是对一个数求导,后者是对容器所有数求导。
std::pair<float_t, float_t> scale()是来控制函数输出的范围。
前向传播和反向传播都是虚函数,在其派生类中有实现。
参考
【机器学习】神经网络-激活函数-面面观(Activation Function)相关文章推荐
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 用Python从零实现贝叶斯分类器的机器学习的教程
- My Machine Learning
- 机器学习---学习首页 3ff0
- Spark机器学习(一) -- Machine Learning Library (MLlib)
- bp神经网络及matlab实现
- CUDA搭建
- 反向传播(Backpropagation)算法的数学原理
- 深入理解CNN的细节
- 关于SVM的那点破事
- 也谈 机器学习到底有没有用 ?
- TensorFlow人工智能引擎入门教程之九 RNN/LSTM循环神经网络长短期记忆网络使用
- TensorFlow人工智能引擎入门教程之十 最强网络 RSNN深度残差网络 平均准确率96-99%
- TensorFlow人工智能引擎入门教程所有目录
- 在 Qt4 中使用 C++11
- 如何用70行代码实现深度神经网络算法
- 量子计算机编程原理简介 和 机器学习
- 近200篇机器学习&深度学习资料分享(含各种文档,视频,源码等)