实训报告 1st

最近主要通过阅读论文的方式,学习了卷积神经网络的基本概念、结构、方法。这篇周报主要是对所学知识的一些总结。

如果有错误,烦请在评论区指正。

1. 神经网络

1.1. 神经元 Neuron

神经网络由神经元组成,单个神经元的结构如下

实际上是,输入向量$x$经过权值$W$进行线性变换之后得到$W^Tx+b$,再进过激活函数$f$将线性结果转变为非线性的结果$f(W^Tx+b)$,即 $H_{W,b}=f(W^Tx+b)$,其中$W^T$是$W$的转置。

1.1.1. 神经元与神经细胞

为了方便,我将用神经元来表示本文中神经网络的基本单位,而用神经细胞表示生物学中的概念。

让我们来将这个神经元与神经细胞做对比。

神经细胞有树突细胞体轴突。单个神经细胞可以看做一个二元分类器————兴奋时输出1,抑制时输出0。当信号量超过某个阈值时,神经元可以将兴奋沿着轴突传递给神经元。

而这里的神经元则是为了模拟神经细胞,权值向量$W$对应树突,偏置$b$对应阈值,激活函数$f$对应细胞体。神经元通过权值向量$W$接收来自上一次的输入向量$x$,并将输入$W^Tx+b$交给激活函数$f$。激活函数将决定传递给下一层神经元的输出。

1.1.2. 激活函数 Activation Function

激活函数定义了神经元在线性变换$W^Tx+b$之后的非线性输出结果。

为什么使用激活函数

如果不使用激活函数,由于所有的操作都是线性的,所以整个神经网络只是一个线性回归模型。线性回归模型的表达能力有限,它在很多问题上都表现得不够好,甚至无法解决这些问题。因此我们通过引入激活函数,为神经网络引入非线性的因素,增强它的能力,使其可以学习更加复杂的数据,表达输入输出之间非线性的复杂映射关系。

常用的激活函数有

  • Sigmoid:$S(t)=\frac{1}{1+e^{-t}}$
  • Tanh: $tanh(x)=\frac{sinh(x)}{cosh(x)}=\frac{e^x-e^{-x}}{e^x+e^{-x}}$
  • ReLU:$f(x)=max(0,x)$

由于梯度消失问题(Vanishing Gradient Problem),前两者已经弃用,ReLU是主流的激活函数。

1.1.3. 全连接 Fully-Connected

这里我们展示的神经元,将来自输入向量$x$中的所有数据都用于计算,我们还称这个神经元是全连接的(fully-connected)

继续我们神经元与神经细胞的比较联想,假如这个神经元是输入向量之后的第一层神经元,那么你可以想象成,我们脑中有一个树突极其巨大的神经细胞,它将来自外界的刺激全部收入囊中,并根据刺激给出输出。

全连通的好处显而易见,每个神经元都可以获取最全面的输入;但它的缺点也显而易见————我们定义处理大量的权值参数。这个缺点的具体描述,以及全连通缺点的方法,都会在接下来的内容中提到。

1.2. 多层神经网络

当多个神经元组合起来,形成分层结构时,就形成了神经网络。

其中

$a_1^{(2)}=f(W^{(1)}_{11}x_1+W^{(1)}_{12}x_2+W^{(1)}_{13}x_3+b^{(1)}_1)$

$a_2^{(2)}=f(W^{(1)}_{21}x_1+W^{(1)}_{22}x_2+W^{(1)}_{23}x_3+b^{(1)}_2)$

$a_3^{(2)}=f(W^{(1)}_{31}x_1+W^{(1)}_{32}x_2+W^{(1)}_{33}x_3+b^{(1)}_3)$

$H_{W,b}=f(W^{(2)}_{12}a_1^{(2)}+W^{(2)}_{22}a_2^{(2)}+W^{(2)}_{32}a_3^{(2)}+b^{(2)}_1)$

这里的$W_{\beta\gamma}^{(\alpha)}$表示从第$\alpha$层到第$\beta$层的第$\gamma$个神经元的权值向量$W$(为了简化,这里省略了转置符号$^T$),$b^{(\alpha)}_\beta$表示从第$\alpha$层到第$\beta$层的偏置$b$。

这是一个典型的三层神经网络,我们将Layer 2称为隐藏层(Hidden Layer)。一个神经网络中可以拥有多个隐藏层。

1.2.1. 前馈神经网络 Feedforward neural network

像这样,在神经网络内部,输入从输入层向输出层单向传播,不构成任何有向环的结构,我们称之为前馈神经网络。

1.2.2. 反向传播 Backpropagation

下一个要解决的问题是,怎样合理地确定神经网络中各层的权值。这句需要用到反向传播算法。

反向传播算法是训练神经网络的常用方法,该方法利用链式法则对网络中的所有权值计算损失函数的梯度,用来更新权值以最小化损失函数,本质上是一种梯度下降法

反向传播算法有两个阶段:激励传播和权值更新

激励传播

  1. 前向传播:输入进入神经网络并前向传播,最后产生输出。
  2. 反向传播:通过损失函数求出输出与标准输出之间的误差,然后通过链式法则求出每一层的权值参数对整体误差的影响(即总误差对权值参数求偏导)。

