Hi,朋友,这是我参加中国海洋大学 2023 暑期《深度学习-算法与实战》课程的学习笔记和感悟。网络上有相关的资源,如果你也对 Deep learning 感兴趣欢迎一起参与学习!

代码练习

MNIST 数据集分类

构建简单的 CNN 对 mnist 数据集进行分类。同时,还会在实验中学习池化与卷积操作的基本作用。Github

数据集中的部分图像

在小型全连接网络上训练(Fully-connected network)

Number of parameters: 6442
Train: [0/60000 (0%)]    Loss: 2.313182
Train: [6400/60000 (11%)]    Loss: 1.850687
Train: [12800/60000 (21%)]    Loss: 1.045183
Train: [19200/60000 (32%)]    Loss: 0.780392
Train: [25600/60000 (43%)]    Loss: 0.608197
Train: [32000/60000 (53%)]    Loss: 0.466111
Train: [38400/60000 (64%)]    Loss: 0.641364
Train: [44800/60000 (75%)]    Loss: 0.407706
Train: [51200/60000 (85%)]    Loss: 0.344793
Train: [57600/60000 (96%)]    Loss: 0.776256

Test set: Average loss: 0.3910, Accuracy: 8857/10000 (89%)

在卷积神经网络上训练

Number of parameters: 6422
Train: [0/60000 (0%)]    Loss: 2.277130
Train: [6400/60000 (11%)]    Loss: 1.012825
Train: [12800/60000 (21%)]    Loss: 0.382229
Train: [19200/60000 (32%)]    Loss: 0.405446
Train: [25600/60000 (43%)]    Loss: 0.384452
Train: [32000/60000 (53%)]    Loss: 0.382139
Train: [38400/60000 (64%)]    Loss: 0.176623
Train: [44800/60000 (75%)]    Loss: 0.254411
Train: [51200/60000 (85%)]    Loss: 0.188118
Train: [57600/60000 (96%)]    Loss: 0.372240

Test set: Average loss: 0.2160, Accuracy: 9332/10000 (93%)

可以发现,含有相同参数的 CNN 效果要明显优于 简单的全连接网络,是因为 CNN 能够更好的挖掘图像中的信息,主要通过两个手段:

  • 卷积:Locality and stationarity in images
  • 池化:Builds in some translation invariance

考虑到CNN在卷积与池化上的优良特性,如果我们把图像中的像素打乱顺序,这样 卷积池化 就难以发挥作用了,为了验证这个想法,我们把图像中的像素打乱顺序再试试

打乱像素顺序后的图片

在全连接网络上训练

Number of parameters: 6442
Train: [0/60000 (0%)]    Loss: 2.322852
Train: [6400/60000 (11%)]    Loss: 1.877555
Train: [12800/60000 (21%)]    Loss: 1.509280
Train: [19200/60000 (32%)]    Loss: 0.939807
Train: [25600/60000 (43%)]    Loss: 0.618809
Train: [32000/60000 (53%)]    Loss: 0.800014
Train: [38400/60000 (64%)]    Loss: 0.542634
Train: [44800/60000 (75%)]    Loss: 0.655749
Train: [51200/60000 (85%)]    Loss: 0.369399
Train: [57600/60000 (96%)]    Loss: 0.427479

Test set: Average loss: 0.4279, Accuracy: 8728/10000 (87%)

在卷积神经网络上训练

Number of parameters: 6422
Train: [0/60000 (0%)]    Loss: 2.328252
Train: [6400/60000 (11%)]    Loss: 2.267081
Train: [12800/60000 (21%)]    Loss: 2.131066
Train: [19200/60000 (32%)]    Loss: 1.464531
Train: [25600/60000 (43%)]    Loss: 1.089298
Train: [32000/60000 (53%)]    Loss: 0.902629
Train: [38400/60000 (64%)]    Loss: 1.014845
Train: [44800/60000 (75%)]    Loss: 0.459655
Train: [51200/60000 (85%)]    Loss: 0.611121
Train: [57600/60000 (96%)]    Loss: 0.533929

Test set: Average loss: 0.5581, Accuracy: 8206/10000 (82%)

从打乱像素顺序的实验结果来看,全连接网络的性能基本上没有发生变化,但是 卷积神经网络的性能明显下降

这是因为对于卷积神经网络,会利用像素的局部关系,但是打乱顺序以后,这些像素间的关系将无法得到利用

CIFAR10 数据集分类

使用 CNN 对 CIFAR10 数据集进行分类。Github

下面将使用CIFAR10数据集,它包含十个类别:‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’。CIFAR-10 中的图像尺寸为3x32x32,也就是RGB的3层颜色通道,每层通道内的尺寸为32*32

CIFAR10 数据集

框架版本更新,如果运行报错,需要修改代码 iter(trainloader).next()next(iter(trainloader))

训练完成后取一组做测试

测试数据

frog
ship
dog
horse
dog
frog
truck
truck

效果还可以,全对

问题总结

1.dataloader 里面 shuffle 取不同值有什么区别?

shuffle 参数用于控制数据在每个 epoch(训练周期)开始时是否进行洗牌操作

