深度学习基础

什么是Pytorch?

Pytorch是torch的python版本,是由Facebook开源的神经网络框架,专门针对 GPU 加速的深度神经网络(DNN)编程。

PyTorch是Torch7团队开发的,从它的名字就可以看出,其与Torch的不同之处在于PyTorch使用了Python作为开发语言。所谓“Pythonfirst”,同样说明它是一个以Python优先的深度学习框架,不仅能够实现强大的GPU加速,同时还支持动态神经网络,这是现在很多主流框架,比如Tensorflow等都不支持的。

PyTorch既可以看做加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络,除了Facebook之外,它还已经被Twitter、CMU和Salesforce等机构采用。

Gpu运行效率远远大于cpu!

什么是transform?

transforms.py就像一个工具箱,里面定义的各种类就像各种工具,图片就是输入对象,经过工具处理,输出期望的图片结果。

python学习的两个小工具:

在终端中输入python或者ipython(交互式)即可打开python控制台

两个小工具:dir()和help()

什么是学习、训练?

由用户判断这个照片是猫还是不是猫,这个结果可以拿给神经网络,神经网络拿到了同样的照片也用自己的标准去判断,判断完了以后用这个结果和你的结果进行比对,肯定是这个结果相差越小,就证明它的标准和你的标准越接近,而神经网络再根据这个差距调整自己的过程,这就是在学习就是在训练。

什么是Backbone、Head、Neck?

在计算机视觉领域,特别是在物体检测和图像分割任务中,通常使用的神经网络结构中,"主干"、"头部"和"颈部"这些术语通常是指以下结构:

  1. 主干网络(Backbone):

    • 主干网络是整个神经网络的核心部分,负责提取输入数据的特征。
    • 对于图像处理任务,主干网络通常是卷积神经网络(CNN)的一部分,如ResNet、VGG、或MobileNet等。
    • 主干网络的输出通常包含丰富的高级特征,用于后续的任务,如对象检测或图像分割。
  2. 头部网络(Head):

    • 头部网络紧跟在主干网络之后,负责执行特定任务的输出。
    • 对于对象检测任务,头部网络可能包括用于预测边界框位置和类别的卷积和全连接层。
    • 对于图像分割任务,头部网络可能包括用于像素级别的分类或回归的层。
  3. 颈部网络(Neck):

    • 颈部网络位于主干网络和头部网络之间,起到连接两者的作用。
    • 颈部网络通常包括一些降维或特征融合的层,以提取并传递更具有信息量的特征给头部网络。
    • 在某些架构中,颈部网络也有助于处理多尺度信息,提高网络的鲁棒性。

这些结构的组合形成了一种分层的网络架构,其中主干网络负责提取通用特征,颈部网络用于调整特征的尺度和精度,头部网络则专注于执行特定的任务。这种模块化结构使得神经网络可以更灵活地适应不同的视觉任务。

推荐视频

安装Anaconda与PyTorch库(GPU版本)

Python深度学习:安装Anaconda、PyTorch(GPU版)库与PyCharm_哔哩哔哩_bilibili

王木头学科学

王木头学科学视频专辑-王木头学科学视频合集-哔哩哔哩视频

霹雳吧啦Wz

霹雳吧啦Wz视频专辑-霹雳吧啦Wz视频合集-哔哩哔哩视频

一:卷积神经网络基础

1.全连接层基础

全连接层的作用:

全连接层的主要功能包括:

  1. 特征组合: 通过学习连接权重,全连接层能够将前面层提取到的特征进行线性组合,形成新的特征表示。这种组合能够捕捉到不同低级特征之间的关系,从而形成更高级的特征。

  2. 非线性映射: 全连接层通常还包括激活函数,引入非线性变换。这个非线性映射使得网络能够学习复杂的非线性关系,提高模型的表达能力。

  3. 任务映射: 最终的全连接层将学到的高级特征映射到网络的输出,适应具体的任务,如分类、回归等。

全连接层结构:

最左边一层是输入层,对应的是数据的维度,数据通过这一层输入到神经网络。每一条边就是一个权重系数。

计算结果还需要经过一个激活函数才会传递到下一层,sigmoid只是符合激活函数要求的一种。

如何理解升维(下一层的神经元个数变多)

如上图所示,如果数据只是二维的,它们互相惨杂在一起,很难用直线进行划分。

而如果把它们全部升维,在更高的维度中,即便用更简单的模型也可以把它们分开

输入的数据进行了这样一个矩阵运算,矩阵对一个向量进行操作,将它变成另外一个向量。

所以我们可以把中间层看作数据的升维过程,有多少神经元就会把数据升到多少维,只要维度够高,一定可以找到一个超平面能对数据完成划分。增加模型的非线性能力,可以更好地拟合复杂的数据分布。

如何理解降维(下一层神经元个数变少)

以下图为例:利用神经网络判断一个人的心情

如果把输入图像的每一个像素当作一个输入节点,则有3500个输入节点,而我们判断一个人心情的特征只需要8个,因此一个特征不需要原始数据的所有维度,所以进行降维处理。(判断眼睛动作特征只需要原始图像的眼睛部位的像素)提高模型的泛化能力。

为什么神经元需要多层

举例:用神经网络判断输入图片是属于哪一个数字

