深度学习与神经网络入门

前言

人工智能(AI)与机器学习(ML)与深度学习(DL)的关系:

DL包含于ML,ML包含于AI。

即深度学习是机器学习一部分,机器学习又是人工智能的一个分支。

那么深度学习到底有什么用呢?

深度学习要解决的问题

先来介绍一下机器学习的基本流程:

1、数据获取
2、特征工程

数据特征决定了模型的上限
预处理和特征提取是最核心的
算法与参数选择决定了如何逼近这个上限

3、建立模型
4、评估与应用

所有的机器学习方法基本都会有上面这个流程,深度学习也是一样。

对于所有的机器学习任务来说,最为困难也是最为核心的地方就在于第二步特征工程的处理上(不够智能,需要人工进行特征提取),比如选取哪些属性作为特征?又如何提取特征?等等,都是非常棘手的问题,而深度学习的出现解决了这个难题。

因为传统机器学习方法是无法实现自动进行特征提取的,而深度学习则不同,它可以使用神经网络(可以看作是一个黑匣子)自动的对输入的数据作特征选择与提取,并且将这些特征转换成计算机所能认识的抽象表示,类似于一个“学习”的过程。

这就是深度学习的核心。

因此,神经网络这个东西不应该被称之为一种算法,应该当成是一种特征提取的方法。

深度学习应用领域

略。

计算机视觉任务

计算机视觉任务是深度学习主要的应用场景。

如图像分类任务:

下图是一只猫,我们想让计算机从一系列标签中(狗、猫、汽车、飞机…)识别出猫来:
在这里插入图片描述

如何实现?

在这之前我们要清楚我们所输入的图片数据究竟是什么样子:

在这里插入图片描述

图像在计算机当中其实是被当作一个三维数组或者说三维矩阵中所存储的一系列数值。

像素值从0到255的含义:像素值越低就越暗,越高就越亮。

上图右侧中的每个像素点都是一个值,而每个值都代表了当前像素的亮暗程度。

上图中这只猫如何表示:一张图片有长和宽,然后还需要一个表示图片的颜色通道的值,三者合起来即我们上述说的三维矩阵。

在这里插入图片描述

假设上图为 jpg 类型图片,其颜色通道为RGB,也就是三颜色通道,那么假设这张猫的图片长为300,宽为100,颜色通道为3,那么表示这只猫的式子就是:300*100*3。

计算机视觉面临的挑战:

在这里插入图片描述

在这里插入图片描述

上述提到的问题都会影响到我们视觉检测的准确性。

视觉任务中遇到的问题

深度学习与机器学习的一般流程都是一样的:

1、收集数据并给定标签
2、训练一个分类器
3、测试、评估

唯一不同的地方就是深度学习是使用神经网络这种技术来做的而传统机器学习不是罢了。

当我们使用传统算法来做一个计算机视觉任务时会遇到哪些问题?

比如使用 K 近邻算法判断下图中的绿色圆是属于哪一类图形的任务:

在这里插入图片描述

这个算法的大致思路就是判断一下该绿色圆圈周围哪一种图形的数量多,那么该算法就认为该绿色圆圈是哪一类图形。

有点类似于近朱者赤近墨者黑的感觉。

比如上图中黑色圆圈范围内,有两个三角形和一个正方形,那么机器就会认为绿色圆圈会是三角形。

计算步骤如下:

在这里插入图片描述

K邻近算法的分析:

在这里插入图片描述

那么使用该算法来实现我们的图像分类任务可不可以呢?来验证一下:

这些数据是从CIFAR-10数据集中取到的数据:

在这里插入图片描述

有了数据之后,我们按照K邻近算法的思想来实现一下:

在这里插入图片描述

我们用测试图片中的像素值减去训练图片中对应位置的像素值以表示两张图片的距离,拿到差值后把所有的像素位置的差值加起来,通过这个和来进行图像类型判断。

测试结果如下:

在这里插入图片描述

那么问题究竟出在哪里?其实就是背景主导的问题(仔细观察上图可以发现背景色近似的图片都被分到一类了,而不是图片主体是一类的图片被分到一类):

在这里插入图片描述

不难发现,K邻近算法并不能进行“学习”,它不知道哪些是背景哪些是主体,所以由此引出深度学习中最核心的一个点,我们需要让神经网络去学习一下拿到一张图像之后要告诉我们哪些是重要的,哪些是我们要的主体(前景),哪些是我们要过滤掉的东西(后景或者叫背景)。

我们需要神经网络像人类一样去识别观察出来哪些是我们要的,哪些是我们不需要的。

那么接下来我们就来看一下在神经网络当中,它是如何一步步进行“学习”识别观察出我们所需要的东西的。

神经网络基础

首先神经网络复杂是毋庸置疑的,我们将其分为几个模块来逐个进行分析。

线性函数(或者叫得分函数)

在这里插入图片描述

假如上图中这只大小为 32*32*3 像素的猫的图片,在一个线性函数 f 中作为输入变量 x ,最后我们通过计算可以得到其属于某一类别的得分,比如说它的类别是狗的得分为-3,为猫的类别得分为+30,也就是通过计算我们能知道这张图片更有可能属于哪一类别。

