神经网络
神经网络是一种古老的算法, 20世纪40年代提出后沉寂了相当一段时间。随着技术和材料的进步,神经网络又再次回到人们的视野当中,称为解决机器学习问题的首选算法。
非线性分类问题
考虑有这样一个分类问题
欲解决这个问题,如果利用逻辑回归算法,首先要构造一个如上图右式所示的包含非常多非线性项的假设函数,其中g仍然代表Sigmoid函数。当多项式非常多的时候,也许会得到上图左边所示的那种决策边界。当只有两项特征\(x_1、x_2\)时,这种方法确实能得到比较好的结果。
譬如,房价预测模型,有100个特征,欲预测房子在半年内能卖出去的概率:
这个时候如果为了拟合数据集而考虑添加许多非线性项或者说添加许多高次多项式项,如添加许多二次项\(x_1^2,x_1x_2,...,x_1x_{100},x_2^2,x_2x_3,...,x_2x_{100},...\)这样会大概有5000个新构建的特征,而且新特征的数量会呈现\(o(n^2)\)的量级增长。
当然也可以考虑只是用如上面这些多项式项的子集:\(x_1^2,x_2^2,...x_{100}^2\),这样的话就只会有100项,大大减少了计算难度,但是由于忽略了太多相关性,最终的拟合结果可能不会太好。
更加极端的情况下,如使用三次项,这样会使项数呈\(o(n^3)\)级别增长。
所以一旦特征数过多,不管从哪个方面看,这都不是最好的解决办法。
然而对于绝大多数机器学习问题, 特征数都是很庞大的。
如机器视觉中的汽车识别问题。
如果我们想要使用机器学习算法训练一个分类器,来判断一个图片是否为汽车。
听起来很简单,对于人来说,这就是一张图,图上面是一辆汽车,而对于计算机来说,图片是很复杂的。
为了解释说明这个问题,我们取出图中红色框的部分。
对于人来说那就是一个门把。
而对于计算机来说,如下的数据矩阵,或者说像素格网
这些数据表示了像素强度值,告诉我们图像中每个像素的亮度值。
所以对于机器视觉来说问题变成了:根据这个像素点亮度矩阵来说明这些数值代表一个汽车门把手。
下面详细说明一下,如何构建一个非线性分类器。
我们在训练集的图片样本上随机选取两个位置的像素(那么其他样本也应该选择相同位置的像素,这就是为什么机器视觉问题的样本图片的像素大小都是一样的)
表示在坐标系中如下:
训练集中有两个车两个“非”车。
为什么都取的是相同位置的像素,但是两辆车处在不同的点?
这是因为白车的像素1、2有其各自的像素强度,橘车的像素1、2也有其各自的像素强度,故而两辆车会处在不同位置。
继续添加样本,
在构建一个非线性分类器之前,我们需要知道特征数量有多少。
如果这个训练集中的图片都是灰度图,且像素大小都是\(50\times50\)的,那么一张图片就有2500个像素(如果是RGB图像则每个像素有Red、Green、Blue三个子像素,因此共有7500个像素)
因此我们特征向量\(x=\begin{bmatrix} pixel1亮度值\\\\pixel2亮度值\\\\{\cdots}\\\\pixel2500亮度值 \end{bmatrix}\)
需要说明的是,对于典型的计算机图片表示方法, 如果存储的是每个像素的灰度值(色彩的强烈程度),那么每个元素的值应该在0-255之间。
如果我们非要通过包含所有二次项来解决这个非线性问题,那么最终大概会有3000000个特征,计算成本实在是太高了。
此时引入神经网络,这个在特征足够复杂时工作效率相当高的算法。
初识神经网络
神经网络起初是为了制造能模拟大脑的机器。
神经网络在20世纪80年代以及90年代早期运用非常广泛,但由于某些原因在90年代后期逐渐减少应用。但是近年神经网络又再次崛起了。神经网络是一种计算量偏大的算法,可能是由于近些年计算机性能节节拔高,能够真正意义上大规模应用神经网络算法。如今的神经网络对许多应用来说是最先进的算法。
人脑是地球上最为奇妙的器官,人的各种感官接收到的信息都要靠大脑来起处理,既然神经网络是模仿大脑的算法,那么也许会需要编写成千上万的程序去一一对应不同的大脑功能。
我们假设不需要编写这么多程序。因为有证据表明大脑处理信息只需要一个单一的学习算法就行了。
比如上图,我们把耳朵到听觉皮层的神经切断,将眼睛的神经连接到听觉皮层上面,那么听觉皮层将会学会用眼睛去听
再比如,将皮肤与体感皮层的神经切断,将眼睛与体感皮层相连,那么体感皮层将学会用眼睛去感受外界。
这些神经重接实验,可以看出了人体有同一块脑组织可以处理各种感觉信息,那么我们应该可以设计一种单一的学习算法同时处理多种不同的信息而不需要运行成千上万不同的程序。
神经网络模型
机器神经网络是在模仿大脑中的神经元或者大脑中的生物神经网络时发明的,要解释如何表示模型,首先来看单个神经元在大脑中是如何表示的
Cell body:细胞体
Dendrite:树突(输入神经)
Axon:轴突(输出神经)
简而言之,神经元是一个信息处理单位,从其他单位接收信息,经过一些计算之后,通过轴突传递到其他单位
计算机中一个简单的神经网络模型,理应表示如下:
左边\(x_1、x_2、x_3\)表示输入,中间的黄圈表示逻辑处理单元,经过一些计算后,输出\(h_\theta(x)\)。
根据之前所学,回归问题中,会有一个变量\(x_0=1\)。
那么根据对具体学习问题是否有利,在构建神经网络模型是,会选择性地加入\(x_0\)结点,该结点称为偏置单位或者偏置神经元。
假设函数\(h_\theta(x)=\frac{1}{1+e^{-{\theta}^{T}x}}\)
我们会说上面这个神经元是有一个Sigmoid函数(逻辑函数)作为激励函数的人工神经元。
在神经网络术语中,激励函数指的就是类似于Sigmoid函数\(g(z)=\frac{1}{1+e^{-z}}\)这样的非线性函数。
激励函数可以使得原有的线性函数变成非线性函数。激励函数的主要作用是提供网络的非线性建模能力。如果没有激励函数,那么该网络仅能够表达线性映射,此时即便有再多的隐藏层,其整个网络跟单层神经网络也是等价的。因此也可以认为,只有加入了激励函数之后,深度神经网络才具备了分层的非线性映射学习能力。
之前一直所说的参数\(\theta\),也就是使假设函数拟合数据集的关键参数,在神经网络中被称为模型的权重(weight of model)
详解模型
Layer1称为输入层,也即输入样本的特征项\(x_1、x_2、x_3\cdots\)
Layer2称为隐藏层,非输入输出层都被称为隐藏层。有些神经网络可能不止一个隐藏层。
Layer3称为输出层,这一层输出最终计算出来的假设函数值,也即预测值
\(a_i^{(j)}\):表示第j层的第i个单元的激励
\(\theta^j\):表示控制从第j层映射到第j+1层的参数矩阵(权重矩阵)
因为加入了偏置神经元,那么\(\theta^1\)就应该是一个\(3\times4\)阶矩阵,看下图也能看出来。
或者更一般地说,如果某网络在第j层有\(s_j\)个单元,在第j+1层有\(s_{j+1}\)个单元,那么\(\theta^j\)应该是一个\(s_{j+1}{\times}{s_j}+1\)阶矩阵。
通俗地讲,就是说当前层有\(j\)个单元,参数矩阵就有\(j\)行,前一层有\(j\)个单元,参数矩阵就有\(j+1\)列。
表示该神经元的激励函数g(z)作用在如上图所示的线性组合上得出的结果。
表示最终输出的结果。
前向传播(向量化)
(括号里的数字j表示那个数据是第j层的)
以$$a_1{(2)}=g(\Theta_{10}{(1)}x_0+\Theta_{11}{(1)}x_1+\Theta_{12}{(1)}x_2+\Theta_{13}^{(1)}x_3)$$为例
令\(z_1^{(2)}=\Theta_{10}^{(1)}x_0+\Theta_{11}^{(1)}x_1+\Theta_{12}^{(1)}x_2+\Theta_{13}^{(1)}x_3\)
由之前所学特征向量\(x=\begin{bmatrix}x_0\\\\x_1\\\\x_2\\\\x_3 \end{bmatrix}\),其中依然是\(x_0=1\)
定义\(z^{(2)}=\begin{bmatrix}z_1^{(2)}\\\\z_2^{(2)}\\\\z_3^{(2)} \end{bmatrix}\)
结合上面表示的\(z_1^{(2)}\)
容易向量化得到:
\(z^{(2)}=\Theta^{(1)}x\),\(a^{(2)}=g(z^{(2)})\)
显然\(\Theta^{(1)}=\begin{bmatrix}\Theta_{10}^{(1)}\\\\ {\Theta}_{11}^{(1)}\\\\{\Theta}_{12}^{(1)}\\\\{\Theta}_{13}^{(1)} \end{bmatrix}\)
令向量\(x=a^{(1)}\),则\(z^{(2)}=\Theta^{(1)}a^{(1)}\)
此时再加入偏置单元\(a_0^{(2)}=1\)
那么按照顺序计算能够得出:
\[z^{(3)}=\Theta^{(2)}{a^{(2)}} \] \[假设函数的实际输出值h_{\Theta}(x)=a^{(3)}=g(z^{(3)}) \]最后再梳理一遍:
\[x=\begin{bmatrix}x_0\\\\x_1\\\\x_2\\\\x_3 \end{bmatrix} \] \[\Theta^{(1)}=\begin{bmatrix}\Theta_{10}^{(1)}& {\Theta}_{11}^{(1)}&{\Theta}_{12}^{(1)}&{\Theta}_{13}^{(1)} \end{bmatrix} \] \[\Theta^{(2)}=\begin{bmatrix}\Theta_{10}^{(2)}& {\Theta}_{11}^{(2)}&{\Theta}_{12}^{(2)}&{\Theta}_{13}^{(2)} \end{bmatrix} \] \[z^{(2)}=\begin{bmatrix}z_1^{(2)}\\\\z_2^{(2)}\\\\z_3^{(2)} \end{bmatrix} \] \[x=a^{(1)} \] \[z^{(2)}=\Theta^{(1)}a^{(1)} \] \[a^{(2)}=g(z^{(2)}) \] \[z^{(3)}=\Theta^{(2)}{a^{(2)}} \] \[h_{\Theta}(x)=a^{(3)}=g(z^{(3)}) \]能够看出来整个数据是向前流动的,所以称之为前向传播
神经网络的自我训练
还是以之前的网络模型为例子。
先将输入层蒙住,只关注隐藏层和输出层
根据之前的推导,有如下结论:
这个式子看上去跟之前的逻辑回归的最终结果极其相似,那么我们可以认为,从Layer2到Layer3的这样一个过程,就是一个逻辑回归的训练过程
只不过这个逻辑回归输入的特征是通过隐藏层计算出来的数值
而这些通过隐藏层学习出来的特征(\(a_1^{(2)}、a_2^{(2)}、a_3^{(2)}\)),是通过Layer1输入的原始输入值得到的
那么分层来看的话,j层的特征值,就是j-1层训练出来的。故而说神经网络可以自行学习特征
Layer2将Layer1的原始输入值作为输入,输出复杂的特征项。
Layer3将Layer2训练出的特征项作为输入,输出更为复杂的特征项。
Layer4将Layer3训练出的特征项作为输入,输出最终的非线性假设函数。
假设函数的输出过程
考虑这样的分类问题。
输入特征\(x_1、x_2\)都是二进制,就只能取0或1 。
这样一个训练集,我们想要得出较好的假设函数去拟合,能看出来是这个函数\(h_\Theta{(x)}=x_1{XNOR}x_2(同或)\)。
拟合AND运算
为了解释神经网络到底是如何计算出假设函数的,我们先考虑拟合AND运算的网络。
假设有\(x_1,x_2{\in} {0,1}\)
神经网络模型如上。权重(参数)标注在箭头上面。
那么在激励函数是Sigmoid函数的情况下
\(h_\Theta(x)=g(-30+20x_1+20x_2)\)
此时需要知道Sigmoid函数的一些性质
如上图,\(g(4.6)\approx0.99\),\(g(-4.6)\approx0.01\)
因为特征\(x_1,x_2{\in} {0,1}\),那么可以得到一个输入与输出关系的表
\(x_1\quad{x_2}\) | \(h_\Theta(x)\) |
---|---|
\(0\quad0\) | \(g(-30)\approx0\) |
\(0\quad1\) | \(g(-10)\approx0\) |
\(1\quad0\) | \(g(-10)\approx0\) |
\(1\quad1\) | \(g(10)\approx1\) |
那么可以得出假设函数\(h_{\Theta}(x){\approx}{x_1}AND{x_2}\)
拟合OR运算
假设有\(x_1,x_2{\in} {0,1}\)
那么在激励函数是Sigmoid函数的情况下
\(h_{\Theta}(x)=g(-10+20x_1+20x_2)\)
可以得出下表
\(x_1\quad{x_2}\) | \(h_{\Theta}(x)\) |
---|---|
\(0\quad0\) | \(g(-10)\approx0\) |
\(0\quad1\) | \(g(10)\approx1\) |
\(1\quad0\) | \(g(10)\approx1\) |
\(1\quad1\) | \(g(30)\approx1\) |
可以看出这几个参数(权重)下的假设函数\(h_{\Theta}(x)=x_1 OR x_2\)
拟合NOT运算
根据上图可以看出,若要拟合逻辑非运算,大体思路就是在预期得到非结果的变量前加上一个比较大的负权重。
通过多层结构拟合XNOR运算
从左到右的假设模型分别为:
将三个单一的神经网络模型组合到一起,则有1个输入层、1个隐藏层、1个输出层。
按照前向传播和神经网络的自我学习理论,最终会得到这样的表
\(x_1\quad{x_2}\) | \(a_1^{(2)} \quad a_2^{(2)}\) | \(h_{\Theta}(x)\) |
---|---|---|
\(0\quad0\) | \(0 \quad 1\) | \(1\) |
\(0\quad1\) | \(0 \quad 0\) | \(0\) |
\(1\quad0\) | \(0 \quad 0\) | \(0\) |
\(1\quad1\) | \(1 \quad 0\) | \(1\) |
我们的输入都放在输入层,隐藏层用来计算一些关于输入的更加复杂的特征,输出层用于计算一个更加复杂的非线性函数。
因此神经网络的层数越多,就越能计算出复杂的函数。
多类别分类问题
要在神经网络中实现多类别分类,本质上采用的方法是一对多法的拓展。
以一个机器视觉的问题为例子。我们要对行人,汽车,摩托车,卡车4个不同的东西进行分类。
那么显而易见,需要建立一个有4个输出单元的神经网络。并且输出的结果将会是一个4维向量。
第一个输出单元考虑是否为行人,第二考虑是否为汽车,第三个考虑是否为摩托车,第四个考虑是否为卡车。
也就是说当是行人时,\(h_{\Theta}(x)=\begin{bmatrix}1\\\\0\\\\0\\\\0\end{bmatrix}\)
以此类推。
那么训练集应该以这样的形式输入:
总共m个样本。
\(x^{(i)}\)表示图片,\(y^{(i)}\)表示该图片属于哪类
需要注意的是\(y^{(i)}\)应该是\(\begin{bmatrix}1\\\\0\\\\0\\\\0\end{bmatrix}\) \(\begin{bmatrix}0\\\\1\\\\0\\\\0\end{bmatrix}\) \(\begin{bmatrix}0\\\\0\\\\1\\\\0\end{bmatrix}\) \(\begin{bmatrix}0\\\\0\\\\0\\\\1\end{bmatrix}\)其中的一个。