由图示可以得出结论,隐藏层越深抽象程度越高。

  1. 增加模型的非线性能力:如果只有一层神经元,那么模型的拟合能力将受到限制,因为它只能表示线性关系。多层神经元可以增加模型的非线性能力,更好地拟合复杂的数据分布。(比如升维

  1. 提高模型的泛化能力:使用多层神经元可以减少过度拟合的风险。如果只有一层神经元,模型可能会过度拟合训练数据,导致在测试数据上表现不佳。多层神经元可以帮助模型学习更通用的特征,从而提高模型的泛化能力。(比如降维

  1. 增加特征的表达能力:每一层神经元都可以提取出不同的特征,通过多层神经元的组合,可以创建更复杂、更抽象的特征表示。这可以帮助模型更好地理解输入数据,并提高模型在复杂任务上的表现能力。

机器学习三要素:

反向传播:

所谓的反向传播就是把计算出来的梯度(交叉熵 偏差)反向传递到神经网络里面,让所有的W进行更新修改。

注:在深度学习网络中,反向传播的目标是计算损失函数对网络中所有可训练参数(包括全连接层、卷积层、循环层等)的梯度。这些梯度用于调整网络参数,使得网络在训练数据上的预测逐渐接近实际标签。

2.卷积层基础

在深度学习中卷积核的参数第一次是随机生成的,之后经过训练学习,通过反向传播进行参数的更新。

(1)卷积的意义

卷积的物理意义:

卷积在神经网络中意义:

(1)周围像素点对中心像素点产生的影响,g函数(卷积核的翻转)规定了如何影响

(2)过滤器:一个像素点如何试探周围的像素点,如何提取特征

注:传统方法的卷积核的参数都是固定的,而深度学习中卷积核的参数是通过训练更新的。因此在深度学习模型中,由于其复杂性和黑盒性,我们无法直接知道每个卷积核具体提取的特征是什么。

(2)卷积步骤

3.池化层基础

二:卷积神经网络基础补充

什么是优化器?

优化器就是在反向传播,权重更新过程中,使用梯度信息更新模型参数时采用不同的策略。

1.损失函数是如何设计出来的

损失函数就是神经网络里的标准和用户心中的那个标准相差多少的定量表达。

比较两个模型差距有多少的三种思路:最小二乘、最大似然估计、交叉熵

(1)最小二乘法
(2)极大似然估计

当我们知道事情发生的结果,去反推产生这个结果的概率模型的时候,往往就会用到最大似然估计法。

在此例子里,真实抛硬币的情况就是现实,在分类问题中,人的判断就是现实。

(3)交叉熵

什么是熵:

什么是KL散度、交叉熵:

2.理解梯度下降和反向传播

引言:前面讲了利用交叉熵来表示神经网络模型和理想模型的差距,现在差距可以表示了,需要做的就是减小这个差距了,用到的策略就是反向传播(梯度下降就是反向传播的一种)

(1)反向传播

所谓的反向传播就是把计算出来的梯度(交叉熵 偏差)反向传递到神经网络里面,根据网络中参数对偏差的贡献的大小对所有的W和b(感知机)进行相应的更新修改。

注:反向传播算法不仅适用于全连接层,也适用于其他层类型,包括卷积层和循环神经网络层等。在全连接层中,反向传播算法的计算比较简单,因为全连接层中每个神经元都与前一层的所有神经元相连接。而在卷积层和循环神经网络层中,每个神经元只与一部分前一层的神经元相连接,因此需要特殊的计算方法来计算梯度。在卷积层中,反向传播算法使用卷积操作来计算梯度。在循环神经网络层中,反向传播算法使用反向传播通过时间(BPTT)算法来计算梯度。卷积层中卷积核的参数也是在这里进行更新的。

(2)梯度下降法

理解了梯度,就要求解实现梯度下降所需要的梯度具体数值a、b、r具体是多少,就是梯度对变量求偏导

3.常用的模型性能指标

  • 准确率(Accuracy):模型正确分类的样本数占总样本数的比例。

  • 召回率(Recall):真实正样本中被模型预测为正的样本数量占真实正样本数量的比例。

  • 精度(Precision):模型预测为正的样本中真实正样本的数量占预测为正的样本数量的比例。

  • F1值(F1 Score):综合考虑准确率和召回率的指标,是准确率和召回率的调和平均数。

  • ROC曲线(ROC Curve):以假正率(False Positive Rate)为横坐标,真正率(True Positive Rate)为纵坐标,绘制出的曲线,用于评估二分类模型的性能,曲线下面积越大,表示模型性能越好。

  • AUC值(Area Under the Curve):ROC曲线下面积,用于度量二分类模型的性能,AUC值越大,表示模型性能越好。

三:深度学习训练过程

深度学习的训练过程的本质就是通过反向传播(Backpropagation)不断调整神经网络的权重,以最小化损失函数。这是一种优化过程,通过梯度下降(Gradient Descent)或其变体来最小化损失函数。

1.训练过程大体步骤:

  1. 数据预处理:选择合适的数据集,对数据进行清洗、去噪、特征提取、归一化等预处理操作,将数据划分为训练集、验证集和测试集(测试集留给用户自己用来测试)。

  1. 模型选择:根据任务的性质和数据的特点,选择合适的深度学习模型,例如卷积神经网络(CNN)、循环神经网络(RNN)、自编码器(Autoencoder)等。

  1. 模型构建:构建深度学习模型,包括输入层、隐藏层和输出层,选择合适的激活函数和损失函数。

  1. 模型训练:使用训练集对模型进行训练,优化模型参数,使得模型在训练集上的损失函数逐渐减小,从而提高模型的预测能力。

  1. 模型验证:在验证集上评估模型的性能,根据评估结果调整模型参数,避免过拟合和欠拟合的问题。

  1. 模型测试:在测试集上评估模型的性能,检查模型的泛化能力和预测能力,评估模型的效果是否符合预期。

  1. 模型优化:根据模型测试的结果,对模型进行优化,例如调整模型结构、选择合适的超参数、采用正则化方法等。

  1. 模型应用:将训练好的模型应用到实际问题中,进行预测和决策。

注:在深度学习训练过程中进行验证和测试,通常不会对训练产生影响。具体而言,训练过程中的验证和测试是在训练过程外独立进行的,不会对训练数据产生任何影响,只是通过验证和测试数据来评估模型的性能和泛化能力。通常会在每训练完一定数量的batch之后,进行一次模型验证,只是为了向用户展示目前正在训练的模型的性能。而测试过程通常是在整个训练过程结束后进行的,用于最终评估模型的性能和泛化能力,以验证模型的有效性和可用性。

torch语法基础:

torch.nn

torch.nn 是 PyTorch 中用于构建神经网络的模块,提供了许多用于构建深度神经网络的类和函数。torch.nn 模块中的类和函数可以帮助我们定义各种类型的神经网络层,如线性层、卷积层、池化层、循环神经网络层等,并提供了常用的激活函数、损失函数、优化器等。

以下是 torch.nn 模块中一些常用的类和函数的使用方法:

  1. 定义神经网络模型

在 torch.nn 中,我们可以通过继承 nn.Module 类来定义自己的神经网络模型。在继承 nn.Module 类后,我们需要在子类的构造函数中定义神经网络的各个层,并在 forward 方法中实现神经网络的前向传播过程。

  1. 定义损失函数

在 torch.nn 中,我们可以使用各种损失函数来计算神经网络的损失。对于分类任务,常用的损失函数是交叉熵损失函数,可以使用 nn.CrossEntropyLoss 类来定义。对于回归任务,常用的损失函数是均方误差损失函数,可以使用 nn.MSELoss 类来定义。

  1. 定义优化器

在 torch.nn 中,我们可以使用各种优化器来更新神经网络的参数。常用的优化器有随机梯度下降(SGD)、Adam、Adagrad 等,可以使用 torch.optim 模块中的类来定义。

2.x = F.relu(self.conv1(x))

F.relu 是 PyTorch 中的一个函数,用于实现 ReLU(Rectified Linear Unit)激活函数。在深度学习中,ReLU 是一种常用的激活函数,可以将神经网络的非线性性引入模型中,从而提高模型的表达能力和性能。

在 PyTorch 中,我们可以使用 F.relu 函数来实现 ReLU 激活函数。在神经网络的前向传播过程中,我们通常会先进行一些线性变换(比如卷积操作或全连接层操作),然后再使用激活函数对结果进行非线性变换。

net.load_state_dict(torch.load('Lenet.pth'))

这行代码使用了 PyTorch 中的 torch.load 函数来加载一个已经训练好的神经网络模型参数。torch.load 函数可以将之前使用 torch.save 函数保存的神经网络模型参数加载到内存中,以便我们使用已经训练好的模型进行预测或继续训练。

具体来说,这个代码段加载了一个名为 Lenet.pth 的文件,该文件包含了一个 LeNet 神经网络模型的参数。然后,调用 net.load_state_dict 函数将加载的参数加载到 net 模型中,以便我们可以使用已经训练好的模型进行预测。

需要注意的是,加载模型参数时需要保证模型结构与之前训练时的模型结构完全一致,否则会出现错误。

transform = transforms.Compose(

[transforms.Resize((32, 32)),

transforms.ToTensor(),

transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

  1. transforms.Resize((32, 32)):将图片缩放到指定大小,这里是将图片缩放到 32x32 像素大小。

  1. transforms.ToTensor():将 PIL.Image 或 numpy.ndarray 格式的图片转换为 PyTorch 中的张量形式,即将图片转换为 shape 为 (C, H, W) 的张量,其中 C、H、W 分别代表通道数、高度和宽度。

  1. transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)):将张量中的每个元素按通道进行标准化,即减去均值并除以标准差。这里是将像素值缩放到 [-1,1] 的范围内,均值和标准差都设置为 (0.5, 0.5, 0.5),表示每个通道的像素值均值为 0.5,标准差为 0.5。

这个数据预处理的代码段通常用于在训练过程中对数据进行预处理,并将预处理后的数据输入到神经网络中进行训练。

torch.utils.data.DataLoader

torch.utils.data.DataLoader 是 PyTorch 中用于加载数据集的工具类,它可以将数据集按照指定的 batch size、shuffle 等方式进行分割,并提供多线程数据预读取功能,以加快数据读取速度。DataLoader 的主要作用是将数据集划分为若干个 batch,并将每个 batch 中的数据按顺序读入内存,以便于神经网络对数据进行训练或预测。

具体来说,我们可以通过以下代码来创建一个 DataLoader 对象:


import torch.utils.data as data

dataset = MyDataset(...)
dataloader = data.DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4)

其中,MyDataset 表示数据集对象,batch_size 表示每个 batch 中包含的样本数量,shuffle 表示是否对数据集进行随机打乱,num_workers 表示使用多少个线程来读取数据。

val_data_iter = iter(val_loader)和val_image, val_label = next(val_data_iter)

这行代码使用 iter 函数将 val_loader 转换成一个迭代器对象 val_data_iter,以便对验证集进行迭代。在 PyTorch 中,可以使用 iter 函数将一个可迭代对象(如列表、元组、数据集对象等)转换成一个迭代器对象,以便逐个访问其元素。

其中 val_image 表示验证集样本的输入数据,val_label 表示验证集样本的标签。

具体来说,当我们调用 iter(val_loader) 时,Python 会自动调用 val_loader 对象的 __iter__ 方法,返回一个迭代器对象。随后,我们可以使用 next 函数逐个访问迭代器中的元素,直到迭代器中的所有元素都被访问完毕。

下面是一个使用 iter 函数迭代数据集的示例代码:


import torch.utils.data as data

dataset = MyDataset(...)
dataloader = data.DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4)