那么怎么样得到得分值呢?很明显的是,这图片是由一个个像素点组合而成的(32*32*3共3072个像素点),那么每个像素点都在影响这张图的分类。显而易见,猫眼睛上的像素点和背景图上的像素点显然会对结果造成不同程度的影响(有些像素点对这张图是一只猫的结果起促进作用,而有一些则起抑制作用),而这些影响都会影响系统对类别的判断。

因此我们可以知道,每个像素点对于当前这张图的测试结果的重要程度是不一样的,此时我们就需要一个权重参数 W 来在函数中进行描述这种重要程度。

总结一下,有了数据之后(我们知道这些数据是由一堆像素点组成的,或者说是一堆特征),每个特征都会对应一个不同的权重参数(如果这张图的每个像素点都是不同的特征,那么这张图就需要3072个权重参数!),这样我们就能够拿到这张图的一个得分值。

在这里插入图片描述

上图显而易见的给出了一个较为简单的得分函数 f(x,W) 的公式表示:f(x,W) = Wx;

注意这是矩阵运算嗷…

x 很明显就是 3072,即我们输入数据(也就是这张猫图)的像素点个数。

而 W 则是我们的权重参数,它象征着数据对于某一类别的权重大小,比如为猫的数据权重假设为 W1,而为狗的数据权重假设为 W2…以此类推。

b 这个参数我们之前没有提过,它叫做偏置项(也可以叫偏置参数),是用来对我们的数学模型进行微调的。

权重参数对结果起决定性作用,而偏置项则起一个微调作用。

多组权重参数构成了决策边界,也就是说权重参数是控制着整个决策边界的走势的,而偏置参数则是进行微调:

在这里插入图片描述

公式含义如下:

在这里插入图片描述

我们要做的是多少类别的分类,则用到的就是几组,若为5种类别的分类,则上式中的 10 就要变成 5 了捏。

一个简单的例子:

在这里插入图片描述

这里将这张图的像素点浅浅划分为了四个像素点以进行示例,然后进行了一波计算,可以结合上上张图的内容进行理解(注意这里只是简单的将其当成一个四个像素点的图来方便理解,并不涉及颜色通道,涉及颜色通道就变成三维的了)。

然后这个例子也就是简单的进行了三分类的逻辑实现,如上图所示,分别是猫、狗和船。

那么有一个问题是:这个权重参数的矩阵,是从哪里来的呢?

这个矩阵实际上是不断优化而来的,一开始我们可以随机的进行一个 3x4 大小的矩阵的构建,这个矩阵中存储的都是一些随机值,比如上图的权重参数矩阵就是一个随机值,显然得到的结果并不好,这张图是狗的得分值要远比是猫的更大,也就是说被错误的判断成狗了。
这很明显是我们的权重参数矩阵有问题,它不够合理。
也就是说,神经网络其实在整个生命周期当中它只做了一件事情,就是不停的寻找什么样的权重参数 W 能更适合于我们的数据去做当前这个任务然后进行相应的参数的优化。

损失函数

从上一小节我们知道了学习的结果有可能好有可能不好,那我们怎么知道好有多好, 不好有多不好呢?

在这里插入图片描述

也就是说我们缺乏一种评价机制来判断机器学习后的效果,此时我们就需要损失函数的存在。

其实神经网络是既可以做分类,也可以做回归的,能做的事情非常多,唯一的区别在于我们的损失函数究竟是如何定义的,而网络结构是不会去改变的。
做不同的任务,说白了就是损失函数不同而已。

举两个例子,两个都是用的比较多的损失函数。

在这里插入图片描述

上面右侧是通过对左侧权重参数的计算得到的损失函数的值,显而易见,如果处理的结果好说明没有损失,处理的不好说明有损失。

不难看出,对于第一张猫的图片,是有损失的,因为其为2.9;第二张图是没损失的,可以正确判断出是车的类型;第三张图可就损失大发了,高达-3.1。

总结一下,损失函数的作用就是衡量当前这组权重参数在训练完之后的结果的效果是好还是不好。

正则化惩罚项

有了损失函数之后还有一个问题,有时候两个模型得到的得分值是一样的,那能够说明这两个模型一样优秀吗?

在这里插入图片描述

可以看到模型 A 虽然与模型 B 的结果是一样的,但很明显模型 A 只考虑了局部因素,模型 B 考虑的更加全面。

更专业的说,模型 A 产生了过拟合的现象。

因此我们在构建损失函数的过程当中还需要加上一项:正则化惩罚项。

在这里插入图片描述

不难看出,正则化惩罚项就是所有权重参数平方的和再乘上一个 λ 参数,这个 λ 参数越大,表示我们希望这个损失函数越不过拟合。

前向传播整体流程

上面说的基本上就有了深度学习中所谓前向传播的概念:

在这里插入图片描述

解释一下:

有了输入数据 x 和权重参数 W,我们就能够通过函数模型 f = Wx 计算得到得分值,然后选择一个损失函数,即hinge loss,也就是上图中的 Li 函数,再加上一个正则化惩罚项,合并起来计算后就能够得到一个损失值 L 。

如何更新模型的问题我们留在后文再说,这里只是先小结一下我们前文所说的事情,同时引出一个问题:

到目前位置我们得到的只是一个损失值 L ,那么如何将我们的损失值或者说是得分值转换为一个概率值呢?
毕竟通过概率值来判断终归是要比一个得分值要舒服吧。

在这里插入图片描述

答案是使用 sigmoid 函数来完成这个转换,该函数在逻辑回归当中是可以把任意一个输入的 x 都能压缩为一个 0 到 1 的值,也就是上图的样子,这不就是我们需要的概率吗?

关于 sigmoid 函数可以看后文的补充知识。

如何理解呢?以Softmax分类器这类学习任务中的处理过程为例介绍一下:

在这里插入图片描述

先不看数学公式,数学公式看着真是让人头痛。

先从概念上来理解一下这个流程:

在这里插入图片描述

也就是从上面这幅图(依然是之前举的对一张猫的图片分类的例子),从我们一开始得到的得分值经过 exp 和 normalize 两步之后就可以得到我们所需要的概率形式的值了。

第一步,通过exp(即e的x次幂,可以画个图自己看一下,输入的x越大,那么映射出来的值就越大)函数将各个类别的得分值给放大,这样就可以让结果看起来更加的明显一些。

第二步,现在我们得到的依然是得分值,如何转换这些值成为概率值呢?答案是通过normalize,即归一化操作即可。以对cat的得分值进行归一化为例:其归一化之后的值为:24.5/(24.5+164+0.18) = 0.13,这就实现了从得分值到概率值的转换。

有了概率值之后,如何进行损失的计算呢?

这里使用了一个 log 函数来进行损失值的计算,注意一点,我们只关注当前输入中属于正确类别的概率值,如上图就是概率值 0.13 ,因为我们输入的图片就是一只猫,我们肯定希望它的概率能够和 1 相近,而 log 函数正好能够帮我们达到这个转换的效果:

在这里插入图片描述

可以看见概率 x 越小的值,其对应的输出也就是我们需要的损失值就越大,因此通过对数函数我们可以轻松的得到由概率值转换出来的损失值。

把我们上述说的逻辑流程换成对应的数学公式(这里是Softmax分类器当中的做法示例),就如下面所示了:

在这里插入图片描述

可以看见归一化之后能拿到概率值 P,然后通过 -log P 我们就可以拿到对应的损失值 Li。

为什么要在对数函数前加个负号:因为 log 函数如上上张图所示其得到的损失值是个负的,因此我们再加一个负号让其输出为正即可。

以后在使用一些深度学习框架比如PyTorch的时候,我们都是需要自己写一个损失函数的,通常情况下,我们都是用这个对数损失函数来完成的。

补充:sigmoid 函数

Sigmoid函数,也被称为逻辑函数(Logistic Function)或S型函数(S-shaped Function),是一种在机器学习和深度学习中广泛使用的数学函数。它的主要特点是将任何实数映射到0和1之间,因此常被用作将线性输出转换为概率输出的手段。

Sigmoid函数的数学表达式为:

在这里插入图片描述
注意:exp的意思是e的x次幂的意思。

其中,( x ) 是输入,( sigmoid(x) ) 是输出。

Sigmoid函数的特性包括:

压缩性:不论输入值的大小,输出值始终被压缩在0和1之间。这使得它非常适合用于将输出解释为概率。

单调性:函数在整个实数范围内是单调递增的。这意味着随着输入值的增大,输出值也会增大,但增长速度逐渐减缓。

可微性:Sigmoid函数是处处可微的,这在进行梯度下降等优化算法时非常重要,因为需要计算损失函数关于模型参数的导数。

非零中心:Sigmoid函数的输出始终为正,这意味着它的输出不是以零为中心的。这可能导致在反向传播时梯度更新效率降低,特别是在深度神经网络中。因此,有时使用其他激活函数(如ReLU或tanh)作为替代。

Sigmoid函数常用于二元分类问题中,作为输出层的激活函数,将模型的线性输出转换为概率值。然而,由于其上述提到的非零中心特性,在构建多层神经网络时,通常不会选择Sigmoid作为隐藏层的激活函数。

小结一下

在这里插入图片描述
综上所述,基本整个神经网络的流程就走完了。

虽然上面是以分类任务来举例的,但其实回归任务也是基本类似的,回归任务最终是要预测一个值,那我们就可以当作回归任务是由得分值去进行一个损失计算就可以了,而分类则是由概率值去进行一个损失计算。

上面所说的从有输入数据和权值参数到最终损失值的计算完毕的这一套流程被称为神经网络中的前向传播,神经网络的执行流程被分为两大模块,一个叫前向传播,一个叫反向传播,前向传播已经讲完了,那么反向传播是什么意思呢?

