【机器学习】深度学习
深度学习
目录
一、何为深度学习?
1、深度学习、机器学习与人工智能
在学习深度学习之前,需要弄清楚深度学习、机器学习和人工智能的关系。
人工智能(artificial inteligence)是一个综合性的领域,不仅包括机器学习与深度学习,还包括更多不涉及学习的方法。例如,早期的国际象棋程序仅包含程序员精心编写的硬编码规则,并不属于机器学习。在相当长的时间内,许多专家相信,只要程序员精心编写足够多的明确规则来处理知识,就可以实现与人类水平相当的人工智能。这一方法被称为符号主义人工智能(symbolic AI)。
虽然符号主义人工智能适合用来解决定义明确的逻辑问题,比如下国际象棋,但它难以给出明确的规则来解决更加复杂、模糊的问题,比如图像分类、语音识别和语言翻译。于是出现了一种更新的方法来替代符号主义人工智能,这就是机器学习(machine learning)。
但随着大数据时代的来临,传统机器学习方法的表现不尽人意。在数据量激增和计算机性能不断提升的时代,利用更深的网络挖掘数据信息的深度学习表现出一骑绝尘的性能,这迅速受到学术界和工业界的重视。尤其在2010年之后,各种深度学习框架的开源和发布,更进一步的促进了深度学习算法的发展。但是,深度学习本身还是一种机器学习方法,它和与传统的机器学习方法一样,都是根据输入数据进行分类或者回归。
2、深度学习的内涵
深度学习是机器学习的一个重要分支,它是从数据中进行学习一种新方法,其强调的是从连续的层(layer)中进行学习。“深度学习”中的“深度”并不是指这种方法能得到更深层次的理解,而是指该方法会包含一系列连续的层。由该方法建立的模型所包含的层数,通常也被称为模型的深度(depth)。现在的深度学习过程通常包含数十个甚至上百个表示层,这些表示层全都是从训练数据中学习而得。与此相对的传统机器学习算法在实质上,相当于仅包含了一两层,因此有时也被称为浅层学习(shallow learning)。
在深度学习中,这些分层的表示几乎总是通过一种被称为神经网络(neural network)的模型学习得到。
3、神经网络结构
用图来表示神经网络的话(如下图所示),我们把最左边的一列称为输入层,最右边的一列称为输出层,中间的一列称为中间层(有也称为隐藏层)。“隐藏”一词的意思是,隐藏层的神经元(和输入层、输出层不同)是无法被看见的。
那层与层之间是如何进行数据变换的呢?权重矩阵。
如果将上一幅图像中的神经网络层次进行拓展(如设置为 2 层),则可以将该图像的完整结构用下图表示:
所以,构建(训练)神经网络的过程,实际上就是寻找 { w i , i = 1 , 2 , … ? } \{w_i, i = 1,2, \dots \} {wi?,i=1,2,…} 的过程。
在上面的网络模型中,我们直接将上一隐层中的数据作为输入与接下来的权重矩阵进行矩阵乘法,并将结果作为接下来隐层中的数据。这种不对前一层数据做任何处理,直接输入到下一层网络中的神经网络模型被称为“线性神经网络”。在这种网络模型中,由于每一层的输出都是该层输入数据的线性函数,所以无论该网络结构怎么搭,最终的输出都将是输入数据的线性组合。
因此,线性网络模型的表达能力是远远不够的。为了解决这一问题,可以在神经网络中引入激活函数。
在神经网络中引入激活函数后的结构如下图所示:
激活函数的作用主要是将前一层的输出进行非线性变换,然后再传入下一层。在引入了激活函数后,神经网络的表达能力会得到极大提升。现在我们谈到的神经网络,大多都是这一类模型,有关激活函数的内容将在后面进行更详细的阐述。
4、深度学习较机器学习的优势
- 性能上限
传统机器学习算法相较深度学习而言,最大的差异莫过于当数据量激增时,其构建模型的性能差异:
- 特征提取
机器学习的流程为:数据获取→特征工程→模型建立→评估与应用。而深度学习的流程里并却没有特征提取这一步,因为它可以通过深层的网络结构自动从原始数据中提取有用特征。因此,对于传统机器学习而言,当面对一份常规数据集时(如加州房地产数据这种已经进行了特征提取和划分的优质数据集),其总能通过一些算法(如逻辑回归、决策树等)直接进行模型构建。但是,当面对的数据集为一些较为复杂的对象时(图片、音频甚至视频),如何从这些数据里定义、划分和筛选特征就成为了一个非常困难的问题。
同时,由于数据的特征决定了模型的上限,而算法与参数决定了如何逼近这个上限,因此对数据进行预处理和特征提取也成为了机器学习中的一个核心关键。以“对图像进行分类”为例,在传统的机器学习的特征提取阶段,需要设计者具备足够的图形学相关知识,才能够找到有效的数据特征,这给建模难度和预测效果增加了不确定性。相比之下,深度学习的方法由于具有端到端的特性,可以直接从原始数据中找到有用的信息,在预测时只使用对预测目标有用的内容,增强了其预测能力,而且不需要过多的人为干预,提高了预测结果的稳定性。
二、深度学习的底层原理
通过前面若干章节的学习,可将传统机器学习算法的固有模式大致归结为以下三步:
- 收集数据并给定标签;
- 找到一个合适的函数 f ( x ; w , b ) f(\text{x}; w, b) f(x;w,b) ,使得 f f f 能最大限度地在给定数据上达到最佳拟合效果;
- 对 f f f 进行测试、评估后,输出 f f f。
同样地,深度学习也是基于这样一种模式。稍有不同的是,在深度神经网络中,由于其含有若干网络层,这就需要为各层单独求解一组权重(这也被称为该层的参数)。在这种语境下,学习的意思就是为神经网络的所有层找到一组权重值,使得该网络能够将每个示例的输入与其目标正确地一一对应。但重点来了:要如何找出这些 W W W 呢?
1、以图像分类任务为例讲解深度学习的原理
下面我们以计算机视觉的核心任务——图像分类,来阐述深度神经网络是如何求解 W W W 的。
现假设我们有一系列带标签的图像数据集:猫、狗、鸭子。
首先,我们需要让计算机理解图像数据:一种简单直观的方式是取图像的像素值以构成像素矩阵。例如,下图给出了一幅规格为 300 × 400 300\times400 300×400 (像素个数)的小狗图像,我们可以将该图像的所有像素点取出,并按序组成一条向量: x = [ 12 , 137 , … , 14 ] T \text{x} = [12,137, … , 14]^T x=[12,137,…,14]T。在图像的表示中,由于彩色图像含有 3 个颜色通道(不考虑 Alpha 通道),因此该向量的长度为 300 × 400 × 3 = 360000 300\times400\times3=360000 300×400×3=360000。
2、权重参数的含义(单隐层)???
接下来,假设我们利用神经网络构建好了一个仅含单隐层的模型 f ( x ; w , b ) f(\text{x};w,b) f(x;w,b) ,其能将输入的图像数据进行处理并反馈该图像在各个类别上的得分:
则可将计算得分的过程用下图表示(为便于理解,假设输入的图像数据为 2 × 2 2\times2 2×2 的灰度图):
在该过程中,首先将原始图像数据的像素值用向量进行表示,得到 X X X。然后再用初始权重矩阵 W W W 和该输入向量进行矩阵乘法( W W W 可进行随机初始化)。因此,这就要求 W W W 的列数要与输入向量 X X X 的长度相等。这一过程将用 W W W 的每行分别与输入向量 X X X 进行向量点乘,即分别计算:
[ 0.2 , 0.4 , 2.1 , ? 0.6 ] ? [ 196 , 8 , 48 , 97 ] = 0.2 × 196 + 0.4 × 8 + 2.1 × 48 ? 0.6 × 97 = 85 [ 1.5 , ? 0.7 , 0.0 , 0.5 ] ? [ 196 , 8 , 48 , 97 ] = 1.5 × 196 ? 0.7 × 8 + 0.0 × 48 + 0.5 × 97 = 336.9 [ ? 0.6 , 1.3 , 0.2 , 0.4 ] ? [ 196 , 8 , 48 , 97 ] = ? 0.6 × 196 + 1.3 × 8 + 2.2 × 48 + 0.4 × 97 = ? 58.8 [0.2, 0.4, 2.1, -0.6]·[196, 8, 48, 97] = 0.2×196+0.4×8+2.1×48-0.6×97=85 \\ [1.5, -0.7, 0.0, 0.5]·[196, 8, 48, 97] = 1.5×196-0.7×8+0.0×48+0.5×97=336.9 \\ [-0.6, 1.3, 0.2, 0.4]·[196, 8, 48, 97] = -0.6×196+1.3×8+2.2×48+0.4×97=-58.8 [0.2,0.4,2.1,?0.6]?[196,8,48,97]=0.2×196+0.4×8+2.1×48?0.6×97=85[1.5,?0.7,0.0,0.5]?[196,8,48,97]=1.5×196?0.7×8+0.0×48+0.5×97=336.9[?0.6,1.3,0.2,0.4]?[196,8,48,97]=?0.6×196+1.3×8+2.2×48+0.4×97=?58.8
实际上,该过程正体现了 W W W 中每一行所代表的含义。由于我们规定最终的结果分别为“预测为猫的得分”、 “预测为狗的得分”、 “预测为鸭的得分”。因此,这也就是说 W W W 中的第一行数据主要是用于捕获输入数据中猫的特征、第二行数据是用于捕获输入数据中狗的特征、第三行数据是用于捕获输入数据中鸭的特征。它们在对输入数据进行预测时,分工明确,各司其职。
同时,观察 W W W 中的每一行数据。如,第一行向量:
[ 0.2 , 0.4 , 2.1 , ? 0.6 ] [0.2, 0.4, 2.1, -0.6] [0.2,0.4,2.1,?0.6]
其表明,当前构建的模型认为:在通过对原始图像数据的像素进行向量化后,其中的第三个像素点(特征)对“预测当前图像属于猫这个类别”最重要,因为它的权重参数达到了 2.1 ,是所有权重系数的最高值;同理可知,其中的第四个像素点对“预测当前图像属于猫这个类别”起着负作用,因为它的权重参数为负,而这将会削减最终预测为猫的得分。其余行也是如此,分别表达着该模型在预测输入向量(特征)属于某种类别时的偏好。这便是单层神经网络中,权重矩阵 W W W 的含义。
需要注意的是, W W W 的规格仅在列数上受限于输入数据的特征长度,而其行数的取值是任意的。当 W W W 的行数与数据集的标签个数不等时,对权重参数的解读将发生变化。
例如,我们有一份数据,其含有:年龄、身高、体重 3 个特征(以及对应的健康指数,作为标签值)。现要求根据这份数据构建神经网络,以对输入数据进行健康打分。
对于这种情况,我们在构建权重矩阵时,可灵活地选择参数矩阵的行数。例如,可取以下权重矩阵:
此时,对于任意输入向量 x ? = [ a g e , h e i g h t , w e i g h t ] T \text{x}^*=[age, height, weight]^T x?=[age,height,weight]T ,当用该矩阵乘以此向量时,则会得到以下结果:
φ x ? = [ 1.41 a g e + 0.32 h e i g h t + 0.73 w e i g h t 1.15 a g e + 0.58 h e i g h t + 0.42 w e i g h t 0.81 a g e + 0.48 h e i g h t + 0.97 w e i g h t 1.25 a g e + 0.66 h e i g h t + 0.79 w e i g h t ] \varphi_{\text{x}^*}= \begin{bmatrix} 1.41age + 0.32height + 0.73weight \\ 1.15age + 0.58height + 0.42weight\\ 0.81age + 0.48height + 0.97weight\\ 1.25age + 0.66height + 0.79weight \end{bmatrix} φx??= ?1.41age+0.32height+0.73weight1.15age+0.58height+0.42weight0.81age+0.48height+0.97weight1.25age+0.66height+0.79weight? ?
可以看到, φ x ? \varphi_{\text{x}^*} φx?? 的长度变为了 4 (取决于 W W W 的行数),而原输入向量 x ? \text{x}^* x? 的长度为 3 。实际上,可将这个过程视为对原输入数据进行的一次特征提取(新得到的特征是对原输入数据的内容进行加权和)。它的用处非常广泛,例如,当样本数据规格很大时,该方法可用于降维以加快算法的执行速度;当样本数据规格很小时(可能会出现低维不可分的情形),此方法又能用于增维(这就相当于采取了核技巧)。
前面提到,深度学习较其他传统机器学习算法最大的差异就在于它并未经过专门的特征工程,而是自动挖掘数据中的特征,并对其进行拟合。从上面的例子可见一斑。
3、权重参数的含义(多隐层)???
单层神经网络的数学展开式实际上和线性回归具有异曲同工之妙。当神经网络的层次加深时,其蕴含的物理含义又是怎样的呢?我们还是以图像分类为例,试解读多层神经网络在其隐层中所保留数据的含义。为便于分析和理解,假设下面所用图像数据的规格为 2 × 2 × 1 2\times2\times1 2×2×1 (即 2 × 2 2\times2 2×2 的灰度图)。
(1) 第一层权重矩阵(网络)
在含双隐层的神经网络中,当第一次用权重矩阵 W 1 W_1 W1? 与输入数据进行矩阵乘法时,该过程实际上是完成了对样本数据的初步特征采样。如右图所示,输入数据(向量)在与权重矩阵进行矩阵乘法后,会将原始图像中有关猫咪图像的一些表层特征进行初步提取。如:
- Frame1: “猫咪图片主体部分的大致范围”;
- Frame2: “猫咪脸的大致模样”;
- Frame3: “猫咪图片中的大致深色位置”;
- Frame4: “猫咪图片中的大致重要特征 1”;
- Frame5: “猫咪图片中的大致重要特征 2”。
这些就是单层神经网络对一幅图片是否是猫咪而做出的一些简单定义,显然,这些定义并不完全正确。因此,为了能让模型取得更好的预测效果,我们尝试加深它的网络层数。
(2) 第二层权重矩阵(网络)
接下来,用权重矩阵 W 2 W_2 W2?与输入数据(隐层 1 中的结果)进行矩阵乘法。该过程会将前一步得到的“定义”进行更深层次的解读(即再特征提取)。如:
针对 Frame1:“猫咪图片主体部分的大致范围可进一步细化为 F1、 F2、 F3、F4、 F5”。这就从原本宽泛的图框,进一步绘出了一只猫咪的轮廓。但实际上,有些图像中的猫咪也许是另一个姿势?
(3) 第三层权重矩阵(网络)
针对 Frame2:“猫咪脸的大致模样可进一步细化为F1、 F2、 F3、 F4、 F5”。这就从原本宽泛的猫脸,进一步细化出了猫咪的双眼、鼻子以及两边的胡须。以此类推……这便是多隐层神经网络中各层存放数据的含义。从这里不难看出,只要神经网络的层次足够深,那它几乎就能将一幅图片的所有特征全部细化出,进而达到几乎完美的分类效果。
因此,深度学习模型较传统机器学习算法而言,其效果几乎是降维式打击。所以,深度学习的研究者似乎更注重防止过拟合(而隔壁机器学习却在想办法如何取得较好的拟合效果)。
4、损失函数的引入
我们继续思考最开始提出的问题:深度学习要如何求出参数矩阵 W W W ?
回到前面的例子(下图),从该预测结果来看,其效果是相当不准确的:很明显该图是一只可爱的猫咪!不过出现这样的预测结果并不意外,毕竟一开始给的权重矩阵 W 就是随机的。
于是,接下来我们需要根据得分结果对原始权重矩阵 W W W 进行反向调整,以使其变得更为合理(实际上,这就像我们刷题的过程:一开始你会做错很多题,但那并不重要,这本来就是练习。接下来你只需要对做错的题反复练习,然后再去练习类似的题,当你做的多了,自然就变得会了)。
调整方法很简单。由于我们拥有数据的真实标签,因此在练习的过程中,当对某个数据分类错误时,我们就可以根据这个错误来进行调整。例如,在前面的例子中,初始情况下的分类器 f f f 对一只猫咪图片进行了预测,其结果如下图所示,但是我们根据图像数据的标签值可知,这是一只猫(猫咪:你看不出么!)。那么对于 f f f 在其他的类别上的得分,就不能明显地高于在猫咪上的得分。所以,对于其余得分,我们需要评估它(错误的预测值)与真实的预测值之间的差异。对于这个差异,我们用 “损失” 这个名词冠以描述。例如,在下图的例子中:
- f f f 认为该图属于狗狗的得分为 339.3 ,则其相较样本真实值(猫咪)的损失为 339.3 - 86.2 = 253.1;
- f f f 认为该图属于鸭子的得分为 -59.6 ,则其相较样本真实值(猫咪)的损失为 -59.6 - 86.2 = -145.8。
对于上面的损失,我们实际仅关心第一组值(即 253.1),因为 f f f 预测该图属于鸭子的得分(-59.6)低于真实值(猫咪),因此用该值算出的损失为负。换言之, W W W 中的第三行向量在“预测不属于猫咪”这项任务上还挺好!(当然,它本身的任务是“预测属于鸭子”的)。因此,我们可以忽略这项损失(人家没犯错,你当然就不能让他改啦!)。故此,引入 max 函数来完成这一逻辑,即有:
L i = ∑ j = 1 , j ≠ y i k max ( 0 , f ( x i ; W j ) ? f ( x i ; W i ) ) L_i=\sum_{j=1, j\neq y_i}^k\text{max}\left(0, f(\text{x}_i;W_j)-f(\text{x}_i;W_i)\right) Li?=j=1,j=yi?∑k?max(0,f(xi?;Wj?)?f(xi?;Wi?))
其中, L i L_i Li? 表示该损失是在第 i i i 个样本上的损失, k k k 表示该分类器的预测类别数(在此例中 k = 3 k = 3 k=3)。 y i y_i yi? 表示第 i i i 个样本的标签(即第 i i i 个样本的真实分类)。该损失函数被称为 hinge loss。
5、松弛因子的引入
有时候,我们会放宽某个样本在各分类上的限制,即允许出现一些误差,故引入松弛因子 ζ \zeta ζ :
L i = ∑ j = 1 , j ≠ y i k max ( 0 , f ( x i ; W j ) ? f ( x i ; W i ) + ζ ) L_i=\sum_{j=1, j\neq y_i}^k\text{max}\left(0, f(\text{x}_i;W_j)-f(\text{x}_i;W_i)+\zeta\right) Li?=j=1,j=yi?∑k?max(0,f(xi?;Wj?)?f(xi?;Wi?)+ζ)
当加入松弛因子后,模型就能更好地去处理一些确实不太容易分辨的情形。例如,一幅图片标记为小狗的图片,看起来既有可能是一只小猫,也有可能是一只小狗,且其得分分别为 89.2 和 89.9 。此时,如果用原损失函数,则计算结果 m a x ( 0 , 89.2 ? 89.9 ) = 0 max(0, 89.2-89.9)=0 max(0,89.2?89.9)=0 ,即忽略掉这一差异(认为分类一定正确)。但是从理性角度看,我们应该为这幅图的属类画一个问号(因为差异并不是很大,故视作证据不够充足)。而此时,若采用引入松弛因子 ζ = 1 \zeta = 1 ζ=1 的损失函数,则计算结果 m a x ( 0 , 89.2 ? 89.9 + 1 ) = m a x ( 0 , 0.3 ) = 0.3 max(0, 89.2-89.9+1) =max(0, 0.3) =0.3 max(0,89.2?89.9+1)=max(0,0.3)=0.3, 即认为需要考虑这一差异(认为该模型还需要进一步优化)。而这显然更符合常理(两个分数接近的人,要更细致地再深入考察,然后再决定去留)。
引入松弛因子后的损失函数会将原始划分边界进行放松(如下图所示),从而为输入数据的归类做更充分的考量(缓冲带)。
6、将输入数据矩阵化
前面的例子都是针对仅有一个输入数据的情况。现在,假设我们要对若干份输入数据(假设为 4 份)进行预测(如下图所示),且所有输入数据都是规格为 32 × 32 32\times32 32×32 的彩色图片(含 RGB 三个颜色通道)。则此时,每份输入数据对应的向量长度为 32 × 32 × 3 = 3072 32\times32\times3= 3072 32×32×3=3072。又由于输入数据共有 4 份,则它们会被合在一起以组成一个规格为 3072 × 4 3072\times4 3072×4 的矩阵。
由于此时每条输入数据的长度为 3072,即神经网络会认为现在面对的数据对象是一个特征数量为 3072 的对象,因此它也会调整参数矩阵 W W W 的宽度(列数)为 3072。最后,我们依然取参数矩阵的行数为 3 (为便于理解),则此时 W W W 矩阵的规格为 3 × 3072 3\times3072 3×3072。
当这些参数都被确定后,神经网络会随机给 W W W 赋值,然后再用 W W W 矩阵乘以由输入向量构成的矩阵,并由此得到各个样本数据在 3 种不同类别上的得分。因为 S i z e W = 3 × 3072 , S i z e X = 3072 × 4 Size_W = 3\times3072,Size_X =3072\times4 SizeW?=3×3072,SizeX?=3072×4 ,则最终得到的是一个规格为 3 × 4 3\times4 3×4 的矩阵(矩阵乘法的性质),其结果上图所示。
此时,可将前面得到的损失函数写为( n n n 为样本数据个数):
L = 1 n ∑ i = 1 n ∑ j = 1 , j ≠ i k max ( 0 , f ( x i ; w j ) ? f ( x i ; w i ) + ζ ) L=\frac1n\sum^n_{i=1}\sum^k_{j=1,j\neq i}\text{max}(0, f(\text{x}_i;w_j)-f(\text{x}_i;w_i)+\zeta) L=n1?i=1∑n?j=1,j=i∑k?max(0,f(xi?;wj?)?f(xi?;wi?)+ζ)
7、正则化的引入
前面说到,深度学习也是机器学习算法的实现之一,因此,其本质也是在寻找拟合函数(即一组权重参数 W W W)。现假设对于某个拟合方程 f f f 得到以下两组 W W W ,且由它得到的决策方程在训练集上取得的效果完全一致:
W
1
=
[
1
,
0
,
0
,
0
]
T
W_1=[1,0,0,0]^T
W1?=[1,0,0,0]T
W
2
=
[
1
4
,
1
4
,
1
4
,
1
4
]
T
W_2=[\frac14,\frac14,\frac14,\frac14]^T
W2?=[41?,41?,41?,41?]T
那应该选谁作为最终的权重参数呢?
答案当然是 W 2 W_2 W2? ,因为由 W 2 W_2 W2? 得到的拟合方程考虑了更多的特征,所以它在测试集上更有可能取得较好的预测效果。有关正则化的更多内容请参看在 线性回归 部分中的介绍。
引入正则化后,其会对原回归方程的权重参数进行惩罚,以让权重参数尽可能平滑。此时,得到的新损失函数为:
L = 1 n ∑ i = 1 n ∑ j = 1 , j ≠ i k max ( 0 , f ( x i ; w j ) ? f ( x i ; w i ) + ζ ) + λ R ( W ) L=\frac1n\sum^n_{i=1}\sum^k_{j=1,j\neq i}\text{max}(0, f(\text{x}_i;w_j)-f(\text{x}_i;w_i)+\zeta) + \lambda R(W) L=n1?i=1∑n?j=1,j=i∑k?max(0,f(xi?;wj?)?f(xi?;wi?)+ζ)+λR(W)
其中, R ( W ) R(W) R(W) 即为引入的正则, λ \lambda λ 为控制系数。
8、激活函数(映射函数)的引入
前面说到,我们要利用损失函数的值对参数矩阵 W W W 进行反向调整,但在此先思考一个问题:损失函数的值有何含义?直观地看,这个值表示“属于某种类别的得分”,但“得分”这个概念有两个瑕疵:
- “得分”没有上下限,因而无法对该结果做出合理评判,这主要体现在难以划分等级(如:百分制让我们觉得 90 分以上是优秀,60 分以下是不合格);
- “得分”没有把“属于某种类别的可能性”体现出来。如:有的数据集算出的结果就是很小,均值在 1-10 ,此时很难从数值上界定某个样本的具体分类。
为此,我们想到了前面在逻辑回归中的处理办法:采用某种值域为 [0, 1] 的函数进行映射。这样,就能将“得分”这个概念转变为“概率”,从而将 1 和 2 中的问题解决。另一方面(也是最根本的一点):映射函数能够将某个输入进行非线性变换。这一变换至关重要,因为它能够将整个模型的预测能力提升至一个完全不一样的档次。基于此,引入激活函数(映射函数)。
最常规的一类激活函数是 S i g m o i d Sigmoid Sigmoid 函数(如下图所示):
其方程为:
σ ( z ) = 1 1 + e ? z ( ? ∞ < z < + ∞ ) \sigma(z)=\frac{1}{1+e^{-z}}(-∞<z<+∞) σ(z)=1+e?z1?(?∞<z<+∞)
它接受范围为 ( ? ∞ , + ∞ ) (?∞, +∞) (?∞,+∞) 的任意实数,并将其映射到 [ 0 , 1 ] [0,1] [0,1] 之间。这样的取值能够更直观地感受到输入数据的所属类别(如:当输入数据在某个类别上的得分为 0.8 及以上时,我们就认为该数据大概率就属于这一类别)。
注: S i g m o i d Sigmoid Sigmoid 函数有一个很好的性质: ? σ ( z ) ? x = ( 1 ? σ ( z ) ) σ ( z ) \frac{\partial\sigma(z)}{\partial x}=(1-\sigma(z))\sigma(z) ?x?σ(z)?=(1?σ(z))σ(z),这有利于反向传播的计算。
三、神经网络中的反向传播
前面做的所有工作实际上都是在寻找合适的损失函数,因为我们知道,有了损失函数,就能对权重矩阵 W W W 进行调整(因为 W W W 在一开始是随机的)。而这个调整过程,就是强化神经网络预测效果的过程。
下图总结了在神经网络中,数据的输入、计算得分、计算损失并反向调整的流程。对于多层神经网络,该过程依然如此。不过在计算损失时,必须从最后一层的损失开始,逐层往前迭代求解(链式法则),即:
1、求第
m
m
m 层损失,调整该层
W
W
W ;
2、求第
m
?
1
m-1
m?1 层损失,调整该层
W
W
W;
……
M、求第
1
1
1 层损失,调整该层
W
W
W ;
这个过程被称之为“反向传播”。
也许你会心存疑惑,为什么要这样对各 W 进行调整?
你似乎会有这样的思路:
若假设各隐层对应的参数矩阵 W W W 分别为: W 1 , W 2 , … , W n W_1, W_2, … , W_n W1?,W2?,…,Wn? ,则可以直接计算出从第一层到第 k k k 层的得分为:
L k = W k ( … ( W 2 ( W 1 x ) ) ) L_k=W_k(\dots(W_2(W_1\text{x}))) Lk?=Wk?(…(W2?(W1?x)))
因为我们希望这个损失值越小越好(表示模型判断错误的情况越少),故对 W k W_k Wk? 求导:
? L k ? W k = W k ? 1 ( … ( W 2 ( W 1 x ) ) ) \frac{\partial L_k}{\partial W_k}=W_{k-1}(\dots(W_2(W_1\text{x}))) ?Wk??Lk??=Wk?1?(…(W2?(W1?x)))
然后令 W k ? 1 ( … ( W 2 ( W 1 x ) ) ) = 0 W_{k-1}(\dots(W_2(W_1\text{x})))=0 Wk?1?(…(W2?(W1?x)))=0 即可算出 W k W_k Wk? 的极值点。将这个方法进行推广,即能将所有的参数矩阵 W W W 都算出来。
这听起来是一个好办法,但是这方法并没有考虑到损失函数 L k L_k Lk? 可能非常复杂,也许你根本无法找到其关于某个变量的表达式,也就更谈不上什么求导了。另一方面,式子:
L k = W k ( … ( W 2 ( W 1 x ) ) ) L_k=W_k(\dots(W_2(W_1\text{x}))) Lk?=Wk?(…(W2?(W1?x)))
的成立是基于“神经网络中各层之间都是直接传递”这一假设(即前一层的输出作为下一层输入),但实际中,我们肯定会引入激活函数,那么 L k L_k Lk? 的表达式就会发生一些变动。因此,要对 W W W 进行反向调整就不能采取这样的思路。
对于这个问题的求解,我们不得不再次想起一个老朋友:梯度下降。
在机器学习中,很多算法最后都会转化为求目标损失函数(loss function)最小值的问题。这个损失函数往往很复杂,难以求出最值的解析表达式。而梯度下降法正是为了解决这类问题。有关该算法的描述和实现和请参见前面 线性回归 部分,在此不再赘述。
“梯度下降优化参数矩阵”的本质是这样的:在一个由待求参数 W W W 和样本数据构成的方程中,初始时赋 W W W 任意值,这时通过样本数据算出的 Y ^ \hat Y Y^ 值会与真实的 Y Y Y 值产生较大偏差。此时,我们可观察 Y ^ \hat Y Y^ 与 Y Y Y 的差距,并分析各项数据在变动时,会对 Y ^ \hat Y Y^ 产生何种影响,然后“因地制宜”地去改变 W W W 的取值以缩减 Y ^ \hat Y Y^ 与 Y Y Y 的差距。但是,怎么做到“因地制宜”呢?转换一下问题,如何得到某个值对函数的影响程度(因为影响程度大的会被用来进行调整,以缩减 Y ^ \hat Y Y^与 Y Y Y 的差距)?高中生帮你回答了:导数(作为大学生,你应该想到维度也许会很高,因此你的答案应该是:梯度)。
下面用一个简单的例子来说明如何利用梯度下降的思路来对参数矩阵进行更新。为便于理解,这里假设所搭建的神经网络模型为仅含单隐层的神经网络(原始数据的特征个数为 2),激活函数为 S i g m o i d Sigmoid Sigmoid 。则可得到此模型对应的函数为:
f ( W , x ) = 1 1 + e ? ( W 0 x 0 + W 1 x 1 + W 2 ) f(W, \text{x})=\frac{1}{1+e^{-(W_0\text{x}_0+W_1\text{x}_1+W_2)}} f(W,x)=1+e?(W0?x0?+W1?x1?+W2?)1?
现假设样本数据向量为 x = [ ? 1 , ? 2 ] T \text{x}=[-1,-2]^T x=[?1,?2]T,初始设置的随机参数矩阵为 W = [ 2 , ? 3 ] T W=[2,-3]^T W=[2,?3]T,初始设置的偏置项为 ? 3 -3 ?3,则可将该神经网络的前向传播过程描述如下:
接下来需要根据计算得到的结果进行反向传播。前面提到,在反向传播的过程中,必须逐层更新(即逐层求导,以对前一层参数进行更新,遵从链式法则),因此这里先给出本模型中涉及到的所有函数的导数公式,以便计算与理解:
d ( x + a ) d x = 1 d ( a x ) d x = a d ( e x ) d x = e x d ( 1 x ) d x = ? 1 x 2 \frac{\text{d}(x+a)}{\text{d} x}=1 \quad\quad \frac{\text{d}(ax)}{\text{d} x}=a \quad\quad \frac{\text{d}(e^x)}{\text{d} x}=e^x \quad\quad \frac{\text{d}(\frac{1}{x})}{\text{d} x}=-\frac{1}{x^2} dxd(x+a)?=1dxd(ax)?=adxd(ex)?=exdxd(x1?)?=?x21?
d ( σ ( x ) ) d x = d ( 1 1 + e ? x ) d x = e ? x ( 1 + e ? x ) 2 = ( 1 + e ? x ? 1 1 + e ? x ) ( 1 1 + e ? x ) = ( 1 ? 1 1 + e ? x ) ( 1 1 + e ? x ) = ( 1 ? σ ( x ) ) σ ( x ) \begin{align} \nonumber \frac{\text{d}(\sigma(x))}{\text{d} x}&=\frac{\text{d}(\frac{1}{1+e^{-x}})}{\text{d} x} \\ \nonumber &= \frac{e^{-x}}{(1+e^{-x})^2} \\ \nonumber &=\left(\frac{1+e^{-x}-1}{1+e^{-x}}\right)\left(\frac{1}{1+e^{-x}}\right) \\ \nonumber &=\left(1-\frac{1}{1+e^{-x}}\right)\left(\frac{1}{1+e^{-x}}\right) \\ \nonumber &=\left(1-\sigma(x)\right)\sigma(x) \nonumber \end{align} dxd(σ(x))??=dxd(1+e?x1?)?=(1+e?x)2e?x?=(1+e?x1+e?x?1?)(1+e?x1?)=(1?1+e?x1?)(1+e?x1?)=(1?σ(x))σ(x)?
现在看我们的参数,主要有 W 0 , W 1 , W 2 W_0, W_1, W_2 W0?,W1?,W2? ,前向传播的计算顺序是 W 0 , W 1 W_0, W_1 W0?,W1? 然后再是 W 2 W_2 W2? ,因此在反向传播时,需要先计算 W 2 W_2 W2? 的梯度然后再计算 W 0 , W 1 W_0, W_1 W0?,W1? 。总结就是:在计算梯度时需要从后往前计算。
如在下图中,对于函数 1 x \frac1x x1?,由于 d 1 x d x = ? 1 x 2 \frac{\text{d}\frac{1}{x}}{\text{d}x}=-\frac{1}{x^{2}} dxdx1??=?x21?,因此可算出该步骤的梯度值为: d 1 x d x ∣ x = 1.37 = ? 1 1.37 2 ≈ ? 0.53 \frac{\text{d}\frac{1}{x}}{\text{d}x}\bigg|_{x = 1.37}=-\frac{1}{{1.37}^2}\approx-0.53 dxdx1?? ?x=1.37?=?1.3721?≈?0.53;对于函数 x + 1 x+1 x+1 ,由于 d ( x + 1 ) d x = 1 \frac{\text{d}(x+1)}{\text{d}x}=1 dxd(x+1)?=1,因此可算出该步骤的梯度值为: d ( x + 1 ) d x ∣ x = 1.37 = 1 \frac{\text{d}(x+1)}{\text{d}x}\bigg|_{x = 1.37}=1 dxd(x+1)? ?x=1.37?=1,由于其前一步梯度值为 ? 0.53 -0.53 ?0.53,因此在这里得到的最终梯度值为 1 × ( ? 0.53 ) = ? 0.53 1\times (?0.53) = ?0.53 1×(?0.53)=?0.53 ;对于函数 e x e^x ex ,可算出该步骤的梯度值为: d e x d x ∣ x = ? 1.00 ≈ ? 0.37 \frac{\text{d}e^x}{\text{d}x}\bigg|_{x = -1.00}\approx-0.37 dxdex? ?x=?1.00?≈?0.37,由于前一步梯度值为 ? 0.53 -0.53 ?0.53,因此在这里得到的最终梯度值为 0.37 × ( ? 0.53 ) ≈ ? 0.20 0.37\times(?0.53) \approx?0.20 0.37×(?0.53)≈?0.20 ;对于函数 ? x -x ?x,可算出该步骤的梯度值为: d ? x d x ∣ x = 1.00 = ? 1 \frac{\text{d}-x}{\text{d}x}\bigg|_{x = 1.00}=-1 dxd?x? ?x=1.00?=?1,则该处最终的梯度值为 ? 1 × ( ? 0.20 ) = 0.20 ?1 \times (?0.20) = 0.20 ?1×(?0.20)=0.20 。
接下来对于 W 0 x 0 + W 1 x 1 + W 2 W_0\text{x}_0+W_1\text{x}_1+W_2 W0?x0?+W1?x1?+W2? 这个整体而言,由于 ? ( W 0 x 0 + W 1 x 1 + W 2 ) ? W 2 = 1 \frac{\partial(W_0\text{x}_0+W_1\text{x}_1+W_2)}{\partial W_2}=1 ?W2??(W0?x0?+W1?x1?+W2?)?=1,因此该反向传播最终传递到 W 2 W_2 W2? 的梯度为 1 × 0.20 = 0.20 1 × 0.20 = 0.20 1×0.20=0.20 。
在正向传播过程中,注意到蓝框部分实际上是 S i g m o i d Sigmoid Sigmoid 门单元。因此,在计算梯度时可以直接对这个整体进行求解:
对 f ( W , x ) = 1 1 + e ? ( W 0 x 0 + W 1 x 1 + W 2 ) f(W, \text{x})=\frac{1}{1+e^{-(W_0\text{x}_0+W_1\text{x}_1+W_2)}} f(W,x)=1+e?(W0?x0?+W1?x1?+W2?)1?,令 z = W 0 x 0 + W 1 x 1 + W 2 z=W_0\text{x}_0+W_1\text{x}_1+W_2 z=W0?x0?+W1?x1?+W2?,则可将原方程改写为: f ( W , x ) = σ ( z ) f(W, \text{x})=\sigma(\text{z}) f(W,x)=σ(z) (其中 σ ( z ) = 1 1 + e ? z \sigma(\text{z})=\frac{1}{1+e^{-\text{z}}} σ(z)=1+e?z1? 为 Sigmoid 函数)。
此时再对 W 2 W_2 W2? 求偏导,则有: ? f ? W 2 = ? σ ? W 2 = ? σ ? z × ? z ? W 2 = [ ( 1 ? σ ( ( z ) ) σ ( ( z ) ) ) ] × 1 = e ? z ( 1 + e ? z ) 2 \frac{\partial f}{\partial W_2}=\frac{\partial \sigma}{\partial W_2} = \frac{\partial \sigma}{\partial \text{z}} \times \frac{\partial \text{z}}{\partial W_2}=\left[(1-\sigma(\text(z))\sigma(\text(z)))\right]\times1= \frac{e^{-\text{z}}}{(1+e^{-\text{z}})^2} ?W2??f?=?W2??σ?=?z?σ?×?W2??z?=[(1?σ((z))σ((z)))]×1=(1+e?z)2e?z?。
将 z = W 0 x 0 + W 1 x 1 + W 2 = 1.00 \text{z}=W_0\text{x}_0+W_1\text{x}_1+W_2=1.00 z=W0?x0?+W1?x1?+W2?=1.00 带入可得到梯度为 ? f ? W 2 ∣ z = ? 1.00 = ? σ ? W 2 ∣ z = ? 1.00 = e ? z ( 1 + e ? z ) 2 ∣ z = ? 1.00 = e ? 1 ( 1 + e ? 1 ) 2 ≈ 0.20 \frac{\partial f}{\partial W_2}\bigg|_{\text{z} = -1.00}=\frac{\partial \sigma}{\partial W_2}\bigg|_{\text{z} = -1.00}=\frac{e^{-\text{z}}}{(1+e^{-\text{z}})^2}\bigg|_{\text{z} = -1.00}=\frac{e^{-1}}{(1+e^{-1})^2}\approx0.20 ?W2??f? ?z=?1.00?=?W2??σ? ?z=?1.00?=(1+e?z)2e?z? ?z=?1.00?=(1+e?1)2e?1?≈0.20。
可以看出,采取这种方式计算的结果与前面是相同的。
当 W 2 W_2 W2? 的梯度计算完毕后,就能计算 W 1 , W 0 W_1, W_0 W1?,W0? 的梯度了。对于函数 x + y x+y x+y ,可算出其梯度为: ? ( x + y ) ? x ∣ x = 4.00 = 1 \frac{\partial(x+y)}{\partial x}\bigg|_{x = 4.00}=1 ?x?(x+y)? ?x=4.00?=1。取 x = W 0 x 0 + W 1 x 1 , y = W 2 x=W_0\text{x}_0+W_1\text{x}_1, y=W_2 x=W0?x0?+W1?x1?,y=W2? ,则可得到传递至 W 0 x 0 + W 1 x 1 W_0\text{x}_0+W_1\text{x}_1 W0?x0?+W1?x1? 这个整体的梯度为 1 × 0.20 = 0.20 1 \times 0.20 = 0.20 1×0.20=0.20 。实际上,加法门单元(诸如 x + y x+y x+y 的式子)在进行梯度传递时,它会将上一步的梯度直接分给加法门中的每个元素。所以,对于 W 0 x 0 W_0\text{x}_0 W0?x0? 和 W 1 x 1 W_1\text{x}_1 W1?x1? 而言,它们都将直接得到前面算出的梯度值:0.20。
接着,由于 d ( W 1 x 1 ) d W 1 = x 1 \frac{\text{d}(W_1\text{x}_1)}{\text{d}W_1}=\text{x}_1 dW1?d(W1?x1?)?=x1?,因此该反向传播最终传递到 W 1 W_1 W1? 的梯度为 x 1 × 0.20 = ? 2.00 × 0.20 = ? 0.40 \text{x}_1 × 0.20 = ?2.00 × 0.20 = ?0.40 x1?×0.20=?2.00×0.20=?0.40。同理可得到最终传递到 W 0 W_0 W0? 的梯度为 ?0.20 。
以上便是神经网络的反向传播过程,当我们对样本数据执行这一过程后,就能得到参数矩阵中各值的梯度。接下来就能利用梯度下降算法来对参数矩阵进行更新,从而不断优化整个神经网络的预测能力。
四、激活函数的选择
前面提到,神经网络为了使模型更强而会对各层之间的数据进行非线性处理,对于这一处理所用到的函数我们称之为“激活函数”。前面我们曾介绍过 Sigmoid 函数,但是在实际使用时这个函数并不常用。因为 Sigmoid 函数在取值为 [ ? 3 , 3 ] [-3, 3] [?3,3] 的区间时,其取值范围就已经达到 [ 0 , 0.95 ] [0, 0.95] [0,0.95] 。因此,当数据的计算结果在 [ ? 3 , 3 ] [-3, 3] [?3,3] 之外时,就基本上不会发生多大改变。说直接点就是, Sigmoid 函数的变化率(梯度)在取值较大或较小时,基本上就为 0 了(这点也能从其图像中直观地看出)。所以,当在神经网络中使用 Sigmoid 函数作为激活函数时,也许会因为样本数据总体偏大而使得反向传播过程中(每层)算出的梯度都偏小。试想, 0. 9 50 ≈ 0.0515 0.9^{50} ≈ 0.0515 0.950≈0.0515。那么在一些层次较深的神经网络中使用 Sigmoid 函数时,很有可能这个梯度值慢慢地就被“吃掉”了(变为 0),我们把这一现象称为“梯度消失” 。因此,在实际操作时,我们通常会选择一些其他的函数来作为激活函数。其中,最常用的两个是 ReLu 函数和 Softmax 函数。
1、ReLu 函数
ReLu 函数的定义如下:
σ ( x ) = { max ( 0 , x ) , x ≥ 0 0 , x < 0 \sigma(x)=\begin{cases} \text{max}(0, x) & , x\geq0 \\ 0 & , x<0 \end{cases} σ(x)={max(0,x)0?,x≥0,x<0?
其图像如下图所示:
ReLu 函数相较 Sigmoid 其主要有以下优点:
- 计算速度快。 Sigmoid 函数需要计算指数,而 ReLu 函数只需要比较大小;
- ReLU 函数的非饱和性可以有效地解决梯度消失的问题, 提供相对宽的激活边界。
- 使用 ReLU 函数可以达到更快的收敛速度。
2、Softmax 函数
Softmax 是用于多类分类问题的激活函数,在多类分类问题中,超过两个类标签就需要类成员关系。对于长度为 K 的任意实向量,Softmax 可以将其压缩为值在 [ 0 , 1 ] [0, 1] [0,1] 之间,且向量中元素总和为 1 的实向量(有关 softmax 的更多内容请参见前面 逻辑回归 部分)。Softmax 函数的定义为:
y ^ i = 1 ∑ j = 1 k e f ( x ( i ) ; W j , b ) [ e f ( x ( i ) ; W 1 , b ) e f ( x ( i ) ; W 2 , b ) … e f ( x ( i ) ; W k , b ) ] \hat y_i=\frac{1}{\sum^k_{j=1}e^{f(\text{x}^{(i)};W_j, b)}}\begin{bmatrix} e^{f(\text{x}^{(i)};W_1, b)}\\ e^{f(\text{x}^{(i)};W_2, b)}\\ \dots\\ e^{f(\text{x}^{(i)};W_k, b)} \end{bmatrix} y^?i?=∑j=1k?ef(x(i);Wj?,b)1? ?ef(x(i);W1?,b)ef(x(i);W2?,b)…ef(x(i);Wk?,b)? ?
这一操作使得所有输入数据都具有了一个相对概率,从而便于我们进行比较,并保留了概率具有不稳定性的特性(即就算某个样本在某些类别上的得分较低,但它仍有可能归类于这些类)。
在采用 Softmax 后,可将前面计算概率的过程进一步表示为:
五、结语
首先要说明一点,深度学习本身是一个非常庞大的方向, 其下属的研究内容十分广泛,且颇具研究价值。而本文的内容,仅仅是一篇导论性质的文章,仅供初入机器学习和深度学习的学者们参考。
随着人工智能的兴起和计算机算力的不断提升,深度学习从机器学习的众多方向中脱颖而出,并不断迸发出强烈生机。基于此,近年来有关深度学习的研究在不断更新,不断前进,有关它的相关领域也早已形成了自己特有的一些研究范畴。所以,虽然本章“深度学习”的内容结束了,但实际上却也刚刚开始。限于本栏的类属,对于深度学习的内容将不再继续深入,感兴趣的同学可以自己去查阅一些其他优秀博主的文章自行学习。
END
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!