权值更新

  1. 将输入带入前面的求到结果中,获得权值梯度。
  2. 将权值乘上一个负的学习率,加到现有的权值上,以更新它的值。

具体实例在这篇博客中有非常详细的过程。

1.2.3. 问题

在前面我们就曾提到过,在我们现在介绍的神经网络中有一个由于全连接导致的巨大问题————参数数量巨大。

想象一下,假如输入是1000X1000的灰度图片(一个channel),也就是一个$10^6$个值,第二层隐藏层有$10^6$个神经元,那我们将面临$10^{12}$次方个权值。这样的参数数量是不可接受的。因此我们需要想一个办法去解决这个问题。

2. 卷积神经网络

2.1. 局部连接 Locally Connected

人对外界的认知是从局部到总体的,我们总是先对图像中的细节————例如边缘、颜色等有了认识,逐渐辨别轮廓,最后识别出物体。另外一个直觉的想法是,图像中的像素点总是和邻近的点关系密切,和距离较远的点关系较小甚至没有关系。

也就是说,一个单一的神经元没有必要对整个输入图像进行感知(全连接)。神经元只需要对局部进行感知(局部连接),再由更高层的神经元进行综合即可。

如上图,第二层隐藏层中的神经元只将部分值当做输入,最后由第三层隐藏层进行全连接。

回到之前的假设,假如输入依旧是1000X1000的灰度图片,第二层隐藏层依旧有$10^6$个神经元。但此时利用局部连接,第二层的神经元每个值对应输入中10X10的图像范围,那么每个神经元只需要100个权值。此时权值总数就是$10^8$个,远小于$10^{12}$个。

2.2. 参数共享 Shared Weights

$10^8$个权值参数虽然对比$10^{12}$已经是相当大的进步,但我们仍然可以进一步缩小它,解决的方案就是参数共享。

第二层的$10^6$个神经元均采用不同的参数,设想一下,加入它们都采用一样的100个权值参数,那么参数的总数就只剩下了100。

我们可以这样理解权值共享,这100个参数其实是通过卷积提取图片的特征的方式。在没有权值共享之前,每个神经元提取特征的方式都是不同的(因为它们的权值参数不同)。而现在所有神经元共享这100个参数,那所有的神经元就会以相同的方式提取图片特征。又因为上述局部连接的存在,每个神经元提取特征的位置是不一样的。最终导致的结果是,每个神经元在各自的局部,用相同的方式提取特征。

这100个参数实际上是10X10的矩阵,我们将这个矩阵成为卷积核(Kernel),卷积(Convolution)的过程就是这个卷积核在图片上游走,将覆盖范围内的所有输入值与卷积核对应位置的权值相乘累加。重复这个过程直到提取出特征图(Feature Map),如下图所示。

2.2.1. 对灰度图像卷积

对于一个图像,每个像素点由RGB三个值描述,也就是说一个图像是一个三维矩阵。我们将这三个维度分别称为长、宽和通道。

对于一个卷积核,也有三个维度,分别为长、宽和深度。

一次卷积操作有多个参数需要考虑:

  • Size:每个卷积核的大小 Width*Height*Depth。
  • Stride:卷积核每次移动的步长。
  • Padding:卷积核在遇到边缘时补0的宽度。

现在我们考虑比较简单的情况,灰度图像的特点是,只有一个通道,那么按照上述要求,卷积核的深度只需要为1就行了。

下图展示了一个Size为3X3X1的卷积核在Stride为2、Padding为1情况下,对一个5X5X1灰度图像的卷积操作:

2.2.2. 对多通道图像卷积

对于多个通道的图像,则要求卷积核的深度必须与输入图像的通道数一致。对于RGB三通道图像,则要求卷积核的深度必须为3。

下图展示了一个Size为3X3X3的卷积核在Stride为2、Padding为0的情况下,对一个9X9X3的RGB图像的卷积操作:

2.2.3. 计算特征图的大小

由于卷积核的深度总是与输入图像的通道数一致,所以输出的特征图总是一个二维矩阵,我们可以通过下面的公式计算出特征图的大小:

$$W_{new}=\frac{W_{old}+Padding*2-W_{kernel}}{stride}+1$$

这里W代表Width,同理可以计算出Height。

2.3. 多核卷积

我们知道,一次卷积操作生成的特征图,是利用一个卷积核提取出来的一种特征。为了能够增加特征的数量,我们可以使用多个卷积核Size、Stride、Padding完全相同,但参数不同的卷积核对输入图像进行卷积。

下图展示了我们使用两个卷积核的卷机操作:

可以发现,输出的特征图的通道数,与输入图像的通道数无关,而是与卷积核的数量有关。使用的卷积核的数量越多,我们提取的特征数量就越多,特征图的通道数也越多。

2.4. 多层卷积

图像是以像素点为单位作为输入的,隐藏层对输入卷积,提取出局部特征(比如边缘)。接下来的下一个隐藏层又以之前隐藏层的输出作为输入进行卷积,提取出抽象等级更高的特征(比如轮廓)。最后不断地增加隐藏层的数量,不断提取抽象等级更高的特征。最后进行全连接,使得学习的特征具有全局化的特性。

