注意:本文引用自专业人工智能社区Venus AI
更多AI知识请参考原站 ([www.aideeplearning.cn])
引言
神经网络,作为人工智能和机器学习领域的核心技术之一,具有极其重要的意义。它们通过模拟人类大脑的工作机制,使计算机能够学习和识别复杂的模式和数据。这种能力使得神经网络在诸多领域,如图像和语音识别、自然语言处理、医学诊断以及金融预测等,都发挥着至关重要的作用。神经网络能处理和解析大量数据,提供深入见解,推动了科技和各行各业的创新与进步。它们的应用不仅改善了技术解决方案的效率和准确性,还开启了新的研究领域和技术前沿,对现代科技发展产生了深远影响。
神经网络起始于线性模型,这是一种基于属性加权和的预测方法,结合损失函数和梯度下降算法进行优化,广义线性模型则进一步扩展了其应用。在处理回归和分类问题方面,线性模型可通过调整损失函数和优化方法来适应不同的任务,涉及到预测连续值或离散标签。
线性模型是感知机模型的基础,感知机模型是构建神经网络和深度学习的基石。当多个感知机层叠形成复杂的神经网络时,我们进入了深度学习的领域。下面是神经网络的一些关键概念和组成部分:
- 输入层(Input Layer):这是神经网络的第一层,负责接收输入数据。每个节点代表输入数据的一个特征。
- 隐藏层(Hidden Layers):在输入层和输出层之间的是隐藏层。这些层可以有多个,它们负责从输入数据中提取和学习特征。隐藏层的节点数量和层数可以根据具体问题进行调整。
- 输出层(Output Layer):这是网络的最后一层,负责输出最终结果。输出层的设计取决于特定任务(如分类、回归等)。
- 权重和偏置(Weights and Biases):每个连接都有一个权重,每个节点都有一个偏置。权重和偏置是网络学习的参数,它们在训练过程中不断调整。
- 激活函数(Activation Functions):激活函数决定了节点是否应该被激活,即是否对信息做出响应。常见的激活函数包括Sigmoid、ReLU(Rectified Linear Unit)等。
- 前向传播(Forward Propagation):在这个过程中,数据从输入层通过隐藏层流向输出层。每个隐藏层的节点都会根据输入、权重、偏置和激活函数计算输出。
- 损失函数(Loss Function):损失函数用于评估模型的预测与真实值之间的差异。常见的损失函数包括均方误差(MSE)和交叉熵(Cross-Entropy)。
- 反向传播(Backpropagation):这是神经网络中的关键学习过程。通过反向传播,网络根据损失函数的梯度更新权重和偏置,以减少预测错误。
- 优化器(Optimizer):优化器决定了网络如何更新其权重和偏置。常用的优化器包括梯度下降(Gradient Descent)、Adam等。
下面,我们讲逐步进行展开的细致讲解。
1 线性模型
1.1 线性模型的定义
线性模型有一个 n 维权重 ω 和一个标量偏差 b :
对于给定的输入 x :
线性模型得到的输出 y 等于输入 x 与权重 ω 的加权求和, 再加上偏置 b, 即:
向量版本的写法为:
线性模型相乘求和的含义是什么? 相乘的含义是通过权重对输入信息进行重要程度的重分配; 而求和的目的是综合考虑所有信息。例如, 生活中房价。假设影响房价的关键因素是卧室的个数、卫生间的个数、居住面积, 记为 那么成交价 y 等于:
其中, ω1,ω2,ω3 通过相乘的方法决定了因素 x1,x2,x3 的权重, 而偏置 b 则是一种纠正,例如即使是同一地域条件差不多的房型, 因为卖家和买主的个人原因, 成交价也是在一个小范围内浮动的, 这就是偏置的概念。
1.2 损失函数
1.1节介绍了线性模型的计算方法,那么如何衡量线性模型的输出值是否准确呢?一般会使用数据的真实值作为衡量标准。还是之前房价的例子,当对某地域的某房型进行估值时,可以使用往年该地域的同类房型的出售价格作为真实值。
假设 是真实值, 是估计值, 则可以比较:
这就是经典的平方损失。它可作为衡量估计值和真实值之间距离的表征, 期望的是让ℓ 尽可能地小, 因为当 ℓ 足够小时, 就说明模型的输出结果无限接近于数据的真值。将 y^ 替换为 〈ω,x〉+b, 则上式变成:
实现让 ℓ 尽可能地小这个期望的方法被称作模型的训练。深度学习中常用的模型训练方法是有监督训练, 详细流程如下。
1.3 梯度下降算法
首先制作一个训练数据集,在当前房价的例子中,可以收集过去两年的房子交易记录。房子的数据(面积、地域、采光等)作为训练集,对应的房子成交价格作为真实值。这些训练数据会随着时间的积累越来越多。然后可以创建一个线性模型,先随机初始化其中的权重和偏置,再将训练数据送进模型,得到一个计算结果,即估计值。此时,由于参数是随机初始化的,这个预估值大概率不准确;接下来使用真实值与预估值进行比较,根据比较的结果反馈,来更新新的模型权重,这个更新权重的方法被称为梯度下降算法,具体解释如下:
从某种程度上,读者可以把梯度理解成某函数偏导数的集合,例如函数的梯度为:
当某函数只有一个自变量时,梯度实际上就是导数的概念。
需要注意的是,梯度是一个向量,既有大小又有方向。梯度的方向是最大方向导数的方向,而梯度的模是最大方向导数的值。另外,梯度在几何上的含义是函数变化率最大的方向。沿着梯度向量的方向前进,更容易找到函数的最大值,反过来说,沿着梯度向量相反的方向前进是梯度减少最快的方向,也就是说更容易找到函数的最小值。
例如,维基百科上用来说明梯度的图片特别典型,说明非常形象,所以引来供读者学习。
设函数 f(x,y)=−(cos2x+cos2y)2, 则梯度 gradf(x,y) 的几何意义可以描述为在底部平面上的矢量投影。每个点的梯度是一个矢量,其长度代表了这点的变化速度,而方向表示了其函数增长速率最快的方向。通过梯度图可以很清楚地看到,在矢量长的地方,函数增长速度就快,而其方向代表了增长最快的方向,梯度图如图1所示。
现在回到损失 ℓ 的概念, ℓ 也是一种函数(例如平方差损失函数),因此要求 ℓ 的最小值,实际上只需要沿着 ℓ 梯度的反方向寻找即可,这就是梯度下降的概念。其公式表示为:
上述公式中-grad表示梯度的反方向, 新的权重 等于之前的权重 向梯度的反方向前进的量。图1中的函数平面化后表示的梯度下降过程如图2所示。
(1) 随机初始化一个初始值 。
(2) 重复迭代梯度下降算法, 即 。
(3) 此时,更新后的权重会比之前的权重得到一个更小的函数值,即 。
(4) η 是学习率的意思, 表征参数更新的快慢, 通过 η×grad 直接影响参数的更新速度。
当 η 过小时, 更新速度太慢, 如图3(a)所示; 当 η 过大时, 容易出现梯度震荡, 如图3(b)所示, 这些都是不好的影响。
需要注意的是,学习率是直接决定深度学习模型训练成功与否的关键因素。当一个深度学习模型效果不好或者训练失败时,不一定是模型设计的原因,也可能是训练策略所导致,其中学习率就是训练策略的主要因素之一。在训练时往往会先选择一个较小的学习率(例如0.0001)进行训练,再逐步调大学习率观察模型的训练结果。此外,训练数据集也会直接影响模型的效果,即模型的效果=训练集+模型设计+训练策略。
最后,在有监督训练深度学习模型时,往往不会在一次计算中使用全部的数据集,因为训练数据集往往很大,全部使用时计算资源和内存会不够用。因此,一般情况下会采用一种被称为小批量随机梯度下降的算法。具体的方法是从训练数据集中随机采用b个样本, 来近似损失,此时损失的表示如下:
上述公式中,b代表批量大小,是一个深度学习训练过程中重要的超参数。当b太小时,每次计算量太小,不适合最大程度利用并行资源;更重要的是,b太小意味着从训练数据集中抽样的样本子集数量少,此时子集的数据分布可能与原始数据集相差较大,并不能很好地代替原始数据集。当b太大时,可能会导致存储或计算资源不足。根据b的大小,梯度下降算法可以分为批量梯度下降法(Batch gradient descent,BGD)、随机梯度下降法(Stochastic Gradient Descent,SGD), 以及小批量梯度下降法(mini-batch gradient descent,MBGD)。
批量梯度下降法是梯度下降法常用的形式,具体做法是在更新参数时使用所有的样本来进行更新。由于需要计算整个数据集的梯度,将导致梯度下降法的速度可能非常缓慢,且对于内存小而数据集庞大的情况十分棘手。而批量梯度下降法的优点是理想状态下,经过足够多的迭代后可以达到全局最优。
随机梯度下降法和批量梯度下降法原理类似,区别在于随机梯度下降法在求梯度时没有用所有的样本数据,而是仅仅选取一个样本来求梯度。正是为了加快收敛速度,并且解决大数据量无法一次性塞入内存的问题。但是由于每次只用一个样本来更新参数,随机梯度下降法会导致不稳定。每次更新的方向,不像批量梯度下降法那样每次都朝着最优点的方向逼近,而是会在最优点附近震荡。
其实,批量梯度下降法与随机梯度下降法是两个极端,前者采用所有数据来进行梯度下降,如图4(a)所示;后者采用一个样本来进行梯度下降,如图4(b)所示。两种方法的优缺点都非常突出,对于训练速度来说,随机梯度下降法由于每次仅仅采用一个样本来迭代,训练速度很快;而批量梯度下降法在样本量很大的时候,训练速度不能让人满意。对于准确度来说,随机梯度下降法仅仅用一个样本决定梯度方向,导致有可能不是最优解。对于收敛速度来说,由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快地收敛到局部最优解。那么,有没有一个办法能够结合两种方法的优点呢?
这就是小批量梯度下降法,如图4(c)所示。即每次训练从整个数据集中随机选取一个小批量样本用于模型训练,这个小批量样本的大小是超参数,一般来说越大越准,当然训练也会越慢。
除此之外,还可以对小批量梯度下降法做进一步的优化,例如加入动量(momentum)的思想。动量本质上是指数移动平均(Exponential Moving Average,EMA)。EMA是一种给予近期数据更高权重的平均方法。其数学表达式如下:
下面来看一下公式推导:
假设:
逐层向上代入得:
上述公式实际上是对时刻 t 之前 (包括 t ) 的实际数值进行加权平均, 时间越近, 权重越大, 而且采用指数式的加权方式, 因此被称为指数加权平均。
与一般情况下计算截至时刻 t 的平均值 相比, 指数移动平均的方法有两个明显的好处:
(1)一般的平均值计算方法需要保存前面所有时刻的实际数值, 会消耗额外的内存。 EMA 则不会。
(2)指数移动平均在有些场景下, 其实更符合实际情况, 例如股票价格, 天气等,上一个时间傩的情况对当前时间戳下的结果影响最大。
梯度下降过程中, 用指数移动平均融合历史的梯度, 收玫速度和稳定性都有显著收益,其中历史梯度被称为动量项(Momentum)。带动量的 SGD 优化步骤如下:
其中, 是上一时刻的梯度,是用 EMA 融合历史梯度后的梯度, 是当前时刻的梯度。 β 是一个超参数, 被称为动量项。由 EMA 的原理可知, 虽然上述里只用到了上一时刻的梯度, 但其实是当前时刻之前的所有历史梯度的指数平均。
加入动量项后进行模型权重的更新,比直接用原始梯度值,抖动更小更加稳定,也可以快速冲过误差曲面(Error Surface)上的鞍点等比较平坦的区域。其原理可以想象成滑雪运动,当前的运动趋势总会受到之前动能的影响,所以滑雪的曲线才比较优美平滑,不可能划出90°这样陡峭的直角弯;当滑到谷底时,虽然地势平坦,但是由于之前动能的影响,也会继续往前滑,有可能借助动量冲出谷底。
小结一下,加入动量项的好处如下:
(1)在下降初期时,动量方向与当前梯度方向一致,能够进行很好的收敛加速效果。
(2)在下降后期时,梯度可能在局部最小值附近震荡,动量可能帮助跳出局部最小值。
(3)在梯度改变方向时,动量能够抵消方向相对的梯度,抑制振荡,从而加快收敛。
1.4 广义线性模型
除了直接让模型预测值逼近实值标记y,还可以让它逼近 y 的衍生物,这就是广义线性模型(Generalized Linear Model,GLM)。
其中, g(.)称为联系函数(Link Function),要求单调可微。使用广义线性模型可以实现强大的非线性函数映射功能。例如对数线性回归(Log-linear Regression, LR),令 g(.)=ln(.)此时模型预测值对应的是真实值标记在指数尺度上的变化, 如图 5 所示。
2 回归与分类
2.1 回归和分类问题的定义与联系
本小节的主要目的是考虑如何将线性模型运用到回归和分类任务当中去。不管是分类,还是回归,其本质是一样的,都是对输入做出预测,并且都是监督学习。也就是根据特征分析输入的内容来判断它的类别或者预测其值。而回归和分类区别在于它们的输出不同:分类问题输出的是物体所属的类别,回归问题输出的是物体的值。
例如,最近曼彻斯特的天气比较怪(阴晴不定),为了能够对明天穿衣服的数量和是否携带雨具做判断,就要根据已有天气情况做预测。如果定性地预测明天及以后几天的天气情况,如周日阴,下周一晴,这就是分类;如果要预测每一个时刻的温度值,得到这个值用的方法就是回归。
(1)分类问题输出的结果是离散的,回归问题输出的值是连续的。
总的来说,对于预测每一时刻的温度这个问题,在时间上是连续的,因此属于回归问题;而对于预测某一天天气情况这个问题,在时间上是离散的,因此属于分类问题。
(2)分类问题输出的结果是定性的,回归问题输出的值是定量的。
定性是指确定某种东西的确切的组成有什么或者某种物质是什么,定性不需要测定这种物质的各种确切的数值量。所谓定量就是指确定某种成分(物质)的确切数值量,这种测定一般不用特别地鉴定物质是什么。例如,这是一杯水,这句话是定性;这杯液体有10毫升,这是定量。
总结一下:分类的目的是为了寻找决策边界,即分类算法得到是一个决策面,用于对数据集中的数据进行分类。 回归的目的是为了找到最优拟合,通过回归算法得到是一个最优拟合线,这个线条可以最优的接近数据集中的各个点。
2.2 线性模型解决回归和分类问题
线性模型的输出可以是任意一个实值,也就是值域是连续的,因此天然可以用于做回归问题,例如预测房价、股票的成交额、未来的天气情况等。而分类任务的标记是离散值,怎么把这两者联系起来呢?其实广义线性模型已经给了我们答案。我们要做的就是找到一个单调可微的联系函数,把两者联系起来。对于一个二分类任务,比较理想的联系函数是单位阶跃函数(Unit-step Function):
但是单位阶跃函数不连续,所以不能直接用作联系函数。这时思路转换为如何在一定程度上近似单位阶跃函数呢?逻辑函数(Logistic Function) 正是常用的替代函数,其公式如下:
逻辑函数图像如图6所示。
逻辑函数有时也称为Sigmoid函数(即形似S的函数)。将它作为g(.)代入广义线性模型,即可将模型任意地连续输出映射到一个[0,1]的值域中,此时可以使用阈值分割的方法进行分类问题。例如,根据模型的输出大于0.5或小于0.5可以把输入信息分成两个不同的类别。
3 神经网络模型
3.1感知机模型定义与理解
感知机模型是神经网络算法中最基础的计算单元,模型公式如下:
其中, x 是感知机模型接收的输入信息; ω 是一个长度为任意长度的向量, 也是感知器训练过程中需要求得的参数。以长度为 4 的输入向量举例, 感知机模型的图形化表示如图7所示。
实际上,感知机就是一个类似广义线性模型的模型,为什么说广义呢?我们可以回顾一下关于广义线性模型的定义:除了直接让模型预测值逼近实值标记 y,还可以让它逼近 y 的衍生物,这就是广义线性模型。
其中g(.)称为联系函数,要求单调可微。使用广义线性模型可以实现强大的非线性函数映射功能。注意,这里的g(.)要求单调可微,但是感知机中的g(.)是一个判断结果是否大于0的判断语句,并不满足单调可微的要求。
至于神经网络模型,就是由很多感知机模型组成的结果,类似图8。
3.2 神经网络算法与深度学习模型
神经网络模型有三个组成成分:输入层,隐藏层和输出层,每一个都是由感知机模型组成的。其中,输入层指的是网络的第一层,是负责接收输入信息的;输出层指的是网络的最后一层,是负责输出网络计算结果的;而中间的所有层统一称为隐藏层,隐藏在的层数和每层的感知机数量都属于神经网络模型的超参数可以进行调整,如果隐藏层的数量大于一层,那么一般称呼这样的模型为多层感知机模型(Multi-layer perception model,MLP)。当隐藏层的数量很多时,例如十几层、几百次甚至几千层,称呼这样的模型为深度学习模型。
所以,深度学习其实并不神秘,它就等价于神经网络算法;我们把隐藏层很多的模型称作深度学习模型。至于深度学习模型的训练方式与之前介绍的线性模型求解方法一致,即,先用损失函数来衡量模型计算结果和数据真实值之间的损失,对损失进行梯度下降来更新模型当中的梯度,直至收敛。
3.3 反向传播算法
梯度下降和反向传播是神经网络训练过程中两个非常重要的概念,它们密切相关。梯度下降是一种常用的优化算法,它的目标是找到一个函数的最小值或最大值。在神经网络中,梯度下降算法通过调整每个神经元的权重,以最小化网络的损失函数。损失函数是用来衡量网络的输出与真实值之间的误差。梯度下降算法的核心思想是计算损失函数对权重的偏导数,然后按照这个偏导数的反方向调整权重。
反向传播是一种有效的计算梯度的方法,它可以快速计算网络中每个神经元的偏导数。反向传播通过先正向传播计算网络的输出,然后从输出层到输入层反向传播误差,最后根据误差计算每个神经元的偏导数。反向传播算法的核心思想是通过链式法则将误差向后传递,计算每个神经元对误差的贡献。
综上所述,梯度下降和反向传播是神经网络训练过程中两个重要的概念,梯度下降算法用于优化网络的权重,反向传播算法用于计算每个神经元的偏导数。它们密切相关,并在神经网络的训练中起着重要的作用。下面用一个例子演示神经网络层参数更新的完整过程。
(1)初始化网络,构建一个只有一层的神经网络,如图9所示。
假设图 9中神经网络的输入和输出的初始化为: 。参数的初始化为: 。
(2) 前向计算, 如图10所示。
根据输入和权重计算 得:
同理, 计算 等于 0.95 。将 和 相乘求和到前向传播的计算结果, 如图 11所示。
(3) 计算损失: 根据数据真实值 y=0.8 和平方差损失函数来计算损失, 如图12所示。
(4) 计算梯度: 此过程实际上就是计算偏微分的过程, 以参数 的偏微分计算为例,如图13所示。
根据链式法则:
其中:
所以:
(5) 反向传播计算梯度: 在第 4 步中是以参数 为例子来计算偏微分的。如果以参数 为例子, 它的偏微分计算就需要用到链式法则, 过程如图14所示。
(6)梯度下降更新网络参数
假设这里的超参数 “学习速率” 的初始值为 0.1 , 根据梯度下降的更新公式, 参数的更新计算如下所示:
同理, 可以计算得到其他的更新后的参数:
到此为止, 我们就完成了参数迭代的全部过程。可以计算一下损失看看是否有减小, 计算如下:
此结果相比较于之间计算的前向传播的结果 2.205, 是有明显的减小的。
4.激活函数的定义与作用
激活函数是深度学习、人工神经网络中一个十分重要的学习内容,对于人工神经网络模型去学习、理解非常复杂和非线性的函数来说具有非常重要的作用。在深度学习模型中,一般习惯性地在每层神经网络的计算结果输入下一层神经网络之前先经过一个激活函数,如图15所示。
激活函数的本质是一个非线性的数学式子,其具体形态有很多种。神经网络的计算本质上就是一个相乘求和的过程,当不用激活函数时,网络中各层只会根据权重和偏差b进行线性变换,就算有多层网络,也只是相当于多个线性方程的组合,依然只是相当于一个线性回归模型,解决复杂问题的能力有限,因为生活中绝大部分的问题都是非线性问题。如果希望神经网络能够处理复杂任务,但线性变换无法执行这样的任务,使用激活函数就能对输入进行非线性变换,使其能够学习和执行更复杂的任务。
Sigmoid函数
Sigmoid函数可以将输入的整个实数范围内的任意值映射到[0, 1]范围内,当输入值较大时,会返回一个接近于1的值;当输入值较小时,则返回一个接近于0的值。Sigmoid函数的数学公式如下,Sigmoid函数图像如图16所示。
Sigmoid函数的优点:输出在映射区间(0, 1)内单调连续,非常适合用作输出层,并且比较容易求导。
Sigmoid函数的缺点:其解析式中含有幂运算,计算机求解时相对比较耗时,对于规模比较大的深度网络,会较大地增加训练时间。且当输入值太大或者太小时,对应的值域变化很小,这容易导致网络训练过程中的梯度弥散问题。
tanh函数
tanh函数与Sigmoid函数相似,实际上,它是Sigmoid函数向下平移和伸缩后的结果,它能将值映射到[-1, 1]的范围。相较于Sigmoid函数,tanh函数的输出均值是0,使得其收敛速度要比Sigmoid函数快,减少了迭代次数,但它的幂运算的问题依然存在。
tanh函数的数学公式如下,tanh函数图像如图17所示。
ReLU函数
ReLU函数是目前被使用最为频繁的激活函数,当 x<0 时,ReLU函数输出始终为0;当 x>0 时,由于ReLU函数的导数为1,即保持输出为x,所以ReLU函数能够在 x>0时保持梯度不断衰减,从而缓解梯度弥散的问题,还能加快收敛速度。
ReLU函数的数学公式如下,ReLU函数图像如图18所示。
类比初中生物课的一个小实验来理解非线性。读者们应该还记得初中生物课本上有一个使用电流来刺激青蛙大腿肌肉的实验吧。当电流不强时,青蛙的大腿肌肉是不反应的,只有电流到达一定强度,青蛙大腿肌肉才开始抽搐,而且电流越大,抽搐的越剧烈。这个反应过程如果画出来的话,实际上与ReLU函数非常相似,这体现了生物的非线性,正是这种非线性反应,让生物体拥有了决策的能力,以适应复杂的环境。所以,在神经网络层后接激活函数的原因,就是给模型赋予这种非线性的能力,让模型通过训练的方式可以拟合更复杂的问题与场景。