按照我们一开始讲的,神经网络其实主要任务就是不断的更新权值参数 W 以期获得一个最优参数组合。假如我们前向传播中最后获得的 LOSS 值非常的大(效果不好),那么我们要如何进行权值参数 W 的更新以让 LOSS 值下降呢?

这就是一种优化。

因此所谓的反向传播要解决的问题就是使用梯度下降的策略来进行权值参数 W 的更新以减少 LOSS 的值。

反向传播计算方法

先说明,学习反向传播的时候要先明白梯度下降算法,如果不知道什么是梯度下降算法可以看本节下面的补充小节。

首先要明确的是,当我们拿到数据集之后,需要经过一个得分函数的变换,但是在百分之九十九的情况下并不会像上面我们所说的例子一样只做单次的变换,而是会做多次的变换。

比如上面的例子中我们只用了一组权重参数 W 做变换,但实际任务中我们基本上会有多组权重参数 Wn ,然后像筛子一样不断的重复筛取我们所输入的数据 x 。

比如此时输入数据为 x,而我们有三组权重参数 W1、W2、W3,那么 x 就要先经过 W1,得到一个值 xW1;
然后经过 W2 成为 (xW1)W2;
最后经过 W3 成为 [(xW1)W2 ]W3。
最后的 [(xW1)W2 ]W3 这个值就是初始数据经过三组权重参数变换后得到的得分值。

看一个反向传播的例子:

在这里插入图片描述

此时如果我们想要 f 的值减小,我们需要改变的是什么?

很明显就是改变 x、y、z的值嘛,因为 f 就和这三个值有关,这和我们之前说的损失函数的那一套操作是一样的吧:指定一个损失函数希望它的值越小越好,然后去调节一个权重参数 W 就可以让损失函数的值越来越小,是上图中的例子一样的吧?

那么我们这个例子应该怎么做才能让函数 f 的值变小呢?

答案就是对这三个值求偏导(梯度下降算法中的概念),比如求 f 对 z 的偏导,其含义就是 z 对最终的结果也就是 f 的变化做多大贡献。

因为 x、y、z 都对结果 f 有影响,因此需要分别求偏导。

那么对 x 和 y 如何求偏导呢?

我们可以设 q = x + y,那么 f 就等于 q*z;
此时对 x 求偏导就等于 f 对 q 求偏导乘以 q 对 x 求偏导的值;
同理对 y 求偏导就等于 f 对 q 求偏导乘以 q 对 y 求偏导的值。

在这里插入图片描述

也就是说在求梯度的过程当中,我们是逐层来进行计算的,比如上面提到的 [(xW1)W2 ]W3 = f 的例子,对于这个例子如何进行反向传播?

当然是从右往左一个一个来传播啦:
先传到权重参数 W3 中,查看 W3 对 f 做了多大贡献;
然后再传到 W2 ,查看 W2 对 W3 以及 f 做了多大贡献;
最后传到 W1 ,查看 W1 对式子右侧所有的内容做了多大贡献。

因此在神经网络当中,反向传播并非是像梯度下降当中那样直接计算出来的,而是有层次有顺序的从后往前逐层的进行计算。

这种方法有有个名字,叫链式法则(即梯度是一步一步进行传播的):

在这里插入图片描述

还有一点概念:

在这里插入图片描述

这种所谓的门单元,我们就当成是一种操作就可以了。

补充:梯度下降算法

一个简单的例子

先来看这样一个问题,现在需要用一条直线来回归拟合下图中的三个点,直线方程为 y = wx + b:

在这里插入图片描述

假设斜率 w 已知,现在想要找到一个最好的截距 b ,一条直线好与不好我们可以使用三个点到直线的长度来衡量(因此肯定是总长度越小截距 b 越好),然后把这个距离误差写成一个最小二乘的方式(ei 就是每一个点与 y 函数直线的距离):

在这里插入图片描述

这个函数也就是我们之前说的损失函数。

我们的目标就是要找到一个 b ,同时让损失函数最小即可(损失函数最小说明这个 b 是最好的截距)。

我们将直线方程带进去化简得:

在这里插入图片描述

可以发现损失函数 L 是关于 b 的一个二次函数,而其它系数都是可以直接计算出来的常数。

假设二次函数如下,根据初中的知识我们可以找到那个让损失函数最小的 b 值就在下图中的最优值所指的位置:

在这里插入图片描述

现在我们换一种求解思路,随便给定一个 b 的值,能不能通过迭代优化的方式找到最好的值呢?

我们可以求出当前点的斜率,再乘以一个常数 epsilon。箭头的方向就是斜率的负方向,然后让 b 更新为 b 减去 epsilon 乘以斜率,这样就得到了一个新的值,这个新的值会比初始的损失函数获得的值更小。

如此往复进行迭代,最后能够到达最优解的位置:

在这里插入图片描述

此时斜率为 0 ,b 就不会再被更新了,我们就找到了那个最好的值,优化过程结束。

这就是梯度下降算法,接下来我们以一个更加一般的形式来表述。

梯度下降算法的一般形式

