跟着问题学2——卷积神经网络

卷积神经网络

前面介绍了传统神经网络,接下来我们将正式进入介绍深度学习网络的环节。

1.1 全连接层

卷积神经网络,我们首先先来回顾一下全连接层(Fully connected layers, FC),原因有二:一是全连接层在之后的深度学习网络中都有用到,常常作为分类器来使用;二是说明一下深度学习网络为什么不全用全连接层,而是使用卷积层来代替。

前面介绍的全连接层,为了说明和计算的方便,每一层节点的个数只取了2或3,下图可以看到,当输入层和隐藏层节点数取到20时,就已经是密密麻麻的了。

20*20的输入层和隐藏层

从数学公式上来看:

式中,表示全连接层输出向量的第j个值,N表示全连接层上一层的输入长度,表示输入的第i个特征值,表示第j个输出值所对应的第i个输入特征值的权重,表示输出的第j个偏置值。

以简单的480*480分辨率的图片来说,全连接层输入特征值即为480*480=230400,再假设输出的特征值为100,那总参数量为230400*100=23040000,即参数量已达到了千万级。

全连接层相邻两层之间每个神经元都相互连接,导致参数量过大,不仅带来了网络模型容易过拟合的问题,也降低了网络训练速度。为了克服这些问题,研究人员提出了卷积神经网络。

1.2 卷积层

权值共享局部感受野

卷积神经网络 (Convolutional Neural Networks, CNN)的核心是提出了卷积层,卷积层具有权值共享局部感受野两大特性,共享了权重和偏置量,使得网络训练的参数量大大减少,降低了网络训练的复杂度。

以图中的输入图像输出特征图为例,对于传统神经网络,输出特征图的每个像素点(神经元)都是由输入图像的所有像素点乘上特定的权重值并求和得到的,也就意味着每个输出层的神经元所对应的权重数是输入图像的所有像素点(神经元)数,而输出层的神经元数也是庞大的,因此总的权重数是庞大的。

相对于“全连接”,卷积层使用了卷积核来减少参数。也就是把层与层之间密密麻麻的权重,抽象成大小远小于输入图像尺寸的卷积核(图中中间部分),卷积核上的每个像素点都代表权重值,这样对应于输出特征图的每一个像素点,只需要对覆盖区域进行卷积操作并产生对应输出,然后将卷积核按照一定的步长在输入图像上移动,最后得到高层特征图。也就是说,整张输入图像是共享该卷积核的权重的,即一个卷积核遍历整个图片(后面我们将看到,一个图片可以使用多个卷积核)。相比于全连接,卷积层的神经元的参数是由卷积核的数量和大小决定的

所谓局部感受野,就是每个神经元都是利用卷积核感知的图像的局部区域(全连接层是感受的输入图像的全部),而该区域也就是该像素点的局部感受野。如图 2-8 所示,在 3×3 的输出特征图上的每个像素点都能映射到输入图像上 3×3 大小的局部感受野(若是传统神经网络,则输出特征图上的每个像素点都能映射到输入图像的所有像素点)。

记 X 为输入图像,Y 为输出特征图,那么卷积操作如下式所示:

(2-15)式中,W 表示卷积核的权重,b 表示卷积偏置量,二维图像卷积公式可以写为:

这里再强调一下所谓输出特征图的概念,深度学习的核心就是数据和模型,而模型的核心就是寻找好的方式来提取传递数据的特征。在普通卷积神经网络中,一个卷积核遍历输入图便是提取该输入图的某种特征,而一般深度学习网络也会设置不同的卷积核个数来提取不同的特征,这就是输出特征图。

在代码里的输出通道数就是卷积核的个数, 每一个卷积核提取了某种特征

nn.Conv2d(self, in_channels, out_channels, kernel_size, stride=1,
                 padding=0, dilation=1, groups=1,
                 bias=True, padding_mode='zeros')

这个函数的功能是对多个二维信号进行二维卷积,主要参数如下:

in_channels:输入通道数

out_channels:输出通道数,等价于卷积核个数

kernel_size:卷积核尺寸

stride:步长

padding:填充宽度,主要是为了调整输出的特征图大小,一般把 padding 设置合适的值后,保持输入和输出的图像尺寸不变。

dilation:空洞卷积大小,默认为 1,这时是标准卷积,常用于图像分割任务中,主要是为了提升感受野

groups:分组卷积设置,主要是为了模型的轻量化,如在 ShuffleNet、MobileNet、SqueezeNet 中用到

bias:偏置

多通道

另一个值得注意的点就是卷积核的维度,很多图示的时候,展示的卷积核是3*3*1,不过我们知道输入彩色图是RGB三通道的,而且中间层的输入通道数会更多,那么卷积核的“通道”是不是也应该是对应的呢?

以 input*channel 为 3,output_channel 为 1 ,卷积核大小为 3×3 的卷积核为例,即nn.Conv2d(3, 1, 3),通过conv_layer.weight.shape查看卷积核的 shape (1, 3, 3, 3),对应是(output_channel, input_channel, kernel_size, kernel_size)。所以第一个维度对应的是卷积核的个数每个卷积核都是`(3,3,3)`。虽然每个卷积核都是3 维的,执行的却是 2 维卷积。下面这个图展示了这个过程。

也就是每个卷积核在 input_channel 维度再划分,这里 input_channel 为 3,那么这时每个卷积核的 shape 是(3, 3)。3 个卷积核在输入图像的每个 channel 上卷积后得到 3 个数,把这 3 个数相加,再加上 bias,得到最后的一个输出。

另外从下图中可以看出,不同通道的卷积核参数是不一样的,因此一个卷积层的参数计算应为:输入通道数*k*k*输出通道数,其中k为卷积核的尺寸。

那么如果输入channel是64呢?通过`conv_layer.weight.shape`查看卷积核的 shape 是不是应该是`(1, 64, 3, 3)`,对应是`(output_channel, input_channel, kernel_size, kernel_size)`。

填充和步幅

填充(padding)是指在输入高和宽的两侧填充元素(通常是0元素),填充的核心目的是为了保证输出特征图尺寸和输入一致。图5.2里我们在原输入高和宽的两侧分别添加了值为0的元素,使得输入高和宽从3变成了5,并导致输出高和宽由2增加到4。

卷积核窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。我们将每次滑动的行数或列数称为步幅(stride)。控制步幅>1可以减小输出特征图的尺寸。

下图是高和宽上步幅分别为3和2的二维互相关运算

卷积运算之后输出特征图相比输入图像尺寸变小了,尺寸计算公式为(不考虑空洞卷积):

其中,输入图片大小是I*I,卷积核大小为k*k,步长stride为s,padding的像素数为p。

可以利用边沿填充 (Padding)使卷积运算前后的尺寸保持不变,Padding 中填充大小 p 的计算公式如下所示

式中,k 为卷积核大小。

1*1卷积层

最后我们讨论卷积核尺寸为(1*1)的多通道卷积层。我们通常称之为1*1卷积层,并将其中的卷积运算称为1*1卷积。

因为使用了最小窗口,1*1卷积失去了卷积层可以识别高和宽维度上相邻元素构成的模式的功能。实际上,1*1卷积的主要计算发生在通道维上。1*1卷积的主要作用是用来升维或降维。

下图展示了使用输入通道数为3、输出通道数为2的卷积核的互相关计算。

值得注意的是,输入和输出具有相同的高和宽。输出中的每个元素来自输入中在高和宽上相同位置的元素在不同通道之间的按权重累加。假设我们将通道维当作特征维,将高和宽维度上的元素当成数据样本,那么卷积层的作用与全连接层等价。

1.3 池化层

不同于一般的神经元连接方式以及卷积操作,池化层的连接不会引入新的参数。池化操作一般位于卷积操作之后,对卷积产生的多通道特征图进行降维操作

