转载自:神经网络基础,深度学习系列(1):神经网络与反向传播算法
神经元模型
1943年,McCulloch和Pitts将上图的神经元结构用一种简单的模型进行了表示,构成了一种人工神经元模型,也就是我们现在经常用到的“M-P神经元模型”,如下图所示:
从上图M-P神经元模型可以看出,神经元的输出:$$y=f(sum_{i=1}^nw_ix_i- heta)$$
其中( heta)为神经元的激活阈值,函数(f(·))也被称为是激活函数。如上图所示,函数(f(·))可以用一个阶跃方程表示,大于阈值激活;否则则抑制。但是这样有点太粗暴,因为阶跃函数不光滑,不连续,不可导,因此我们更常用的方法是用sigmoid函数或tanh函数来表示函数(f(·))。
sigmoid函数的表达式和分布图如下所示:(f(x) = frac{1}{1+e^{-x}})
tanh函数的表达式和分布图如下:(f(z)=tanh(z)=frac{e^z-e^{-z}}{e^z+e^{-z}})
tanh(z) 函数是sigmoid函数的一种变体,它的取值范围为[-1,1] ,而不是sigmoid函数的[0,1] 。
如果选择sigmoid函数,那么它的导数就是(f'(z)=f(z)(1-f(z)));如果选择tanh函数,则它的导数是(f'(z)=1-f(z)^2)。可以根据sigmoid或tanh函数的定义自行推导。
感知机
这部分可以看之前的博客深度学习基础——感知机
神经网络模型
神经网络就是将许多神经元联结在一起,这样,一个神经元的输出就可以是另一神经元的输入。例如,下图就是一个简单的神经网络:
我们使用圆圈来表示神经网络的输入,标上”+1”的圆圈被称为偏置节点,也就是截距项。神经网络最左边的一层叫做输入层,最右边的一层叫做输出层(本例中,输出层只有一个节点)。中间所有节点组成的一层叫做隐藏层,如此命名是因为我们不能在训练样本中观测到它们的值。同时可以看到,以上神经网络的例子中有3个输入单元(偏置单元不算在内),三个隐藏单元及一个输出单元。
我们用(n_l)表示神经网络的层数,本例中(n_l=3),我们将第(l)层记为(L_l),于是(L_l)是输入层,输出层是(L_{nl})。本例神经网络有参数((W,b)=(W^{(1)},b^{(1)},W^{(2)},b^{(2)})),其中(W_{ij}^{(l)})是第l层第j个单元与第l+1层第i单元之间的联接参数(其实就是连接线上的权重,注意标号前后顺序),(b_i^{(l)})是第l+1层第i个单元的偏置项。(color{red}{偏置单元没有输入,即没有单元连向偏置单元,它们总是输出+1。(这里我没看懂是什么意思……)})同时,我们用(s_l)表示第l层的节点数(偏置单元不计在内)。
P.S.这里我问了一下师姐,师姐给我的解释是可以假设两种解释,一种是y=Wx+b,这样相当于在b后面再乘了一个1,y=Wx+b*1,把1也作为一个x,在反向传播时同时对W和b求导调整;一种是y=W[x;1],W变成(n+1) * (n+1)矩阵,反向传播对W进行求导,也类似对b进行调整.
我们用(a_i^{(l)})表示第l层第i个单元的激活值(输出值)。当l=1时,(a_i^{(1)}=x_i)也就是第i个输入值(输入值的第i个特征)。对于给定参数集合W,b,我们的神经网络就可以按照函数(h_{W,b}(x))来计算结果。本例中神经网络的计算步骤如下:
神经网络的矩阵表示
首先我们把隐藏层4个节点的计算依次排列出来:$$a_4=f(w_{41}x_1+w_{42}x_2+w_{43}x_3+w_{4b})$$$$a_5=f(w_{51}x_1+w_{52}x_2+w_{53}x_3+w_{5b})$$$$a_6=f(w_{61}x_1+w_{62}x_2+w_{63}x_3+w_{6b})$$$$a_7=f(w_{71}x_1+w_{72}x_2+w_{73}x_3+w_{7b})$$
接着,定义神经网络的输入向量(vec{x}) 和隐藏层每个节点的权重向量(vec{w_j})。令$$vec{x}=left[ egin{matrix} x_1 x_2 x_3 1 end{matrix}
ight]$$$$vec{w_4}=[w_{41},w_{42},w_{43},w_{4b}]$$$$vec{w_5}=[w_{51},w_{52},w_{53},w_{5b}]$$$$vec{w_6}=[w_{61},w_{62},w_{63},w_{6b}]$$$$vec{w_7}=[w_{71},w_{72},w_{73},w_{7b}]$$
代入之前的一组式子,得到$$a_4=f(vec{w_4}·vec{x})$$$$a_5=f(vec{w_5}·vec{x})$$$$a_6=f(vec{w_6}·vec{x})$$$$a_7=f(vec{w_7}·vec{x})$$
现在,我们把上述计算(a_4,a_5,a_6,a_7)的四个式子写到一个矩阵里面,每个式子作为矩阵的一行,就可以利用矩阵来表示他们的计算了。令$$vec{a}=left[ egin{matrix} a_4 a_5 a_6 a_7 end{matrix}
ight]$$$$vec{W}=left[ egin{matrix} vec{w_4} vec{w_5} vec{w_6} vec{w_7} end{matrix}
ight] = left[ egin{matrix} vec{w_{41}} vec{w_{42}} vec{w_{43}} vec{w_{4b}} vec{w_{51}} vec{w_{52}} vec{w_{53}} vec{w_{5b}} vec{w_{61}} vec{w_{62}} vec{w_{63}} vec{w_{6b}} vec{w_{71}} vec{w_{72}} vec{w_{73}} vec{w_{7b}} end{matrix}
ight]$$ $$fleft( egin{matrix} left[ egin{matrix} x_1 x_2 … … end{matrix}
ight] end{matrix}
ight) = left( egin{matrix} f(x_1) f(x_2) f(x_3) …end{matrix}
ight)$$
代入前面的一组式子,得到(vec{a}=f(W·vec{x}))在上式中,f是激活函数,在本例中为sigmoid函数;W是某一层的权重矩阵;(vec{x})是某层的输入向量;(vec{a}) 是某层的输出向量。它说明了神经网络的每一层的作用实际上就是先将输入向量左乘一个数组进行线性变换,得到一个新的向量,然后再对这个向量逐元素应用一个激活函数。
每一层的算法都是一样的。比如,对于包含一个输入层,一个输出层和三个隐藏层的神经网络,我们假设其权重举证分别为(W_1,W_2,W_3,W_4),每个隐藏层的输出分别是(vec{a_1},vec{a_2},vec{a_3}),神经网络的输入为(vec{x}) ,神经网络的输入为(vec{y}),如下图所示:
则每一层的输出向量的计算可以表示为:$$vec{a_1}=f(W_1·vec{x})$$$$vec{a_2}=f(W_2·vec{a_1})$$$$vec{a_3}=f(W_3·vec{a_2})$$$$vec{y}=f(W_4·vec{a_3})$$这就是神经网络输出值的计算方法。
误差逆传播算法
所谓神经网络的训练或者是学习,其主要目的在于通过学习算法得到神经网络解决指定问题所需的参数,这里的参数包括各层神经元之间的连接权重以及偏置等。因为作为算法的设计者(我们),我们通常是根据实际问题来构造出网络结构,参数的确定则需要神经网络通过训练样本和学习算法来迭代找到最优参数组。
说起神经网络的学习算法,不得不提其中最杰出、最成功的代表——误差逆传播(error BackPropagation,简称BP)算法。BP学习算法通常用在最为广泛使用的多层前馈神经网络中。
BP算法的主要流程可以总结如下:
输入:训练集(D=(x_k,y_k)_{k=1}^m);学习率;
过程:
在(0,1)范围内随机初始化网络中所有连接权和阈值
repeat:
(qquad)for all ((x_k,y_k) in D) do
(qquad)(qquad)根据当前参数计算当前样本的输出;
(qquad)(qquad)计算输出层神经元的梯度项;
(qquad)(qquad)计算隐层神经元的梯度项;
(qquad)(qquad)更新连接权与阈值
(qquad)end for
until 达到停止条件
输出:连接权与阈值确定的多层前馈神经网络。
具体的BP算法的公式推导,留下另一篇博文里详细说吧。
常见的神经网络模型
Boltzmann机和受限Boltzmann机
神经网络中有一类模型是为网络状态定义一个“能量”,能量最小化时网络达到理想状态,而网络的训练就是在最小化这个能量函数。Boltzmann(玻尔兹曼)机就是基于能量的模型,其神经元分为两层:显层和隐层。显层用于表示数据的输入和输出,隐层则被理解为数据的内在表达。Boltzmann机的神经元都是布尔型的,即只能取0、1值。标准的Boltzmann机是全连接的,也就是说各层内的神经元都是相互连接的,因此计算复杂度很高,而且难以用来解决实际问题。因此,我们经常使用一种特殊的Boltzmann机——受限玻尔兹曼机(Restricted Boltzmann Mechine,简称RBM),它层内无连接,层间有连接,可以看做是一个二部图。下图为Boltzmann机和RBM的结构示意图:
RBM常常用对比散度(Constrastive Divergence,简称CD)来进行训练。
RBF网络
RBF(Radial Basis Function)径向基函数网络是一种单隐层前馈神经网络,它使用径向基函数作为隐层神经元激活函数,而输出层则是对隐层神经元输出的线性组合。下图为一个RBF神经网络示意图:
训练RBF网络通常采用两步:
- 确定神经元中心,常用的方式包括随机采样,聚类等;
- 确定神经网络参数,常用算法为BP算法。
ART网络
ART(Adaptive Resonance Theory)自适应谐振理论网络是竞争型学习的重要代表,该网络由比较层、识别层、识别层阈值和重置模块构成。ART比较好的缓解了竞争型学习中的“可塑性-稳定性窘境”(stability-plasticity dilemma),可塑性是指神经网络要有学习新知识的能力,而稳定性则指的是神经网络在学习新知识时要保持对旧知识的记忆。这就使得ART网络具有一个很重要的优点:可进行增量学习或在线学习。
SOM网络
SOM(Self-Organizing Map,自组织映射)网络是一种竞争学习型的无监督神经网络,它能将高维输入数据映射到低维空间(通常为二维),同时保持输入数据在高维空间的拓扑结构,即将高维空间中相似的样本点映射到网络输出层中的临近神经元。下图为SOM网络的结构示意图:
结构自适应网络
一般的神经网络都是先指定好网络结构,训练的目的是利用训练样本来确定合适的连接权、阈值等参数。与此不同的是,结构自适应网络则将网络结构也当做学习的目标之一,并希望在训练过程中找到最符合数据特点的网络结构。
递归神经网络以及Elman网络
与前馈神经网络不同,递归神经网络(Recurrent Neural Networks,简称RNN)允许网络中出现环形结构,从而可以让一些神经元的输出反馈回来作为输入信号,这样的结构与信息反馈过程,使得网络在t时刻的输出状态不仅与t时刻的输入有关,还与t−1时刻的网络状态有关,从而能处理与时间有关的动态变化。
Elman网络是最常用的递归神经网络之一,其结构如下图所示:
RNN一般的训练算法采用推广的BP算法。值得一提的是,RNN在(t+1)时刻网络的结果O(t+1)是该时刻输入和所有历史共同作用的结果,这样就达到了对时间序列建模的目的。因此,从某种意义上来讲,RNN被视为是时间深度上的深度学习也未尝不对。
RNN在(t+1)时刻网络的结果O(t+1)是该时刻输入和所有历史共同作用的结果,这么讲其实也不是很准确,因为“梯度发散”同样也会发生在时间轴上,也就是说对于t时刻来说,它产生的梯度在时间轴上向历史传播几层之后就消失了,根本无法影响太遥远的过去。因此,“所有的历史”只是理想的情况。在实际中,这种影响也就只能维持若干个时间戳而已。换句话说,后面时间步的错误信号,往往并不能回到足够远的过去,像更早的时间步一样,去影响网络,这使它很难以学习远距离的影响。
为了解决上述时间轴上的梯度发散,机器学习领域发展出了长短时记忆单元(Long-Short Term Memory,简称LSTM),通过门的开关实现时间上的记忆功能,并防止梯度发散。其实除了学习历史信息,RNN和LSTM还可以被设计成为双向结构,即双向RNN、双向LSTM,同时利用历史和未来的信息。
深度学习
深度学习指的是深度神经网络模型,一般指网络层数在三层或者三层以上的神经网络结构。
理论上而言,参数越多的模型复杂度越高,“容量”也就越大,也就意味着它能完成更复杂的学习任务。就像前面多层感知机带给我们的启示一样,神经网络的层数直接决定了它对现实的刻画能力。但是在一般情况下,复杂模型的训练效率低,易陷入过拟合,因此难以受到人们的青睐。具体来讲就是,随着神经网络层数的加深,优化函数越来越容易陷入局部最优解(即过拟合,在训练样本上有很好的拟合效果,但是在测试集上效果很差)。同时,不可忽略的一个问题是随着网络层数增加,“梯度消失”(或者说是梯度发散diverge)现象更加严重。我们经常使用sigmoid函数作为隐含层的功能神经元,对于幅度为1的信号,在BP反向传播梯度时,每传递一层,梯度衰减为原来的0.25。层数一多,梯度指数衰减后低层基本接收不到有效的训练信号。
为了解决深层神经网络的训练问题,一种有效的手段是采取无监督逐层训练(unsupervised layer-wise training),其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,这被称之为“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)训练。比如Hinton在深度信念网络(Deep Belief Networks,简称DBN)中,每层都是一个RBM,即整个网络可以被视为是若干个RBM堆叠而成。在使用无监督训练时,首先训练第一层,这是关于训练样本的RBM模型,可按标准的RBM进行训练;然后,将第一层预训练号的隐节点视为第二层的输入节点,对第二层进行预训练;... 各层预训练完成后,再利用BP算法对整个网络进行训练。
(color{red}{事实上,“预训练+微调”的训练方式可被视为是将大量参数分组,对每组先找到局部看起来较好的设置,然后再基于这些局部较优的结果联合起来进行全局寻优。这样就在利用了模型大量参数所提供的自由度的同时,有效地节省了训练开销。})
另一种节省训练开销的做法是进行“权共享”(weight sharing),即让一组神经元使用相同的连接权,这个策略在卷积神经网络(Convolutional Neural Networks,简称CNN)中发挥了重要作用。下图为一个CNN网络示意图:
CNN可以用BP算法进行训练,但是在训练中,无论是卷积层还是采样层,其每组神经元(即上图中的每一个“平面”)都是用相同的连接权,从而大幅减少了需要训练的参数数目。