数据点不止是三个而是很多点,函数是任意一个非线性函数 y = f(x,θ) ,其中要优化的参数是 θ ,第 i 个样本点的损失函数可以写成下图中右侧这样的形式:

在这里插入图片描述

我们首先可以求出 L 关于 θ 的偏导,也就是梯度值:

在这里插入图片描述

然后做一个平均,为了更方便我们使用 g 来表示这个长长的式子:

在这里插入图片描述

θ 沿着梯度的负方向移动,就可以让损失函数更小了:

在这里插入图片描述

其中的常数 epsilon 也被称之为学习率,是人为设定的一个值,用来控制梯度下降的步长。

整个梯度下降的核心就是下图中红框的两步了:

在这里插入图片描述

这就是梯度下降算法的一般形式表述。

神经网络整体架构

在这里插入图片描述

上图形象的展示了神经网络的结构和我们生物学中的神经细胞是很类似的。

在这里插入图片描述

上面这张图非常重要,基本看明白了这张图,那么神经网络这个东西基本就明白了百分之八十以上。

我们先来看神经网络是如何工作的,从上图容易发现,神经网络有几大模块组成:

1、层次结构:

从上图可以看出一共有输入层(input layer)、隐藏层(hidden layer)以及输出层(output layer),这就印证了我们之前说的,输入数据 x 会经过多层的变换最终拿到最后的输出。

2、神经元:

在深度学习中,神经元是一个基本的计算单元,它模拟了生物神经网络中神经元的功能和工作方式。深度学习的神经元模型通常由以下部分组成:
在这里插入图片描述
通过将多个神经元组合在一起,可以形成更复杂的神经网络结构,如全连接层、卷积层、池化层等。这些网络结构能够学习从输入数据中提取有用的特征表示,并执行各种复杂的任务。

3、全连接:

全连接层(Fully Connected Layer),也称为密集连接层或全连接神经网络层,是神经网络的一种基本组成部分。其主要作用是将输入的所有神经元与输出的所有神经元相互连接,每个输入神经元与每个输出神经元都存在连接,因此称为“全连接”。全连接层通常出现在神经网络的前馈(Feedforward)部分,用于学习输入数据的表示。
比如上图中,每一列的三个白色圆圈都会与下一层的所有白色圆圈相连接,故称全连接。

4、非线性:

非线性的概念至关重要,它是指模型能够学习和表示输入和输出之间复杂、非直线性的关系。在神经网络的上下文中,非线性主要通过激活函数来实现,这些函数被应用于神经元的输出,使得整个网络能够逼近复杂的函数。
如果神经网络仅由线性层(即没有激活函数的层)组成,那么整个网络的输出将仅仅是输入的线性组合。这意味着无论网络有多少层,其输出都可以被简化为一个单一的线性函数,这极大地限制了网络的学习能力。
非线性激活函数(如ReLU、Sigmoid、Tanh等)的引入打破了这种局限性。它们使得神经元的输出不再是输入的简单线性组合,而是可以根据输入的不同而有所变化,从而允许网络学习并表示复杂的、非线性的模式。

那么各层之间是如何进行转换的呢?这就要提到我们之前所说的权重参数矩阵 W 了。

在各层之间进行转换的时候都需要权重参数 W 的参与。

以上上张图为例,输入层有三个特征样本,其大小为 1x3 ,而我们经过转换之后到达隐藏层 1 时特征样本被网络扩展为 4 个了,即大小变成了 1x4 大小,如何完成 1x3 到 1x4 大小的转换?

那肯定就是在两层之间建立一个 [3,4] 大小的权重参数矩阵啦,这样就可以完成转换了(就跟做矩阵运算一样)。

转换时还需要注意非线性变换的存在,正如上文提到的非线性的概念,如果神经网络仅有线性层组成(即没有激活函数的层),那么整个网络的输出将仅仅是输入的线性组合(这极大地限制了网络的学习能力)。因此为了避免这种情况,在权重参数矩阵完成转换之后还需要进行一次非线性变换才可以继续进入下一层的变换。

那么非线性变换如何实现?其实就是找一个非线性的函数,比如之前提到的 sigmoid 函数,max 函数等,只要是非线性的函数就可以。

逻辑简单理解就是这样,转成数学公式的话可以以下图为例:

在这里插入图片描述

层数堆叠之后的情况分析如下:

在这里插入图片描述

在深度学习中,神经元个数的多少并不是简单地越多越好。实际上,神经元的数量需要根据具体任务、数据集和网络结构来合理设置。

首先,神经元个数的增加确实可以提高网络的表示能力,使其能够学习更复杂的函数和模式。更多的神经元意味着网络可以捕获更多的特征和信息,这有助于提升模型的性能。

然而,神经元个数过多也可能导致一些问题。一方面,过多的神经元会增加网络的复杂性和计算成本,使得训练和推理的速度变慢。另一方面,过多的神经元也可能导致过拟合问题,即模型在训练集上表现良好,但在测试集上性能下降,因为模型过于复杂而记住了训练数据的噪声和细节。

