激活函数是连接感知机和神经网络的桥梁。朴素感知机是指单层网络,指的是激活函数使用了阶跃函数的模型。多层感知机是指神经网络,即使用sigmoid函数等平滑的激活函数的多层网络。
sigmoid函数
神经网络和感知机的主要区别就在于这个激活函数。sigmoid函数的平滑性对神经网络的学习具有重要意义。阶跃函数只能返回0和1,sigmoid函数可以返回连续的实数。
但是阶跃函数和sigmoid函数都是非线性函数,sigmoid函数是一条曲线,阶跃函数是一条折线。
# coding: utf-8
import numpy as np
import matplotlib.pylab as plt
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def step_function(x):
return np.array(x > 0, dtype=np.int)
x = np.arange(-5.0, 5.0, 0.1)
y1 = sigmoid(x)
y2 = step_function(x)
plt.plot(x, y1, label="sigmoid")
plt.plot(x, y2, 'k--', label="step_function")
plt.ylim(-0.1, 1.1) #指定图中绘制的y轴的范围
plt.xlabel("x") # x轴的标签
plt.ylabel("y") # y轴的标签
plt.title('sigmoid & step_function')
plt.legend()
plt.show()
啥叫函数?函数就是输入某个值返回一个值的转换器。
啥叫线性函数?就是向这个转换器输入某个值后,输出值是输入值的常数倍的函数。,c为常数。因此,线性函数是一条笔直的直线。
为啥神经网络不能用线性函数?因为使用线性函数,加深网络的层数就没有意义了。无论怎样加深层数,总是存在与之等效的“无隐藏层的神经网络”,无法发挥多层网络叠加带来的优势。
现在主要使用ReLU(Rectified Linear Unit)函数作为激活函数。
ReLU函数
# coding: utf-8
import numpy as np
import matplotlib.pylab as plt
def relu(x):
return np.maximum(0, x)
x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)
plt.plot(x, y, label="relu")
plt.ylim(-1.0, 5.5)
plt.xlabel("x") # x轴的标签
plt.ylabel("y") # y轴的标签
plt.title('relu')
plt.legend()
plt.show()
神经网络中不同的层使用的激活函数也不同,输出层所用的激活函数要根据求解问题的性质决定。一般回归问题可以使用恒等函数(原样输出),二元分类问题可以使用sigmoid函数,多元分类问题可以使用Softmax函数。
啥叫分类啥叫回归?分类就是数据属于哪一类别,回归是根据某个输入预测一个数值。
Softmax函数
这个公式表示假设输出层共有n个神经元,计算第k个神经元的输出,可以看出这个激活函数使得各个神经元都受到所有输入信号的影响。而且Softmax函数重要特征是,输出是0.0到1.0之间的实数,并且输出值的总和是1。因此,可以把Softmax函数的输出解释为“概率”。也就是说,通过使用Softmax函数,可以使用概率的(统计的)方法处理问题。由于使用的指数函数是单调递增的,所以即便使用了Softmax函数,各元素之间的大小关系也不会改变。因为神经网络只把输出值最大的神经元所对应的类别作为识别结果,所以使用Softmax函数,输出值最大的神经元的位置也不会改变。
softmax函数在代码实现中要注意溢出问题,因为涉及到指数计算时值会非常大,而计算机表示的数值范围是有限的(数值必须在4字节或8字节的有限数据宽度),所以结果会出现nan(not a number,不确定)的情况。因此上述的softmax函数必须进行以下改进:
分子分母同时乘C这个常数,计算结果不变。
# coding: utf-8
import numpy as np
import matplotlib.pylab as plt
def softmax(x):
x = x - np.max(x) # 溢出对策
return np.exp(x) / np.sum(np.exp(x))
x = np.arange(-5.0, 5.0, 0.1)
y = softmax(x)
plt.plot(x, y, label="softmax")
plt.ylim(-1.0, 5.5)
plt.xlabel("x") # x轴的标签
plt.ylabel("y") # y轴的标签
plt.title('softmax')
plt.legend()
plt.show()