在卷积操作中,卷积核的滑动步长一般要小于卷积核的尺寸,导致相邻的两次卷积操作的卷积核覆盖区域在输入图像上有所重叠,使得产生的高层特征中存在信息冗余。而在池化操作中,池化区域之间一般是不存在重叠的,直接将该区域的多个特征映射为一个特征,具有防止过拟合的作用。

池化方式有多种,比如平均池化(Average pooling)和最大池化(Max pooling)。如图 2-9 所示,平均池化是在输入特征图的 2×2 区域内计算平均值作为输出特征;最大池化是在输入特征图的 2×2 区域内选择最大值作为输出特征。

在处理多通道输入数据时,池化层对每个输入通道分别池化,而不是像卷积层那样将各通道的输入按通道相加。这意味着池化层的输出通道数与输入通道数相等。

池化操作后图像维度计算公式:

 

其中,O是池化后输出维度,I是输入图片的维度,池化层大小为k*k,s是步长stride。

nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1,

return_indices=False, ceil_mode=False)

主要参数:

• kernel_size:池化核尺寸

• stride:步长

• padding :填充个数

• dilation:池化核间隔大小

• ceil_mode:尺寸向上取整

• return_indices:记录池化像素索引

    maxpool_layer = nn.MaxPool2d((2, 2), stride=(2, 2))   # input:(i, o, size) weights:(o, i , h, w)

    img_pool = maxpool_layer(img_tensor)

nn.AvgPool2d(kernel_size, stride=None, padding=0, ceil_mode=False, count_include_pad=True, divisor_override=None)

主要参数:

• kernel_size:池化核尺寸

• stride:步长

• padding :填充个数

• ceil_mode:尺寸向上取整

• count_include_pad:填充值用于计算

• divisor_override :除法因子

    avgpoollayer = nn.AvgPool2d((2, 2), stride=(2, 2))   # input:(i, o, size) weights:(o, i , h, w)

    img_pool = avgpoollayer(img_tensor)

1.4卷积神经网络中的全连接层

深度学习网络中经常用全连接层做最后的输出,这时,不同于卷积层和池化层是对输入图像上的局部感受野计算输出特征,全连接层输出的感受野是整张输入图像,而且需要将多维特征图展平为一维向量作为输入。

   在PyTorch中,全连接层通常由nn.Linear类实现。这个类接受两个主要参数:输入特征数量(或输入尺寸)和输出特征数量(或输出尺寸)。例如,如果我们想在一个全连接层中将10个特征的输入转化为5个特征的输出,可以如下定义:

import torch.nn as nn

fc = nn.Linear(10, 5)

这个全连接层将包含10*5=50个参数,即权重和偏差。权重参数用于描述输入特征和输出特征之间的关系,而偏差参数则描述了输出特征的初始偏移量。

1.5卷积神经网络结构

至此,我们已经搭建了卷积神经网络结构的骨架,下图为LENET的基本网络结构,后面我们会以此介绍卷积神经网络的初步应用。

1.6初始化

参数初始化的背景和意义

神经网络参数初始化是深度学习中的关键步骤之一。初始化方法都旨在为神经网络提供合适的初始权重和偏置,以促进网络的稳定训练和性能优化。选择合适的参数初始化方法取决于网络结构、激活函数的选择以及任务的特点。在实践中,常常根据网络的具体情况选择合适的初始化方法,甚至可以结合不同的初始化方法进行混合使用。初始化方法对网络有以下影响:

避免对称性问题:在神经网络中,对称性指的是具有相同初始值的神经元或参数之间的对称性。如果所有的权重都被初始化为相同的值,那么在前向传播中,所有的神经元将计算相同的线性变换,导致它们产生相同的输出。这将导致网络中的对称性问题,使得不同神经元无法独立地学习和表示不同的特征

保持梯度稳定性:在反向传播过程中,如果参数初始化不合适,梯度可能会出现梯度消失或梯度爆炸的问题。合适的参数初始化方法可以帮助保持梯度的稳定性,促进网络的训练和收敛。