data_iter = iter(dataloader)
while True:
    try:
        inputs, labels = next(data_iter)
        # 将 inputs 输入到神经网络中进行训练或预测
    except StopIteration:
        break

在这个示例中,我们首先使用 DataLoader 类加载数据集,并使用 iter 函数将 dataloader 转换成迭代器对象 data_iter。然后,我们使用 next 函数逐个访问迭代器中的元素,将 inputs 输入到神经网络中进行训练或预测。当所有元素都被访问完毕后,next 函数会抛出 StopIteration 异常,此时我们可以退出循环。

epoch

epoch 是深度学习中的一个重要概念,表示将训练集中的所有样本都用于训练一次。在一个 epoch 中,我们需要将训练集分成若干个 batch,每个 batch 包含多个样本,用于同时训练神经网络的多个参数。训练过程中,通常需要对每个 batch 进行多次迭代,以便使神经网络更好地学习数据集中的模式。在每个 batch 中进行多次迭代的过程称为 mini-batch 梯度下降。

具体来说,一个 epoch 的训练过程通常包含以下步骤:

  1. 将训练集分成若干个 batch,每个 batch 包含多个样本。

  1. 对每个 batch 进行多次迭代,以便使神经网络更好地学习数据集中的模式。

  1. 在每个迭代中,将一个 batch 的样本输入到神经网络中进行前向传播和反向传播,并根据损失函数计算损失值。

  1. 在每个迭代结束后,使用优化算法(如随机梯度下降)调整神经网络的参数,以减小损失值。

  1. 当所有 batch 中的样本都被用于训练时,一个 epoch 的训练过程结束。