在 DataLoader 中,shuffle 参数可以取两个值:True 和 False。

  1. shuffle=True

    • 当设置为 True 时,在每个 epoch 开始时,DataLoader 会将数据集中的样本随机打乱,这样模型在每个 epoch 中看到的样本顺序都是不同的。
    • 这样做的好处是训练数据可以更好地代表整体数据的分布,避免模型过度拟合特定样本顺序的问题。
    • 在训练集较大时,shuffle=True 可以使每个 epoch 的样本顺序都不同,增加数据的多样性,有助于更好地优化模型。
  2. shuffle=False

    • 当设置为 False 时,在每个 epoch 开始时,DataLoader 不会对数据集进行洗牌,而是按照原始顺序依次加载样本。
    • 这在某些情况下是有用的,比如在验证集或测试集上,由于不需要进行梯度更新,没有必要对数据进行洗牌,可以提高数据加载的效率。

在使用 DataLoader 时,通常在训练集上设置 shuffle=True,以获得更好的模型训练效果,在验证集或测试集上设置 shuffle=False,以确保结果的可复现性和准确性

2.transform 里,取了不同值,这个有什么区别?

对于 transform,常见的取值有两种:Train transform 和 Test transform。

  1. Train transform(训练时数据增强):

    • Train transform 通常在模型的训练阶段使用,用于增强训练数据的多样性,提高模型的泛化能力。
    • 在 Train transform 中,可以使用一些数据增强的方法,例如随机裁剪、随机翻转、随机旋转等,来扩充训练数据集,增加数据的多样性。
    • 此外,一般还会对图像进行归一化操作,将图像的像素值映射到一个特定范围,例如 [0, 1] 或 [-1, 1]。
  2. Test transform(测试时数据处理):

    • Test transform 通常在模型的测试阶段使用,用于对测试数据进行预处理,使其符合模型输入的要求。
    • 在 Test transform 中,不使用数据增强的方法,因为测试时需要保持数据的原始状态,以保证结果的一致性和可比性。
    • 通常只进行与模型输入匹配的预处理,例如缩放、裁剪或归一化等操作,保证测试数据和训练数据具有相似的预处理方式。

区分 Train transform 和 Test transform 的原因在于,在模型的训练和测试阶段,数据预处理的目标是不同的。在训练阶段,我们希望增加数据的多样性以提高模型的泛化能力,而在测试阶段,我们需要保持数据的原始状态,以获得准确且可复现的模型性能评估结果

3.epoch 和 batch 的区别?

  1. Epoch(训练周期):

    • Epoch 是指将整个训练数据集在神经网络中前向传播(计算损失函数)和反向传播(更新权重)的过程的一个完整迭代。
    • 在每个 epoch 中,所有的训练样本都会被用于训练一次,即模型会看到数据集中的所有样本一次。
    • 一个 epoch 的训练完成后,模型的参数(权重和偏置)会根据优化算法进行更新,以使模型逐渐收敛于最优解。
  2. Batch(批次):

    • Batch 是指在每次参数更新时,模型一次性处理的一组样本。
    • 由于训练数据集通常非常大,一次性使用全部数据进行训练可能会导致内存不足或计算效率低下。因此,将数据分成若干个较小的 batch 可以加快训练过程。
    • 每个 batch 的样本数量通常称为 batch size。较大的 batch size 可以提高训练速度,但可能需要更多的内存。较小的 batch size 可以降低内存需求,但可能导致训练过程更加嘈杂,尤其是在数据集较小的情况下。

在训练深度学习模型时,通常会将整个数据集分成多个 batch,并在每个 epoch 中使用不同的 batch 随机训练模型,这样可以有效地利用计算资源,减少内存需求,并且在训练过程中增加数据的随机性,有助于模型更好地泛化

4.1x1的卷积和 FC 有什么区别?主要起什么作用?

  1. 1x1 卷积:

    • 1x1 卷积是指卷积核的大小为 1x1 的卷积操作,也称为逐点卷积(pointwise convolution)。
    • 1x1 卷积并不会改变输入数据的空间尺寸(宽度和高度),只会改变通道数。它对每个通道进行独立的线性变换。
    • 1x1 卷积可以看作是一个特殊的卷积,通过调整通道数,实现对特征通道的线性组合,以增加或减少通道的数量。
    • 1x1 卷积在深度学习中的主要作用是用于特征融合和降维。通过调整通道数,可以实现对特征图的维度变换,从而提取更有意义的特征,并减少网络参数。
  2. 全连接层(FC):

    • 全连接层是深度学习中最常见的层之一,也称为密集连接层或线性层。在全连接层中,每个神经元都与上一层的所有神经元相连接。
    • 全连接层的输入数据通常是一个展平的向量,将之前的卷积层或池化层的输出数据展平成一维向量后作为全连接层的输入。
    • 全连接层的主要作用是实现特征与类别之间的映射。在分类任务中,全连接层将特征向量映射到类别的概率分布,输出对每个类别的预测概率。