信号传播的稳定性:参数初始化还可以影响信号在网络中的传播稳定性。每个神经元的输出会作为下一层神经元的输入,如果信号传播过程中的方差变化过大,可能会导致网络中的信号失真或放大,影响网络的性能。合适的参数初始化方法可以帮助平衡每一层的信号传播,确保合适的信息流动。

通过合理选择和设置参数初始化方法,可以帮助提高网络的训练效果和收敛速度,减少梯度相关的问题,并帮助网络更好地学习和表示输入数据的特征。因此,参数初始化在神经网络的训练和性能优化中起着重要的作用。

常用的参数初始化方法

在神经网络中,有几种常用的参数初始化方法,包括:

零初始化(Zero Initialization):将所有的权重和偏置初始化为零。这种方法简单直接,但在实践中这种方法很少使用,因为它会导致所有的神经元具有相同的更新,并且会带来梯度消失问题等等。

随机初始化(Random Initialization):将权重和偏置随机地初始化为较小的随机值。这可以打破对称性,并为神经元提供不同的起点,促进网络的多样性和学习能力。常见的随机初始化方法包括从均匀分布或高斯分布中随机采样。但是会带来训练不稳定、对称性和梯度消失或爆炸的问题。

Xavier初始化方法,它的设计思想是根据前一层和后一层的神经元数量来设置权重的初始值,以保持信号在前向传播过程中的适当范围;其核心思想是,保持输入信号和梯度的方差在不同层之间大致相等,避免在深层网络中产生梯度消失或梯度爆炸的问题。这种初始化方法有助于提供合适的梯度范围,促进网络的稳定训练和收敛。具体而言,对于具有线性激活函数(如sigmoid和tanh)的网络层,Xavier初始化将权重初始化为均匀分布或高斯分布,其方差取决于前一层神经元数量n和后一层神经元数量m。

对于均匀分布的Xavier初始化(均匀版)

从均匀分布中随机初始化权重矩阵W,范围为[-a, a],其中a = sqrt(6 / (n + m))。

对于高斯分布的Xavier初始化(高斯版)

从高斯分布中随机初始化权重矩阵W,均值为0,方差为variance,其中variance = 2 / (n + m)。

来看一个具有5层的神经网络的例子,以解释Xavier初始化是如何工作的。假设我们有一个具有以下结构的神经网络:输入层(100个神经元) - 隐藏层1(80个神经元) - 隐藏层2(60个神经元) - 隐藏层3(40个神经元) - 输出层(10个神经元)。现在,我们将使用Xavier初始化来初始化每一层的权重。

对于隐藏层1,我们需要计算它的权重初始范围。根据Xavier初始化的公式,我们需要知道前一层和后一层的神经元数量。在这种情况下,前一层是输入层,有100个神经元,后一层是隐藏层1本身,有80个神经元。根据公式,我们可以计算权重初始范围a:a = sqrt(6 / (100 + 80)) ≈ 0.136。现在,我们可以从均匀分布[-0.136, 0.136]中随机初始化隐藏层1的权重矩阵。

接下来,我们继续计算隐藏层2的权重初始范围。前一层是隐藏层1,有80个神经元,后一层是隐藏层2本身,有60个神经元。我们使用相同的公式来计算权重初始范围a:a = sqrt(6 / (80 + 60)) ≈ 0.153。然后,我们从均匀分布[-0.153, 0.153]中随机初始化隐藏层2的权重矩阵。

类似地,我们可以计算隐藏层3和输出层的权重初始范围,并进行相应的初始化。

通过这样的递归计算和初始化过程,Xavier初始化确保了每一层的权重都与前一层和后一层的神经元数量相关联。这有助于平衡信号和梯度的传播,避免梯度消失或梯度爆炸问题,从而提高神经网络的训练稳定性和收敛性能。