在 PyTorch 中,我们可以使用 for 循环迭代多个 epoch,以便训练神经网络的所有参数。在每个 epoch 中,我们可以使用 DataLoader 类加载数据集,并将其分成若干个 batch,然后对每个 batch 进行多次迭代,以训练神经网络的参数。

下面是一个使用 DataLoader 类训练神经网络的示例代码:


import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as data

class MyDataset(data.Dataset):
    def __init__(self, ...):
        ...

    def __getitem__(self, index):
        ...

    def __len__(self):
        ...

dataset = MyDataset(...)
dataloader = data.DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4)

model = MyModel(...)
optimizer = optim.SGD(model.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss()

num_epochs = 10
for epoch in range(num_epochs):
    for inputs, labels in dataloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

在这个示例中,我们首先定义了一个自定义的数据集 MyDataset,并使用 DataLoader 类加载数据集。然后,我们定义了一个神经网络模型 MyModel,使用随机梯度下降算法优化神经网络的参数,并使用交叉熵损失函数计算损失值。最后,我们使用 for 循环迭代 10 个 epoch,在每个 epoch 中使用 DataLoader 类加载数据集,并对每个 batch 进行多次迭代,以训练神经网络的参数。

损失函数

在深度学习中,损失函数是用于衡量神经网络预测值与真实值之间差距的函数。在训练过程中,我们需要最小化损失函数的值,以使神经网络的预测值更接近真实值。

在 PyTorch 中,我们可以使用 nn.CrossEntropyLoss() 类定义交叉熵损失函数。在训练过程中,我们需要将神经网络的输出值和真实标签作为参数传递给交叉熵损失函数,以计算损失值。然后,我们可以使用反向传播算法计算梯度,并使用优化算法更新神经网络的参数,以使损失值最小化。

optim.Adam(net.parameters(), lr=0.001)

这行代码使用 Adam 优化算法来更新神经网络的参数,以最小化损失函数的值。

Adam(Adaptive Moment Estimation)是一种常用的优化算法,它结合了 AdaGrad 和 RMSProp 两种优化算法的优点,能够自适应地调整每个参数的学习率,并保持对过去梯度的指数加权平均。这使得 Adam 在训练神经网络时表现出色,尤其适用于大规模数据和高维参数空间的情况。

在 PyTorch 中,我们可以使用 optim.Adam() 类来定义 Adam 优化算法。在训练过程中,我们需要将神经网络的参数和学习率作为参数传递给 Adam 类。然后,我们可以在每个 epoch 中使用反向传播算法计算梯度,并使用 Adam 类更新神经网络的参数,以最小化损失函数的值。

具体来说,上述代码中的 net.parameters() 表示将神经网络的所有参数传递给 Adam 类。lr 参数表示学习率,即每次参数更新的步长。在实际应用中,我们需要根据具体问题和数据集调整学习率的大小,以获得最优的训练效果。

for step, data in enumerate(train_loader, start=0):

这段代码使用 enumerate() 函数来遍历训练集中的所有 batch,并对每个 batch 进行训练。

enumerate() 函数是 Python 中的一个内置函数,用于将一个可迭代对象转换为一个枚举对象,同时返回每个元素的索引和值。在这段代码中,train_loader 是一个 DataLoader 类对象,用于加载训练集数据,并将其分成若干个 batch。start=0 表示从索引 0 开始枚举元素。

在每个 epoch 中,我们需要对训练集中的所有 batch 进行迭代,并对每个 batch 进行训练。在这段代码中,step 表示当前迭代的 batch(第几批)的索引,data 表示当前迭代的 batch 数据。具体来说,data 是一个元组,包含两个元素:输入数据和对应的标签。

optimizer.zero_grad()

这行代码用于清空优化器中之前计算的所有梯度信息。

在深度学习中,我们需要使用反向传播算法计算神经网络的梯度,并使用优化算法更新神经网络的参数。优化器中存储了每个参数的梯度信息,每次参数更新前,我们需要清空优化器中之前计算的所有梯度信息,以避免之前的梯度对当前的参数更新产生影响。

在 PyTorch 中,我们可以使用 zero_grad() 方法来清空优化器中的梯度信息。具体来说,在每个 batch 进行训练前,我们需要调用 zero_grad() 方法清空优化器中的梯度信息,然后再计算当前 batch 的梯度信息并更新参数。

需要注意的是,当我们需要对多个 batch 进行训练时,每个 batch 训练前都需要调用 zero_grad() 方法清空优化器中的梯度信息,以免不同 batch 之间的梯度产生干扰。

loss = loss_function(outputs, labels)和 loss.backward()

这行代码用于计算当前 batch 的损失值

在深度学习中,我们需要使用损失函数来衡量神经网络预测值和真实值之间的差异。在训练过程中,我们需要最小化损失函数的值,以使神经网络的预测值更接近真实值。

在这段代码中,outputs 表示当前 batch 的神经网络输出值,labels 表示当前 batch 的真实标签。loss_function 是之前定义的交叉熵损失函数,用于计算神经网络预测值和真实值之间的距离。通过将 outputs 和 labels 作为参数传递给 loss_function,我们可以计算当前 batch 的损失值。

在 PyTorch 中,我们可以使用 loss.backward() 方法计算当前 batch 的梯度,并使用优化算法更新神经网络的参数。需要注意的是,在计算梯度前,我们需要将当前 batch 的损失值累加到之前的损失值中,以便对整个训练集的损失值进行统计和分析。

optimizer.step()

这行代码用于使用优化算法更新神经网络的参数。

在深度学习中,我们需要使用优化算法来更新神经网络的参数,以最小化损失函数的值。在 PyTorch 中,我们可以使用 optimizer.step() 方法更新神经网络的参数。

在每个 batch 训练过程中,我们需要先使用反向传播算法计算当前 batch 的梯度,并将梯度信息存储到优化器中。然后,我们可以使用 optimizer.step() 方法根据优化算法更新神经网络的参数。具体来说,该方法将优化器中存储的梯度信息与当前参数值结合起来,计算出新的参数值,并将其存储到神经网络中。

需要注意的是,当我们需要对多个 batch 进行训练时,每个 batch 训练后都需要使用 optimizer.step() 方法更新神经网络的参数。此外,我们还需要在每个 epoch 开始前将优化器的学习率进行调整,以适应当前的训练状态。

with torch.no_grad()

在 PyTorch 中,torch.no_grad() 是一个上下文管理器,用于关闭自动求导机制。在这个上下文中,所有的计算都不会被加入到计算图中,也就是说,不会对模型的梯度产生影响。这样可以减少内存的使用,并提高计算速度。

一般来说,我们在使用 PyTorch 训练神经网络时,需要开启自动求导机制,以便计算梯度并更新模型参数。但是,在测试或推理阶段,我们通常不需要计算梯度,因为这会浪费计算资源,而且也没有必要。此时,我们可以使用 torch.no_grad() 上下文管理器来关闭自动求导机制,以减少不必要的计算。

predict_y = torch.max(outputs, dim=1)[1]

这行代码用于根据当前 batch 的神经网络输出值,获取当前 batch 的预测标签。

在深度学习中,我们需要使用神经网络对输入数据进行预测,并将预测结果与真实标签进行比较。在这段代码中,outputs 表示当前 batch 的神经网络输出值。由于我们的模型是一个分类模型,因此 outputs 表示当前 batch 中每个样本属于不同类别的概率值。具体来说,outputs 是一个大小为 (batch_size, num_classes) 的矩阵,其中 batch_size 表示当前 batch 的大小,num_classes 表示分类问题中的类别数量。

为了获取当前 batch 的预测标签,我们可以使用 torch.max() 函数。该函数用于获取输入张量在指定维度上的最大值和对应的索引。在这段代码中,我们指定 dim=1,表示在第 1 个维度上进行操作,即在每个样本的概率值中取最大值。torch.max() 函数的返回值是一个元组,包含两个张量,分别表示最大值和对应的索引。由于我们只需要获取索引值,因此使用 [1] 索引获取对应的张量。

需要注意的是,当前 batch 的预测标签是一个大小为 (batch_size,) 的张量,其中每个元素表示对应样本的预测标签。

语义分割篇

语义分割前言

转置卷积

FCN网络结构

膨胀卷积

膨胀卷积(Dilated convolution)-CSDN博客

1.当使用扩张率为2,卷积核为3*3进行卷积三次叠加,原始图层像素被卷积次数示意图(感受野范围)

2.当使用扩张率依次为1,2,3,卷积核为3*3进行卷积三次叠加,原始图层像素被卷积次数示意图(感受野范围)

3.卷积核为3*3的普通卷积(扩张率为1)进行三次叠加后,原始图层像素被卷积次数示意图(感受野范围)

明显可以看出使用空洞卷积多次卷积叠加之后,感受野范围增大了许多!

4.未使用HDC原则和使用HDC原则确定扩张率的效果展示对比图