因此,在选择神经元个数时,需要综合考虑多个因素。对于不同的任务和数据集,可能需要尝试不同的神经元个数来找到最优的配置。同时,也可以采用一些正则化技术(如dropout、L1/L2正则化等)来防止过拟合,从而在一定程度上缓解神经元个数过多带来的问题。

总之,要辩证的看就完事儿了。

正则化与激活函数

正则化

在深度学习中,正则化惩罚项是一个重要的概念,它主要用于防止过拟合现象,提高模型的泛化能力。

过拟合指的是模型在训练数据上表现优秀,但在新数据或测试数据上性能下降的情况。为了防止过拟合,我们需要在损失函数中添加正则化项,对模型的复杂度进行限制。正则化项通常是对模型参数(如权重)的某种形式的惩罚,例如L1正则化或L2正则化。

L1正则化是对模型参数绝对值的和进行惩罚,这有助于使模型稀疏化,即一些参数会变为零,从而简化模型。
L2正则化则是对模型参数平方和进行惩罚,它有助于使参数值更接近于零,但通常不会使参数完全为零。

在添加正则化项后,模型的损失函数会变为原始损失与正则化项之和。在训练过程中,模型会尝试同时最小化原始损失和正则化项,从而平衡拟合训练数据和防止过拟合的需求。

正则化惩罚项的使用需要根据具体任务和数据集进行调整。如果正则化项权重过大,可能会导致模型欠拟合;如果权重过小,则可能无法有效防止过拟合。因此,通常需要通过交叉验证等方法来选择合适的正则化项权重。

在这里插入图片描述

从上图中可以发现,当常数 λ 为 0.001 时,也就是惩罚力度比较小的时候,在训练集上可以完美的避开所有红点,但是有没有可能有那么几个红点其实应该也是绿点但是被错误标记出去了呢?这说明过拟合现象有些严重了。

当逐渐增大 λ 的值可以发现,过拟合现象渐渐消失了,这就是正则化的作用以及效果。

同样对最终结果有影响的还有我们输入的参数,或者说神经元个数:

在这里插入图片描述

隐藏层神经元数量越多,对结果的影响越正向,但处理不当也会造成过拟合现象。

激活函数

在深度学习中,激活函数(Activation Function)是一个非常重要的概念,它决定了神经元如何响应其输入。激活函数的作用是将神经元的加权输入转换为输出,并引入非线性特性,使得神经网络能够学习和表示复杂的模式。

没有激活函数,神经网络的每一层都只是对输入数据进行线性变换,无论网络有多少层,输出都是输入的线性组合。这样的网络无法学习并逼近复杂的非线性函数,从而限制了其解决问题的能力。

激活函数通过在神经元中引入非线性元素,打破了这种线性限制。它们使得神经元的输出不再是输入的简单线性组合,而是可以根据输入的不同而有所变化。这样,神经网络就能够逼近任意复杂的函数,从而解决各种非线性问题。

在这里插入图片描述

常用的激活函数对比:

在这里插入图片描述

如上图所示,sigmoid 函数会造成 梯度消失 的情况,因为从它的函数图像上可以看到,当在函数左右两侧无限远处,对其求梯度也就是求偏导时会基本趋近于0,因为前向反向传播时遵循的是链式法则也就是说主要做的是乘法运算,那有 0 的出现就会导致算到最后梯度为 0 的情况,也就是梯度消失了(网络不进行更新也不进行传播了),基于这个原因 sigmoid 已经不怎么用了。

当前市面上使用最多的激活函数是 ReLu 函数,其不会有梯度消失问题,基本占据了百分之九十以上的市场,剩下百分之十中有些是 ReLu 的变体,有些则是一些其它的小众函数。

神经网络过拟合解决办法

数据预处理

深度学习中数据预处理是一个关键步骤,它指的是在进行深度学习模型训练之前,对原始数据进行清洗、转换和集成等一系列处理过程。数据预处理的目的是将原始数据转化为可用于建模和分析的合适形式,以提高模型的性能和准确性。

数据预处理包括多个方面,如数据读取和加载、数据清洗和去噪、数据归一化和缩放、数据变换和映射、数据增强和扩展、数据划分和验证,以及数据保存和加载等。具体的处理方法和技术有很多种,需要根据具体的问题和数据特征进行选取和应用。

数据清洗涉及去除重复数据、处理缺失值和异常值等,以确保数据的质量和完整性。数据归一化和缩放则是将数据调整到特定的范围或尺度,使得不同维度的数据具有相同的分布,有助于提高模型的训练效果。数据变换和映射可能包括特征提取、降维和变换,以减少数据的维度并提取有用的特征。数据增强则通过对数据进行旋转、裁剪、翻转、加噪声等操作,增加数据的数量和多样性,提高模型的泛化能力和鲁棒性。

此外,数据预处理还包括将数据划分为训练集、验证集和测试集,用于模型的训练、调优和评估。最后,预处理后的数据和模型可以保存到磁盘或云存储,以便后续的部署和应用。

在这里插入图片描述

参数初始化