He初始化方法针对使用Rectified Linear Units (ReLU)激活函数的神经网络进行了优化,其核心思想是,根据每一层的激活函数的特性来设置权重的初始范围,以更好地平衡信号和梯度的传播。

He初始化使用了前一层神经元数量来计算权重的初始范围,以确保输入信号的方差与输出信号的方差保持一致。具体而言,对于具有n个前一层神经元的全连接层,He初始化使用以下公式来计算权重的初始范围:a = sqrt(2 / n)。在这个公式中,n是前一层神经元的数量。通过将这个数量代入公式,我们可以得到权重初始范围a。

在使用ReLU激活函数时,输入为负时输出为0,而输入为正时输出等于输入。这意味着在前向传播过程中,大约一半的神经元输出为0。考虑一层具有n个输入神经元的全连接层,如果权重的方差为1/n,那么通过该层的输出的方差为1/n * n/2 = 1/2(每个神经元权重独立同分布,所以为n/2)。因此,为了保持信号的方差在前向传播中的稳定性,我们设置权重的初始范围为sqrt(2/n),希望权重的初始范围能够使输出的方差保持在1。这样,每一层的输出都具有合适的范围,有助于提供良好的梯度传播和训练稳定性。

1.7 Dropout

全连接层的每一个节点都和上一层全部节点相连接,这样可以让每一个输出都综合考虑前面所有被提取到的特征,但是会使参数量增加产生大量计算,延缓网络的训练速度,同时也容易产生过拟合现象。通常我们可以通过加入 Dropout 的方式缓解过拟合问题,在每次前向传播的时候以一定的比例抑制部分神经元,之后在反向传播阶段只需要更新未被抑制的神经元参数即可。

深度学习模型常常使用丢弃法(dropout)[1] 来应对过拟合问题。丢弃法有一些不同的变体。本节中提到的丢弃法特指倒置丢弃法(inverted dropout)。

1.8 Batch normalization

为什么做标准化

具有统一规格的数据, 能让机器学习更容易学习到数据之中的规律。而在神经网络中的标准化的核心目的是为了让数据经过激活函数后不处于饱和阶段(不然相当于激活函数失效了,梯度也反向传播不过去)

  

在神经网络中, 数据分布对训练会产生影响。比如某个神经元 x 的值为1, 某个 Weights 的初始值为 0.1, 这样后一层神经元计算结果就是 Wx = 0.1; 又或者 x = 20, 这样 Wx 的结果就为 2。

现在还不能看出什么问题, 但是,当我们使用像tanh 的激励函数, Wx 的激活值就变成了 ~0.1 和 ~1, 接近于1的部已经处在了激励函数的饱和阶段, 也就是如果 x 无论再怎么扩大, tanh 激励函数输出值也还是接近1. 换句话说, 神经网络在初始阶段已经不对那些比较大的 x 特征范围 敏感了。 这样很糟糕, 想象我轻轻拍自己的感觉和重重打自己的感觉居然没什么差别, 这就证明我的感官系统失效了.

当然我们是可以用之前提到的对数据做 normalization 预处理, 使得输入的 x 变化范围不会太大, 让输入值经过激励函数的敏感部分。

但刚刚这个不敏感问题不仅仅发生在神经网络的输入层, 而且在隐藏层中也经常会发生。只是x换到了隐藏层当中, 我们能不能对隐藏层的输入结果进行像之前那样的normalization 处理呢? 答案是可以的, batch normalization正是处理这种情况.

BN 添加位置

Batch Normalization, 批标准化, 和普通的数据标准化类似, 是将分散的数据统一的一种做法, 也是优化神经网络的一种方法。Batch normalization 也可以被看做一个。在一层层的添加神经网络的时候, 我们先有数据X, 再添加全连接层, 全连接层的计算结果会经过激活函数成为下一层的输入, 接着重复之前的操作. Batch Normalization (BN) 就被添加在每一个全连接和激活函数之间.

BN 效果

