首先,我们要先明确一点:什么是激活函数?
在构建神经网络时,神经网络中的每个神经元节点接受上一层神经元的输出值作为本神经元的输入值,并将输入值传递给下一层,输入层神经元节点会将输入属性值直接传递给下一层(隐藏层或者输出层),在多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,这个函数就被称为激活函数。
为什么要引入激活函数呢?
简单来说,激活函数是指如何把“激活的神经元特征”通过函数把特征保留并映射出来,负责将神经元的输入映射到输出端。
如果不用激活函数,在这种情况下每一层输出都是上层输入的线性函数。容易验证,无论神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,这种情况就是最原始的感知机。加入激活函数之后,给神经元引入非线性因素,神经网络就可以任意逼近任何非线性函数,这样神经网络就可以应用到非线性模型中。
激活函数ReLU(Rectified Linear Unit)由下式表示。
根据上述公式,可以求出y关于x的导数,由下式表示。
在导数公式中,如果正向传播时的输入x大于0,则反向传播会将上游的值原封不动的传给下游。反过来,如果正向传播时的x小于等于0,则反向传播中传给下游的信号将停在此处。如下图1.1所示。
图1.1 ReLu层的计算图
现在,我们来实现ReLu()层,代码实现如下图1.2所示。
图1.2 ReLu()函数的实现代码
Relu类有实例变量mask。这个变量mask是由True/False构成的NumPy数组,它会把正向传播时的输入x的元素中,小于等于0的地方保存为True,其他地方(大于0)保存为False。如下例所示,mask变量保存了由True/False构成的NumPy数组。
如上图所示,如果正向传播时的输入值小于等于0,则反向传播的值为0。因此,反向传播中会使用正向传播时保存的mask,将从上游传来的dout的mask中的元素为True的地方设为0。
因此,ReLU层的作用就像电路的开关一样。正向传播时,有电流通过的话,就将开关设为ON;没有电流通过的话,就将开关设为OFF。反向传播时,如果开关为ON,电流直接通;开关为OFF的话,则不会有电流通过。