深度学习中的参数初始化指的是在网络训练之前,对各个节点的权重和偏置进行初始设置的过程。这个过程对于网络能否训练出好的结果或者是以多快的速度收敛都至关重要。以下是一些常见的参数初始化方法:

随机初始化:这是深度学习中最常用的参数初始化方法之一。在随机初始化中,模型的参数通过从均匀或正态分布中随机采样来进行初始化。
预训练初始化:特别适用于深度神经网络。在预训练初始化中,模型首先在一个较小的数据集上进行训练,然后使用这些学到的参数作为初始参数进一步训练。然而,预训练初始化需要大量的计算资源和时间,并且可能无法适应新的任务。
Xavier/Glorot初始化:这是一种旨在解决梯度消失/爆炸问题的初始化方法。它将参数初始化为从均匀分布或正态分布中随机采样的值,其均值为0,方差为(1/(n_in + n_out)),其中n_in和n_out分别代表输入层和输出层的神经元数量。
标准初始化:权重参数初始化从区间均匀随机取值。即从(-1/√d,1/√d)均匀分布中生成当前神经元的权重,其中d为每个神经元的输入数量。
偏置初始化:通常偏置项初始化为0,或比较小的数,如0.01。

此外,还有一些其他的初始化方法,如正态分布初始化,它将权重初始化为来自正态(或高斯)分布的随机数。该分布通常以0为均值,其标准差(或方差)可以根据网络的特定需求进行调整。

请注意,不同的初始化方法适用于不同的网络结构和任务,因此在实际应用中需要根据具体情况进行选择。同时,初始化参数的选择也可能会影响到模型的收敛速度和训练效果,所以在进行深度学习模型训练时,应该仔细考虑参数初始化的策略。

在这里插入图片描述

上图中的随机值乘上 0.01 是为了不让网络当中不同的一个权重参数值浮动差异太大,希望尽可能稳定一点。

DROP-OUT正则化技术

深度学习中的Dropout是一种正则化技术,旨在减少神经网络训练过程中的过拟合问题。在训练过程中,Dropout按照一定的概率将神经网络单元暂时从网络中丢弃,这意味着在前向传播时,某些神经元的激活值会以一定的概率p停止工作。这种随机关闭神经元的方式可以明显减少特征检测器(隐层节点)间的相互作用,使模型不会过于依赖某些局部特征,从而提高网络的泛化能力。

Dropout的使用方式相对简单。在神经网络的某些层中,可以随机丢弃一定数量的神经元,使得每次训练时都会有不同的神经元被丢弃。这种随机性增加了模型的鲁棒性和泛化能力。在实现时,可以在代码中使用Dropout函数或者在模型中添加Dropout层来实现。

在测试时,由于不能随机丢弃神经元,所以需要采用一种策略来近似所有可能的精简网络的平均预测效果。通常的做法是在测试阶段将神经元的输出向量乘以1/(1-p),以补偿训练时由于Dropout导致的缩放效应。

在这里插入图片描述

上图形象的展示了如何叫随机的关闭一些神经元的行为。

总结

在这里插入图片描述

把本文说的东西串起来就是上面这一副图所要展示的内容啦,至此神经网络当中基本的内容都已经介绍完了,接下来我们将介绍深度学习中最经典的神经网络:卷积神经网络CNN。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/827038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openGauss学习笔记-268 openGauss性能调优-TPCC性能调优测试指导-网络配置-网卡多中断队列设置

文章目录 openGauss学习笔记-268 openGauss性能调优-TPCC性能调优测试指导-网络配置-网卡多中断队列设置268.1 中断调优268.2 网卡固件确认与更新 openGauss学习笔记-268 openGauss性能调优-TPCC性能调优测试指导-网络配置-网卡多中断队列设置 本章节主要介绍openGauss数据库内…

B203-若依框架应用

目录 简介版本RuoYi-fast项目准备新增模块/代码生成 简介 基于SpringBoot的权限管理系统,基于SpringBoot开发的轻量级Java快速开发框架 版本 前后端未分离单应用版本:RuoYi-fast,前后端未分离多模块版本:RuoYi 前后端分离单应用…

转行做银行测试,需要了解哪些?