之前说过, 计算结果在进入激活函数前的值很重要, 如果我们不单单看一个值, 我们可以说, 计算结果值的分布对于激活函数很重要. 对于数据值大多分布在这个区间的数据, 才能进行更有效的传递.

对比这两个在激活之前的值的分布,没有 normalize 的数据使用tanh 激活以后, 激活值大部分都分布到了饱和阶段, 也就是大部分的激活值不是-1, 就是1, 而 normalize 以后, 大部分的激活值在每个分布区间都还有存在. 再将这个激活后的分布传递到下一层神经网络进行后续计算, 每个区间都有分布的这一种对于神经网络就会更加有价值。

BN 算法

我们引入一些 batch normalization 的公式. 这三步就是我们在刚刚一直说的 normalization 工序, 但是公式的后面还有一个反向操作, 将 normalize 后的数据再扩展和平移. 这是为了让神经网络自己去学着使用和修改这个扩展参数 gamma, 和平移参数 β, 这样神经网络就能自己慢慢琢磨出前面的normalization 操作到底有没有起到优化的作用, 如果没有起到作用, 就使用gamma 和 belt 来抵消一些 normalization 的操作.

最后我们来看看一张神经网络训练到最后, 代表了每层输出值的结果的分布图. 这样我们就能一眼看出 Batch normalization 的功效啦. 让每一层的值在有效的范围内传递下去.

Batch Normalization VS Layer Normalization

batch normalization是对一批样本同一纬度特征做归一化。如下图我们想根据这个batch中的三种特征(身高、体重、年龄)数据进行预测性别,首先我们进行归一化处理,如果是Batch normalization操作则是对每一列特征进行归一化,如下图求一列身高的平均值。

BN特点:强行将数据转为均值为0,方差为1的正态分布,使得数据分布一致,并且避免梯度消失。而梯度变大意味着学习收敛速度快,能够提高训练速度。

而layer normalization是对单个样本的所有维度特征做归一化。如下表中,如果是Layer normalization则是对每一行(该条数据)的所有特征数据求均值。

Layer normalization更多的是用到自然语言处理上,比如著名的Transformer架构。Transformer为什么用Layer Normalization呢?

从操作上看:BN是对同一个batch内的所有数据的同一个特征数据进行操作;而LN是对同一个样本进行操作。

从特征维度上看:BN中,特征维度数=均值or方差的个数;LN中,一个batch中有batch_size个均值和方差

如在NLP中上图的C、N、H,W含义:

N:N句话,即batchsize;

C:一句话的长度,即seqlen;

H,W:词向量维度embedding dim。

BN不适合RNN、transformer等序列网络,不适合文本长度不定和batchsize较小的情况,适合于CV中的CNN等网络;

LN适合用于NLP中的RNNtransformer等网络,因为sequence的长度可能是不一致的

栗子:如果把一批文本组成一个batchBN就是对每句话的第一个词进行操作,BN针对每个位置进行缩放就不符合NLP的规律了。而LN则是对一句话的所有词进行操作。

1.9 网络模型验证与评价

训练误差和泛化误差

评价一个网络模型的好坏可以利用之前讲到的损失函数,损失值越小,则模型越好。不过,这里需要注意区分训练误差(training error)和泛化误差(generalization error),通俗来讲,前者指模型在训练数据集上表现出的误差,后者指模型在任意一个测试数据样本上表现出的误差的期望,并常常通过测试数据集上的误差来近似。

以高考为例来直观地解释训练误差和泛化误差这两个概念。训练误差可以认为是做往年高考试题(训练题)时的错误率,泛化误差则可以通过真正参加高考(测试题)时的答题错误率来近似。假设训练题和测试题都随机采样于一个未知的依照相同考纲的巨大试题库。如果让一名未学习中学知识的小学生去答题,那么测试题和训练题的答题错误率可能很相近。但如果换成一名反复练习训练题的高三备考生答题,即使在训练题上做到了错误率为0,也不代表真实的高考成绩会如此。

