目前所有神经网络和支撑向量机的基础都是1957年提出来的感知机。感知机(perceptron) 是二类分类的线性分类模型, 其输入为实例的特征向量, 输出为实例的类别, 取+1和–1二值。 感知机对应于输入空间(特征空间) 中将实例划分为正负两类的分离超平面, 属于判别模型。但是感知机却不能分来异或这种简单的布尔运算。后来是加入了激活函数才将感知机给拯救了回来,也才有了现在的各种神经网络。
激活函数(activation function)运行时激活神经网络中某一部分神经元,将激活信息向后传入下一层的神经网络。神经网络之所以能解决非线性问题,本质上就是激活函数加入了非线性因素,弥补了线性模型的表达力,把“激活的神经元的特征”通过函数保留并映射到下一层。
因为神经网络的数学基础是处处可微的,所以选取的激活函数要能保证数据输入与输出也是可微的。那么激活函数在 TensorFlow 中是如何表达的呢?激活函数不会更改输入数据的维度,也就是输入和输出的维度是相同的。 TensorFlow 中包括平滑非线性的激活函数,如 sigmoid、 tanh、 elu、 softplus 和 softsign,也包括连续但不是处处可微的函数 relu、 relu6、 crelu 和 relu_x,以及随机正则化函数 dropout。
上述激活函数的输入均为要计算的 x(一个张量),输出均为与 x 数据类型相同的张量。常见的激活函数有 sigmoid、 tanh、 relu 和 softplus 这 4 种。下面我们就来逐一讲解。
(1) sigmoid 函数
这是传统神经网络中最常用的激活函数之一(另一个是 tanh),对应的公式和图像如下图所示。
使用方法如下:
结果如下:
软饱和性,一旦输入落入饱和区, f'(x)就会变得接近于 0,很容易产生梯度消失。
(2) tanh 函数
对应的公式和图像如下图所示。
tanh 函数也具有软饱和性。因为它的输出以 0 为中心,收敛速度比 sigmoid 要快。但是仍无法解决梯度消失的问题。
(3) relu 函数是目前最受欢迎的激活函数
ReLU函数虽然不是Alex首次提出来的,但是当AlexNet在2012届图像识别大赛取得冠军才使其被大众所熟知。softplus可以看作是 ReLU的平滑版本。 relu定义为 f(x)=max(x,0)。softplus 定义为 f(x)=log(1+exp(x))。
由上图可见, relu 在 x<0 时硬饱和。由于 x>0 时导数为 1,所以, relu 能够在 x>0 时保持梯度不衰减,从而缓解梯度消失问题,还能够更很地收敛,并提供了神经网络的稀疏表达能力。但是,随着训练的进行,部分输入会落到硬饱和区,导致对应的权重无法更新,称为“神经元死亡”。
结果:
(4) dropout 函数。
一个神经元将以概率 keep_prob 决定是否被抑制。如果被抑制,该神经元的输出就为 0;如果不被抑制,那么该神经元的输出值将被放大到原来的 1/keep_prob 倍。
在默认情况下,每个神经元是否被抑制是相互独立的。但是否被抑制也可以通过 noise_shape 来调节。当 noise_shape[i] == shape(x)[i]时, x 中的元素是相互独立的。如果 shape(x) = [k, l, m, n],x 中的维度的顺序分别为批、行、列和通道,如果 noise_shape = [k, 1, 1, n],那么每个批和通道都是相互独立的,但是每行和每列的数据都是关联的,也就是说,要不都为 0,要不都还是原来的值。使用示例如下:
结果:
激活函数的选择:
当输入数据特征相差明显时,用 tanh 的效果会很好,且在循环过程中会不断扩大特征效果并显示出来。当特征相差不明显时, sigmoid 效果比较好。同时,用 sigmoid 和 tanh 作为激活函数时,需要对输入进行规范化,否则激活后的值全部都进入平坦区,隐层的输出会全部趋同,丧失原有的特征表达。而 relu 会好很多,有时可以不需要输入规范化来避免上述情况。因此,现在大部分的卷积神经网络都采用 relu 作为激活函数。
PS:全部摘自李嘉璇的<<TensorFlow 技术解析与实战>>第四章4.7.1节