3990 字
5 分钟
13 次
- 2026-08-16
前言
大部分是我在空闲时间对深度学习一些知识的复盘,可能并不是完全正确的。我只是利用 费曼学习法 在对我学习到的一些知识的解释,毕竟如果你自己能解释清楚知识点,才说明你真的学会了。
神经网络原理、CNN、RNN
深度学习,特指基于深层神经网络模型和方法的机器学习,它重要的特点是具有自动提取特征的能力。 神经网络是深度学习的核心,神经网络模仿人脑神经元的工作方式,通过层层的链接与计算,理解数据特征。 深度学习其实就是多层堆叠,并且具备分层自动特征理解的深层神经网络。 神经网络的基本结构是神经元,神经元主要做加权求和、加偏置、激活函数转换、输出。也就是说,神经元是一个计算容器。
神经网络的每一层有很多神经元,每一层都是对输入的数据做特征提取。上一层的神经元输出结果后,传递到下一个神经元,称之为一次连接。每次神经元连接,就是上层神经元计算的值,传递到下一层神经元,并且这次传递是带权重的,神经元依据这次权重进行计算。偏置是与神经元绑定,每个神经元独有一个偏置项,但是权重不是属于神经元的,而是神经元连接参数。
神经网络的训练,实际上是计算一个匹配数据规律或者说特征的内部权重集合。类似解方程,训练数据集的数据集类比函数图像上的点(x, y),训练模型实际上就是根据函数图像上的点,计算出方程的未知变量,使其匹配函数图像。当然,实际上的神经网络是非线性的复杂函数,不能够通过“图像的点”求出解,只能近似拟合。
神经网络具有自动提取特征的能力,体现在其能够在一次次的训练中,根据预期输出和实际输出,自动更新权重参数,使其逐步符合预期。
这种能力的原理是基于梯度下降算法。我们知道,权重的更新实际上就是一次加减运算,这次训练偏离了多少,就根据这次的偏离,决定这次的权重需要增加还是减少,然后进行下一次训练。这个偏离了多少,就是实际值和预期值的一个差值,叫做损失。但我们知道差值还不够,知道差值只是知道偏离了多少,我们还要根据这个偏离的量,知道权重是应该增加还是减少。
我们知道,我们计算损失是根据相关公式的,例如线性模型中是用高度差,也就是实际 y 和预期 y 的差值(当然,实际还会进行一些变换)。既然知道公式,我们就可以知道它的变化规律,那就是通过导数。我们想知道损失和权重的变化关系,那就求损失对权重的导数,如果导数为正,说明权重越大,损失越大,那就需要减少权重;导数为负,说明权重越大,损失越小,那就需要增加权重。知道需要增加还是减少权重了,但是要增加多少,减少多少呢?那就需要一个固定的步长来决定,规定权重每次更新多少,这个步长也称学习率。步长没有最大最小之分,只有合不合适,学习率过大会导致无法收敛,也就是损失降不下来,模型找不到合适的参数组合;学习率过小会则会导致训练耗时增加。
因此,我们的权重更新公式就出来了:w新 = w旧 - a * 损失函数对权重的导数。 损失函数对权重的导数,我们称之为梯度,这条公式也叫做梯度下降算法。需要说明的是,神经网络中的函数基本都是多元函数,所以梯度这个导数,其实是偏导数。此外,梯度通常指向的是损失函数上升最快的方向,但是8我们在实际是希望损失最小,这也是为什么要减去a * 损失函数对权重的导数,因为我们要朝着损失下降最快的方向进行。
但由于神经网络并非是一个线性的函数,因此可能会有多个“最低点”,称之为局部最低点(最优解),当有一个最低点,没有其他最低点的值比它还小了,这个最低点成为全局最低点(最优解)。
在实际的神经网络中,网络的层数不只有一层,神经元也不只有一个,这意味着我,神经网络会有非常多的连接,也就是有非常多的权重参数需要计算梯度。这会导致一个问题,那就是计算量。我们知道梯度是损失函数对权重的导数,而损失函数是在模型最终输出阶段计算的。也就是说,如果我们有一个 10 层的神经网络,如果我们要计算第一层的梯度,那么我们就要顺着连接链路,一直嵌套计算导数,直到求导到末尾的损失函数上。不仅如此,每一个权重参数的梯度计算时,都需要向前进行一轮求导,在向前求导过程中,中间会有很多导数是已经被重复计算很多次的,这对算力和内存都是浪费。
上面就是一个我们根据正常思维理解的神经网络梯度计算过程,也就是从输入一直向前计算梯度。为了解决这个向前计算梯度对算力和内存的浪费问题, 就引入另一种计算方式:反向传播。顾名思义,反向传播不从输入开始,而是从输出开始向后计算梯度。由于先计算好了后面的梯度,使得前面的梯度在计算导数时,可以直接使用后面计算好的梯度(导数),不需要每次再重新算到底,极大节省了算力和内存。
那么有反向传播,有没有正向传播呢?有的。我们知道,我们要计算出梯度的实际值,我们就要知道最终的损失函数的值,也就是本次训练的损失。要计算损失,就是要计算模型这次训练出的预测值,预测值就是需要输入数据,进行一轮神经网络的计算,得到最终预测值,这个流程就是正向传播。也就是说,正向传播是从输入出发,计算出预测值,然后根据预测值与真实值计算损失;反向传播是从损失出发,利用计算图逆向计算梯度,实现自动更新权重。
从我们上述可以看到,对于神经网络来说,计算梯度时,是一个节点一个节点计算的。并且由于上一个神经元的输出,是后面一个神经元的输入,所以实际上每个连接链路就是,这条链路的每个神经元的计算公式的多层嵌套,非常复杂。为了方便理解,也为了在实际开发运算程序时,能够根据每一个节点的神经元,构建这些复杂的函数,这里就引入一个概念:计算图。
计算图将一个复杂函数,拆分成多个简单的数学运算,并且以图连接的方式,构建出这个公式的运算流程。也就是说,不管神经网络的结构多么复杂, 层数多深,利用计算图都可以根据结构构建出复杂的函数。只要能构建出这些函数,就可以利用反向传播计算梯度,完成梯度下降。
另外,由于我们使用的是链式法则计算的梯度,会涉及到一个问题,当有多个绝对值小于 1 的导数的值相乘,梯度会越来越小,最后几乎为0,这种问题叫做梯度消失。
最后再理解一个概念,激活函数。简单来说,激活函数的作用是给神经网络添加非线性能力,来解决像分类、图片、视频这些非线性问题。如果没有激活函数,那么神经网络整体就等同于一个单层的线性变换,只能拟合线性数据,处理图像、文本、分类这类非线性场景。
当利用神经网络处理图片时,使用仅线性层构成的神经网络,会出现一个问题,那就是当原本空间上相邻的元素,被展平成线性后,就可能变得不相邻,也就是说,它失去了一部分空间信息。此外,图片基本上是由二维矩阵构成,图片像素点越多,二维矩阵越大,展平后输入的参数量就越大,参数量大就容易过拟合。
因此,这里引入另一个神经网络:卷积神经网络,来解决线性层神经网络的弊端。卷积神经网络引入了两个层,卷积层和池化层。卷积层是为了提取局部特征,卷积层有一个卷积核,图片的二维矩阵会按照卷积核大小,依次将对应位置的元素与卷积核窗口进行数乘运算(对应元素相乘再相加),然后叠加偏置量,得到一个值。最终,得到一个卷积运算后的结果,这个结果就是本次卷积层提取的特征。
对于图片来说,一整张图片在卷积层进行卷积运算时,均使用一个卷积核,卷积核通常是一组多维的权重参数,这种共用一个卷积核的方式叫做共享权重(权重共享)。权重共享的引入,使得处理图片的参数量大大减少。并且,由于卷积核计算是二维矩阵形态,不会强行拉成一维,所以不会破坏输入图片的空间结构,使得图片的空间信息得到保留,训练效果也得到提升。
此外,权重共享机制还有另一个好处,就是假如图片的目标物体进行了平移,例如原本在左上但移动到了右下,由于图片用的是同一个卷积核进行运算,使得它还是能够识别这个特征,不会因为位置变化就判断为不同的东西。这个称之为平移鲁棒性(不变性)。
池化层的作用是对卷积层输出的特征图做压缩,或者叫下采样,精简特征图。通常采用最大池化方法,取一个 2 x 2 的池化窗口,设置步长为 2,每次取窗口中的最大值作为输出,最终得到压缩后的特征图。此外,池化层还能强化平移鲁棒性,目标物体平移,但只要最大值没有太大变化,输出结果保持不变。
然而,无论是全连接神经网络,还是卷积神经网络,都有一个共同的局限性,那就是输入的数据彼此之间都是相互独立的,前后的数据会认为是没有关系的。在现实中,有很多数据类型是有前后联系的,例如语言、天气、股票等等。也就是说,不论是全连接神经网络还是卷积神经网络,若将序列类型的数据传入,就会丢失时序依赖关系,也就是丢失数据前后之间的联系。
循环神经网络的结构有所不同,每一个神经元除了需要输入数据,还需要输入上一个神经元的计算结果。计算时,当前神经元接收上一个神经元的计算结果,以及当前的输入进行计算,然后将结果传递到下一个神经元,继续进行这样的循环。由于传递了计算结果,所以在神经元计算时,就能知道当前时序之前的信息,实现一个记忆的功能,简而言之就是过去记忆加上当前的输入,来更新记忆。而用于存储记忆的这个神经元输出结果层,称为隐藏层,或者叫隐藏状态。
在循环神经网络中,在时间,或者说时序维度,都共用一套权重矩阵,上一个隐藏层与当前隐藏层连接的权重,当前输入与当前隐藏层的权重,以及当前隐藏层的偏置项。不会出现每个循环神经元都有一套新的权重参数的情况,而是整条序列共用一套权重参数。这种权重共享的机制同样也减少了计算量。
同样的,如果时序数据很长,在梯度下降时,链式法则如果连续不断相乘绝对值小于 1 的数值,会导致梯度消失问题,体现出来的效果就是模型无法学习到长距离位置的关联,只能捕捉到短时的时序之间的关联。为了解决这个问题,循环神经网络引入了门控机制。
比较熟知的是LSTM和GRU,LSTM全程长短期记忆网络,它是循环神经网络的一个变体,其中引入三个关键的门控:遗忘门、输入门、输出门。遗忘门决定筛选并丢弃无用的长期记忆,保留有用旧记忆;输入门决定筛选有效新信息,写入神经元状态;输出门决定根据当前神经元状态,筛选输出当前时刻的隐藏特征。所谓的神经元状态,是LSTM能够解决梯度消失的关键,它的一个横跨所有时序的数据通道,在这个通道间传输记忆时,只会做小幅度增减,而不会整体大幅度变化,这使得记忆的传输不会出现损耗,解决了梯度消失的问题。
GRU 全程是门控循环单元,也是循环神经网络的变体。不过其门控机制比 LSTM 更精简,其引入两个关键的门:更新门、重置门。更新门是 LSTM 中输入门和遗忘门的合并,决定保留多少旧记忆,写入多少新信息;重置门决定多大程度忽略过去的记忆。
那所谓的“门”决定记忆如何处理的方式,本质上是通过 sigmoid 激活函数,若趋近与 0,信息大幅丢弃;趋近于 1 信息完整保留。门控就是使用 0~1 的权重系数对记忆信息做筛选。