快速介绍
对神经网络模型的引入,不必非要使用对人脑的比喻。实际上,根据之前课程中的线形模型,可以引申出神经网络模型。
在线性模型中,s = Wx,其中W是[10, 3072]的矩阵,x是图像像素点被拉长为[3072, 1]的矢量。两者计算得到s为[10, 1]的矢量,其每个分量对应一种类别的得分score。
由上面的式子,可以引入非线性函数,变成一个神经网络。例如一个简单的神经网络模型可以由下面式子表示,s = W2 max(0, W1x)。W2可以是[10, 100]的矩阵,W1可以是[100, 3072]的矩阵,max的计算是elementwise的。这里引入的非线性函数max是引起魔法的重要部分,如果去掉它,则公式中W2和W1可以直接相乘,则又变为了线性的计算。
粗糙的类比模型
人工智能中的神经网络模型是对生物神经网络的一个粗糙类比。对于生物神经元,其计算更加复杂。例如,生物神经元的树突可以进行复杂的非线性计算。突触并不就是一个简单的权重,它们是复杂的非线性动态系统。很多系统中,输出的峰值信号的精确时间点非常重要,说明速率编码的近似是不够全面的。
感兴趣的可以参考下面的论文
作为线性分类器的单个神经元
一个单独的神经元可以用来实现一个二分类分类器,比如二分类的Softmax或者SVM分类器。
常用激活函数
上图概括了常用的几种激活函数,及其优缺点。下面再补充几点
sigmoid由于历史原因,在过去用得很多。许多教程也会以它为入门实例进行讲解和提及,但由于其缺点,如今几乎不使用。
Leakly ReLU尝试解决ReLU的dead neuron问题。有时表现不错,但是并不总是有效、稳定。
对于maxout,ReLU、Leakly ReLU是其特殊形式。它兼具ReLU的优点(线性操作、不会饱和),也避免了其缺点(dead neuron)
如此多可选的激活函数,实际中应该选哪种呢?可以参考如下建议:
- 用ReLU非线性函数。注意设置好学习率,或许可以监控你的网络中死亡的神经元占的比例。
- 如果单元死亡问题困扰你,就试试Leaky ReLU或者Maxout,不要再用sigmoid了。也可以试试tanh,但是其效果应该不如ReLU或者Maxout。
神经网络前向传播计算的示例
# 一个3层神经网络的前向传播:
f = lambda x: 1.0/(1.0 + np.exp(-x)) # 激活函数(用的sigmoid)
x = np.random.randn(3, 1) # 含3个数字的随机输入向量(3x1)
h1 = f(np.dot(W1, x) + b1) # 计算第一个隐层的激活数据(4x1)
h2 = f(np.dot(W2, h1) + b2) # 计算第二个隐层的激活数据(4x1)
out = np.dot(W3, h2) + b3 # 神经元输出(1x1)
需要注意的是x,它代表了学习的样本集,其并非一个单独的列向量,而是一个矩阵,矩阵中的每一列对应一个样本。由于使用了矩阵运算,x表示为矩阵可以并行的对每个样本进行高效的计算,大大加快运算效率。
神经网络的表达能力:可以近似任何连续函数
现在看来,拥有至少一个隐层的神经网络是一个通用的近似器,在研究(例如1989年的论文Approximation by Superpositions of Sigmoidal Function,或者Michael Nielsen)中已经证明,简单的说就是神经网络可以近似任何连续函数。