主要区别和作用:

  • 区别:

    • 1x1 卷积是一个特殊的卷积操作,主要用于特征融合和降维,通过调整通道数进行特征的线性组合。
    • 全连接层是深度学习中常用的层之一,将输入数据的所有元素与权重相乘并加上偏置,实现特征到输出类别的映射。
  • 主要作用:

    • 1x1 卷积用于调整通道数,可以增加网络的表达能力和灵活性,同时减少参数量和计算量。
    • 全连接层用于分类任务,将特征映射到类别的概率分布,进行最终的分类决策。

5.residual leanring 为什么能够提升准确率?

Residual Learning(残差学习)通过引入残差块(Residual Blocks)来提升准确率和训练效率

  1. 解决梯度消失问题:在深度神经网络中,随着层数的增加,梯度可能会变得非常小,导致梯度消失问题。这会使得网络难以训练,甚至导致训练过程陷入不收敛的状态。Residual Learning 通过引入残差块,使得网络的前向传播可以直接跳过一些层,这样就能保留较大的梯度,有效地缓解了梯度消失问题,使得网络更容易训练。
  2. 容易优化:由于残差块的结构,模型训练过程中可以选择跳过某些层,从而使得整个网络变得更加平滑,更容易优化。这种设计方式允许网络学习恒等映射(identity mapping),即将输入直接作为输出,这样即使添加了额外的层,网络也可以选择学习将输入直接传递给下一层,从而保持了模型的性能。
  3. 更深的网络:传统的深度神经网络在增加层数时,准确率可能会饱和或下降,因为随着网络深度的增加,梯度消失和梯度爆炸等问题变得更加明显。但是,使用残差学习,即使网络变得更深,模型也能够更好地训练和优化,因此能够构建更深层次的神经网络。深层网络通常具有更强大的表示能力,可以更好地捕获数据的复杂特征,从而提升准确率。
  4. 特征复用:残差块的设计可以使得网络的前向传播中,之前层的特征直接添加到后续层的特征中,这样可以促进特征的复用。复用之前层的特征可以帮助网络学习到更加有效和表达能力强的特征表示,从而提升准确率。

6.代码练习二里,网络和1989年 Lecun 提出的 LeNet 有什么区别?

  1. 结构和深度:

    • LeNet:LeNet 是早期的卷积神经网络,由 Yann LeCun 等人于 1989 年提出,用于手写数字识别。它是一个相对较浅的网络,包含了两个卷积层和三个全连接层,总共只有几层。
    • 现代网络:随着深度学习的发展,现代的神经网络通常更深、更复杂。例如,ResNet、VGG、Inception、BERT 等,这些网络都有数十层乃至上百层,拥有更强大的表达能力,可以处理更复杂的任务。
  2. 卷积操作:

    • LeNet:LeNet 中使用的卷积操作相对简单,没有像现代网络那样广泛使用各种卷积核大小、步幅和填充方式。
    • 现代网络:现代网络采用了更多的卷积技巧,如不同大小的卷积核、跨步卷积、空洞卷积(Dilated Convolution)、转置卷积等,以提取更丰富的特征信息。
  3. 激活函数:

    • LeNet:LeNet 使用的激活函数主要是 Sigmoid 和 Tanh,这在现代网络中已经不常使用了。
    • 现代网络:现代网络一般使用 ReLU(Rectified Linear Unit)等更为有效的激活函数,以避免梯度消失问题和加速收敛。
  4. 参数初始化和优化算法:

    • LeNet:在 LeNet 的时代,参数初始化和优化算法相对简单,通常使用随机初始化和梯度下降法进行训练。
    • 现代网络:现代网络使用更复杂的参数初始化方法,如 He 初始化、Xavier 初始化等,并采用更高级的优化算法,如 Adam、RMSprop 等,以提高训练速度和效果。

7.代码练习二里,卷积以后feature map 尺寸会变小,如何应用 Residual Learning?

Residual Learning(残差学习)是为了解决深度神经网络中的梯度消失和退化问题而提出的技术。它的主要思想是引入残差块(Residual Blocks),使得网络可以学习恒等映射(identity mapping),从而在训练过程中,网络可以选择是否跳过某些层,使得网络变得更加平滑且易于优化

  1. 网络跳跃连接(Skip Connection):

    • 在残差块中,引入了跳跃连接,将输入特征图直接与残差块的输出相加。这样,即使特征图的尺寸发生变化,仍然可以通过跳跃连接将原始输入与变换后的输出相加,从而保持特征图的尺寸不变。
  2. 填充和步幅控制:

    • 在卷积操作中,可以通过合适的填充和步幅控制来减少特征图尺寸的变化。对于 1x1 的卷积操作,步幅通常设置为 1,而对于其他卷积层,可以使用适当的填充和步幅来控制特征图的尺寸,使其与之前的特征图尺寸保持一致。
  3. 维度变换:

    • 在残差块中,可以使用 1x1 的卷积操作来改变特征图的通道数,从而使得输入和输出的通道数相同,便于进行相加操作。

8.有什么方法可以进一步提升准确率?

  1. 对数据进行准确标注和预处理
  2. 选用最优的激活函数、顺势函数
  3. 使用更深更宽的神经网络

最后修改:2023 年 07 月 27 日
如果觉得我的文章对你有用,请随意赞赏