在机器学习里,我们通常假设训练数据集(训练题)和测试数据集(测试题)里的每一个样本都是从同一个概率分布中相互独立地生成的。基于该独立同分布假设,给定任意一个机器学习模型(含参数),它的训练误差的期望和泛化误差都是一样的。例如,如果我们将模型参数设成随机值(小学生),那么训练误差和泛化误差会非常相近。但我们从前面几节中已经了解到,模型的参数是通过在训练数据集上训练模型而学习出的,参数的选择依据了最小化训练误差(高三备考生)。所以,训练误差的期望小于或等于泛化误差。也就是说,一般情况下,由训练数据集学到的模型参数会使模型在训练数据集上的表现优于或等于在测试数据集上的表现。由于无法从训练误差估计泛化误差,一味地降低训练误差并不意味着泛化误差一定会降低。

机器学习模型应关注降低泛化误差。

模型选择

在机器学习中,通常需要评估若干候选模型的表现并从中选择模型。这一过程称为模型选择(model selection)。可供选择的候选模型可以是有着不同超参数的同类模型。以多层感知机为例,我们可以选择隐藏层的个数,以及每个隐藏层中隐藏单元个数和激活函数。为了得到有效的模型,我们通常要在模型选择上下一番功夫。下面,我们来描述模型选择中经常使用的验证数据集(validation data set)。

验证数据集

从严格意义上讲,测试集只能在所有超参数和模型参数选定后使用一次。不可以使用测试数据选择模型,如调参。由于无法从训练误差估计泛化误差,因此也不应只依赖训练数据选择模型。鉴于此,我们可以预留一部分在训练数据集和测试数据集以外的数据来进行模型选择。这部分数据被称为验证数据集,简称验证集(validation set)。例如,我们可以从给定的训练集中随机选取一小部分作为验证集,而将剩余部分作为真正的训练集。

然而在实际应用中,由于数据不容易获取,测试数据极少只使用一次就丢弃。因此,实践中验证数据集和测试数据集的界限可能比较模糊。从严格意义上讲,除非明确说明,否则本书中实验所使用的测试集应为验证集,实验报告的测试结果(如测试准确率)应为验证结果(如验证准确率)。

 K折交叉验证

由于验证数据集不参与模型训练,当训练数据不够用时,预留大量的验证数据显得太奢侈。一种改善的方法是K折交叉验证(K-fold cross-validation)。在K折交叉验证中,我们把原始训练数据集分割成个不重合的子数据集,然后我们做K次模型训练和验证。每一次,我们使用一个子数据集验证模型,并使用其他个子数据集来训练模型。在这次训练和验证中,每次用来验证模型的子数据集都不同。最后,我们对这K次训练误差和验证误差分别求平均。

欠拟合和过拟合

接下来,我们将探究模型训练中经常出现的两类典型问题:一类是模型无法得到较低的训练误差,我们将这一现象称作欠拟合(underfitting);另一类是模型的训练误差远小于它在测试数据集上的误差,我们称该现象为过拟合(overfitting)。在实践中,我们要尽可能同时应对欠拟合和过拟合。虽然有很多因素可能导致这两种拟合问题,在这里我们重点讨论两个因素:模型复杂度和训练数据.

如上图,给定训练数据集,如果模型的复杂度过低,很容易出现欠拟合;如果模型复杂度过高,很容易出现过拟合。应对欠拟合和过拟合的一个办法是针对数据集选择合适复杂度的模型。

影响欠拟合和过拟合的另一个重要因素是训练数据集的大小。一般来说,如果训练数据集中样本数过少,特别是比模型参数数量(按元素计)更少时,过拟合更容易发生。此外,泛化误差不会随训练数据集里样本数量增加而增大。因此,在计算资源允许的范围之内,我们通常希望训练数据集大一些,特别是在模型复杂度较高时,例如层数较多的深度学习模型。

参考资料

《动手学深度学习》 — 动手学深度学习 2.0.0 documentation

Batch章节参考了一篇博客,图片来源原博客,找不到链接了,找到后补上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值