在这个内卷严重的时代,银行的业务不断增加,随着软件信息化的要求越来越高,银行对软件测试人员也提出了非常高的要求。 银行的软件测试是针对银行的软件系统(如柜面系统、信贷系统)和银行专用设备(如ATM机、…

一键还原精灵 V12.1.405.701 装机版

网盘下载 个人版:不划分分区不修改分区表及MBR,安装非常安全,备份文件自动隐藏,不适用于WIN98系统。 装机版:需用PQMAGIC划分分区作隐藏的备份分区,安装过程中有一定的风险,安装后就非常安全。…

Linux(rpm,yum安装及管理程序)

目录 1.应用程序与系统命令 2.RPM 2.1rpm软件包管理工具 2.2 rpm命令的形式 2.3查询rpm软件包 ​2.4安装、升级、卸载rpm软件包 2.5维护数据库 3.yum 3.1 配置本地yum源仓库 3.2 yum常用操作命令 3.3 源码编译安装软件 1.应用程序与系统命令 应用程序与系统命令的关系 典…

银河麒麟安装OpenJDK

# 更新软件包列表(根据系统的实际情况,可能不需要这一步) sudo apt-get update # 安装OpenJDK sudo apt-get install openjdk-8-jdk

圣若热城堡、贝伦塔、热罗尼莫斯修道院 BIBM 2024在里斯本等你

会议之眼 快讯 2024年BIBM(IEEE International Conference on Bioinformatics and Biomedicine)即IEEE生物信息学与生物医学国际会议将于 2024年 12月3日-6日在葡萄牙里斯本举行!这个会议由IEEE(电气和电子工程师协会&#xff09…

linux将一个文件移动或复制到另一个目录下(超详细)

问题:需要在linux中将一个文件移动或复制到另一个目录下 下面提到的目录,可以直观理解为window中的文件夹 1、mv命令 mv是"move"的缩写,用于移动文件或目录到另一个位置。 将 文件 a.txt 移动到 目录home下 mv a.txt home将 目录…

Spark 中的分桶分化

Spark 中的分桶分化 Bucketing是 Spark 和 Hive 中用于优化任务性能的一种技术。在分桶桶(集群列)中确定数据分区并防止数据混洗。根据一个或多个分桶列的值,将数据分配给预定义数量的桶。 分桶有两个主要好处: 改进的查询性能&…

小游戏贪吃蛇的实现之C语言版

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:C语言 目录 游戏前期准备: 设置控制台相关的信息 GetStdHandle GetConsoleCursorInfo SetConsoleCursorInfo SetConsoleCu…

单机三pxc节点集群,+docker-haproxy2.0负载均衡实现

一.下载 https://www.haproxy.org/download/2.0/src/haproxy-2.0.5.tar.gz 或者在这里下载(下面需要的各个配置文件都有): https://download.csdn.net/download/cyw8998/89170129 二.编写文件,制作docker镜像 1.Dockerfile&a…

四款一键智能改写工具,为你轻松改出爆款文章

四款一键智能改写工具,为你轻松改出爆款文章!当今,虽然内容创作变得非常重要。但是,有时候创作灵感可能枯竭,或者需要对已有内容进行改写以增加独特性。这时候,一键智能改写工具成为了创作中的一种强大的辅…

LeetCode 课程表二(拓扑排序+Python)

使用桶排序算法中的kahn(卡恩)算法,也可以使用dfs。 这里使用卡恩算法,主要维护一个列表cnt,cnt【i】表示能到达节点i的边,比如说:a到c有一条边,b到c有一条边,那么cnt【…

信息流广告大行其是,微博回望“原生”的初心

摘要:有流量的地方,就当有原生信息流广告 信息流广告,自2006年Facebook推出后就迅速火遍全球数字营销界,被誉为实现了广告主、用户、媒体平台三赢。特别是随着OCPM/OCPX大放异彩,信息流广告几乎成为广告主的必选项&…

Print Conductor 文档批量打印工具 v9.0.2312

网盘下载 Print Conductor 是 Windows 上一款功能强大的文档批量打印工具,通过该软件可以快速的帮用户批量处理打印PDF文件、协议、文档、图纸、演示文稿、文本文件等,完美的支持PDF、DOC、JPG、PNG、SNP、PSD、MSG、WRI、WPS、RTF、TXT、XLS、PPT、PPS、…

在Linux系统中,禁止有线以太网使用NTP服务器进行时间校准的几种方法

目录标题 方法 1:修改NTP配置以禁止所有同步方法 2:通过网络配置禁用NTP同步方法 3:禁用NTP服务 在Linux系统中,如果想要禁止有线以太网使用NTP服务器进行时间校准,可以通过以下几种方法之一来实现: 方法 …

Java中的对象

什么是类和对象 在Java中类是物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些类进行单独思考,最后才是对某分类下的细节进行单独思考 面向对象适合处理复杂问题适合处理需要多人协作的问题 在Java中面向…

【状态机dp 动态规划】100290. 使矩阵满足条件的最少操作次数

本文涉及知识点 动态规划汇总 状态机dp LeetCode100290. 使矩阵满足条件的最少操作次数 给你一个大小为 m x n 的二维矩形 grid 。每次 操作 中,你可以将 任一 格子的值修改为 任意 非负整数。完成所有操作后,你需要确保每个格子 grid[i][j] 的值满足…

【Qt 学习笔记】Qt常用控件 | 显示类控件 | Label的使用及说明

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt常用控件 | 显示类控件 | Label的使用及说明 文章编号:Q…

Opencv Python图像处理笔记一:图像、窗口基本操作

文章目录 前言一、输入输出1.1 图片读取显示保存1.2 视频读取保存1.3 文件读取保存 二、GUI2.1 窗口2.2 轨迹条2.3 画图2.4 鼠标回调 三、图像入门操作3.1 颜色空间转化3.2 通道分离合并3.3 添加边框3.4 算数操作 四、二值化4.1 普通4.2 自适应4.3 Otsu 参考 前言 随着人工智能…