上一篇提到的感知机,虽然可以表达复杂的函数,即便是计算机进行的复杂处理也可以表示出来,但是设定参数(确定合适的w和b)确实需要人工来进行。
而神经网络就是为了解决这一问题而出现的,神经网络的一个重要性质就是它可以自动地从数据中学习到合适的参数信息。
1.激活函数出场:
感知器数学表达如下所示:
感知机将输入x1、X2分别乘以权重在加上偏置之后,将其传送到下一个神经元。在下一个神经元中会计算这些加权信号的总和,如果总和大于0将输出1,否则输出0。
现在我们引入一个新函数h(x)
,从而可以将上述式子改写成下面的式子:
其中:
这个引入的新函数h(x)
就是激活函数,它的作用就是如何将输入的信号转换为输出信号,也就是决定如何来激活输入信号。
下面我们进一步改写式子,让其分两步进行处理,即先计算输入信号的加权综合,然后在使用激活函数激活输入。
- a为输入信号的加权总和;
- y为将a使用
h(x)
函数转换得到的输出。
此时,上一篇的感知器可以表示为:
2.激活函数——阶跃函数:
上面引入的激活函数h(x)
是以某一阈值为界,一旦输入超过这个阈值就被激活,也就是输出为1。这样的函数就被称为“阶跃函数”。因此可以说感知机中使用了阶跃函数作为激活函数。
import numpy as np
import matplotlib.pyplot as plt
# 定义阶跃函数
def step_function(x):
# 对numpy数组进行判断,得到布尔数组([False,True,True])
y = x > 0:
# astype()将得到的布尔数组转换为int型([False,True,True]→[0,1,1])
return y.astype(np.int)
# 也可以简化处理为下面的表达
# return np.array(x > 0, dtype=np.int)
x = np.arange(-5.0,5.0,0.1)
y = step_function(x)
plt.plot(x,y)
# 指定y轴取值范围
plt.ylim(-0.1,1.1)
plt.show()
运行得到阶跃函数的图形表示:
可以看到阶跃函数以0为界,大于等于0输出为1,小于0输出为0,成阶梯状,因此被称为阶跃函数。
3.激活函数——sigmoid函数:
如果感知机的激活函数从阶跃函数替换成其他函数,就可以进入神经网络的世界了。
神经网络中经常使用的一个激活函数就是sigmoid函数(sigmoid function),函数公式表示为:
import numpy as np
import matplotlib.pyplot as plt
# 定义sigmoid函数
def sigmoid_function(x):
return 1 / (1 + np.exp(-x))
x = np.arange(-5.0,5.0,0.1)
y = sigmoid_function(x)
plt.plot(x,y)
# 指定y轴取值范围
plt.ylim(-0.1,1.1)
plt.show()
运行得到阶跃函数的图形表示:
3.激活函数——ReLU函数:
在神经网络发展史上,sigmoid函数很早就开始使用了,现在则主要使用ReLU函数,ReLU函数函数在输入大于0时输出该值,当输入小于等于0时输出0,函数公式表示为:
import numpy as np
import matplotlib.pyplot as plt
# 定义sigmoid函数
def relu_function(x):
return np.maximum(0,x)
x = np.arange(-5.0,5.0,0.1)
y = relu_function(x)
plt.plot(x,y)
# 指定y轴取值范围
plt.ylim(-1,5.5)
plt.show()
运行得到阶跃函数的图形表示:
4.激活函数比较分析:
比较分析上面的三个激活函数,可以发现三者之间的一些不同:
- 三个函数的“平滑性”不同;
- – 相对于阶跃函数只能返回0和1,sigmiod函数和ReLU函数都可以返回实数。也就是说感知机中神经- 元之间传递的是0或1的二元信号,而神经网络中传递的是连续的实数值信号。
Reference:
《Deep Learning from Scratch》