2.5. 过拟合 Overfitting

一般一个机器学习算法在训练集上训练,最后训练出来的模型被期望在用于预测时也拥有良好的表现,我们称之为泛化性。

然而如果一个模型开始学习训练集数据中的特化性质或者随即特征,在预测时对于未知数据的表现就会变差,我们称之为过拟合。

举一个简单的例子是,如果一个神经网络被训练用于分辨出所有的轿车。泛化性良好的情况下,模型只学习了轿车的通用特征,比如拥有四个轮子、车大灯、后备箱等。但如果我们的训练集中所有的轿车都是白色的,模型过度学习认为只有白色的才是轿车,这就是过拟合现象。

2.5.1. 池化 Polling

通过卷积获得特征之后,我们希望使用这些特征去分类。理论上,我们可以使用提取到的所有特征去分类,但这样会面临极其大的数据量。

例如对于一个96X96X1的输入图像,我们使用一400个8X8的卷积核进行卷积(Stride为1、Padding为0),那么我们最终会得到一个89X89X400的特征图。这个特征图中拥有超过三百万个数据,如此庞大的数据量难以学习,且容易出现过拟合的现象。我们可以选择池化来解决这个问题。

所谓池化,就是尝试使用一个更小的特征图去描述一个巨大的特征图。就像我们人类观察一个巨大的图片时,我们并不会注意图片中的每个细节,而是在每个区域选出有代表性特征,然后组合这些特征形成一个更小更利于理解的特征图。使用池化可以大大降低特征图的大小,并且减少过拟合现象。

上图描述了一个典型的池化操作,将这个特征图分为四个部分,每个部分取出一个代表性特征,并最终形成一个4X4的池化特征图。

和卷积一样,池化也有几个需要考虑参数:

  • Size:每次池化的范围
  • Stride:池化范围在特征图移动的距离

上图就是一个典型的Size=Stride的池化。

池化方法

  • 平均池化:Size=Stride,取池化范围中所有的值的均值作为特征
  • 最大池化:Size=Stride,取池化范围中的最大值作为特征
  • 重叠池化:Stride<Size,此时池化范围会有重叠,包含重叠平均池化和重叠最大池化。

2.5.2. 失活 Dropout

一个降低预测误差的方法是,我们训练多个不同的模型,并且将这些模型的预测结果结合起来。这是一个很好的想法,但是代价也相当的大。训练一个模型已经需要相当长的时间,训练多个模型的成本将成倍增加,但是收益却并没有那么显著。因此一个折中的方案被提出————失活。

失活这个机制在神经网络中作用的方式是,对于每次输入,隐藏层中的每个神经元的输出都有一定的概率(例如0.5)被设为0,这些失活的神经元不再参与前向传播和反向传播。因此,每次输入,神经网络都会以一种不同的结构,这强迫神经元学习更加鲁棒的特征,减少相互之间的依赖,以适应随机的失活机制。

在实践中,失活机制大大减少了过拟合的现象,代价则是使得收敛的时间翻了一倍。

2.6. 局部响应归一化 Local Response Normalization

局部响应归一化原理是仿造生物学上活跃的神经细胞对相邻神经细胞的抑制现象(侧抑制)。它将神经网络中响应较强的特征到增强,而响应较弱的特征被抑制,从而加快收敛速度。

其公式如下:

$$b_{x,y}^i=a_{x,y}^i/\left(k+\alpha\sum_{j=max(0,i-n/2)}^{min(N-1,i+n/2)}(a_{x,y}^j)^2\right)^\beta$$

其中$a_{x,y}^i$表示在i通道中的,x、y位置上的点的值,k、$\alpha$、$\beta$、n都是自定义的值。

从上图我们可以得知,实际上是以$a_{x,y}^i$为中心,沿着通道的轴的方向取n个值累加值作为分母,若该点的值越大,则被加强的越多;若越小,则被抑制的越多。

2.7. SoftMax

它能将一个含任意实数的K维的向量$z$的“压缩”到另一个K维实向量$\sigma(z)中,使得每一个元素的范围都在(0,1)之间,并且所有元素的和为1。该函数的形式通常按下面的式子给出:

$$\sigma(z)_j=\frac{e^{z_j}}{\sum_{k=1}^Ke^{z_k}}$$

假设神经网络最后的全连接输出的向量为1000维,那么将这1000维的向量输入SoftMax函数中,将会输出1000维的概率向量。这个向量中的每一个值描述了这个输入属于1000个分类中每个分类的概率。

3. 参考

图片来自Google Image

Krizhevsky A, Sutskever I, Hinton G E. ImageNet Classification with Deep Convolutional Neural Networks

维基百科. 前馈神经网络

维基百科. 感知器

UFLDL教程

维基百科. 链式法则

维基百科. 反向传播算法

Charlotte77. 一文弄懂神经网络中的反向传播法——BackPropagation

维基百科. 线性整流函数

维基百科. 过拟合