Pytorch 的神经网络 学习笔记

news2024/12/25 4:59:23

参照官方网址

Module — PyTorch 2.2 documentation

一. 介绍

1. torch.nn模块

torch.nn是PyTorch中专门用于构建神经网络的模块。它提供了构建深度学习模型所需的所有构建块,包括各种层类型(如全连接层、卷积层、循环层等)、激活函数、损失函数等。

2.nn.Module

nn.Module是所有神经网络模块和层的基类。自定义的网络模型通常通过继承nn.Module类来创建。在这个类中,你需要定义__init__方法来初始化网络层,以及forward方法来指定数据如何通过这些层。

3. 层(Layers)

PyTorch提供了多种预定义的层,可以直接用于构建神经网络。例如:

  • nn.Linear:全连接层(线性层)。
  • nn.Conv2d:二维卷积层,用于图像处理。
  • nn.LSTM:长短期记忆网络层,用于处理序列数据。
  • nn.ReLUnn.Sigmoidnn.Tanh等:激活函数层。

4. 损失函数(Loss Functions)

损失函数用于计算模型输出与真实标签之间的差异。PyTorch提供了多种损失函数,如:

  • nn.MSELoss:均方误差损失,常用于回归任务。
  • nn.CrossEntropyLoss:交叉熵损失,常用于分类任务。
  • nn.BCEWithLogitsLoss:带有Sigmoid的二元交叉熵损失。

5. 优化器(Optimizers)

PyTorch通过torch.optim模块提供了多种优化算法来更新网络的权重。这些优化器包括:

  • optim.SGD:随机梯度下降。
  • optim.Adam:基于自适应矩估计的优化算法。
  • optim.RMSprop:均方根传播优化算法。

6. 数据处理(DH)

如前所述,torch.utils.data.Datasettorch.utils.data.DataLoader是PyTorch中用于处理数据的重要组件。它们帮助你高效地加载和预处理数据,以便用于训练和评估模型。

7. 自动微分(AD)

自动微分(Automatic Differentiation),PyTorch的autograd模块提供了自动微分功能,这是训练神经网络的核心。它允许开发者只需定义前向传播,而后向传播(梯度计算)则由库自动完成。

一个典型的神经网络训练流程包括定义模型结构、选择损失函数和优化器、加载数据、执行前向传播、计算损失、执行反向传播以及更新模型参数。

 8.先写一个最基础的

引入依赖

import torch
from torch import tensor, nn

创建类

class ykModule(nn.Module):

定义最基本的两个函数,首先是init函数,必须要重写父类的init方法

    def __init__(self):
        super().__init__()

然后还有向前传播forward方法,

    def forward(self, input):
        output = input + 1
        return output

创建实例测试,创建对象,创建张量,代入测试

yk = ykModule()
x = torch.tensor(1.0)
output = yk(x)
print(output)

全部代码

import torch
from torch import tensor, nn


class ykModule(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, input):
        output = input + 1
        return output


yk = ykModule()
x = torch.tensor(1.0)
output = yk(x)
print(output)

打印

二. 卷积层

CONV2D 是卷积神经网络(Convolutional Neural Network, CNN)中常见的一种操作。它指的是二维卷积操作(2D Convolution),用于处理二维图像数据。在卷积神经网络中,通过使用卷积操作可以从输入图像中提取特征,并在不同层次上进行特征的抽象和表示。

在 CNN 中,CONV2D 操作通常由一个卷积核(kernel)对输入图像进行滑动计算得到的结果组成。这个操作会将卷积核与输入图像的每个位置进行对应元素相乘,并将结果相加,得到输出特征图。卷积核的参数通常是需要学习的,它决定了卷积操作提取的特征种类和性质。

1. 参数

  1. in_channels(int):输入图像的通道数,即输入图像的深度。对于彩色图像,通常有RGB三个通道,因此该参数为3;对于单通道灰度图像,该参数为1。

  2. out_channels(int):输出特征图的通道数,即卷积核的数量,也是卷积操作产生的特征图的深度。

  3. kernel_size(int或tuple):卷积核的大小。可以是一个整数表示卷积核的高度和宽度相等,也可以是一个元组 (k_height, k_width) 表示卷积核的高度和宽度分别为 k_height 和 k_width

  4. stride(int或tuple,可选):卷积核在输入图像上移动的步长。默认值为1,表示每次移动一个像素;可以是一个元组 (s_height, s_width) 表示垂直方向和水平方向的步长分别为 s_height 和 s_width

  5. padding(int、tuple或str,可选):在输入图像的四个边缘添加的零填充的数量,用于控制卷积操作的输出尺寸与输入尺寸的关系。默认值为0,表示不进行零填充;可以是一个整数表示在所有边缘添加相同数量的填充,也可以是一个元组 (pad_height, pad_width) 表示在垂直方向和水平方向的填充数量分别为 pad_height 和 pad_width

  6. padding_mode(str,可选):零填充的方式。可选值有 ‘zeros’(默认)、‘reflect’、‘replicate’ 或 ‘circular’。

  7. dilation(int或tuple,可选):卷积核内部元素之间的空间间隔,用于控制卷积核的感受野(receptive field)。默认值为1,表示卷积核内部元素之间没有空隙;可以是一个元组 (d_height, d_width) 表示垂直方向和水平方向的空间间隔分别为 d_height 和 d_width

  8. groups(int,可选):分组卷积的组数,用于将输入通道分成几组并分别对每组进行卷积操作。默认值为1,表示不使用分组卷积。

  9. bias(bool,可选):是否添加可学习的偏置。默认为True,表示在卷积操作的结果上添加一个可学习的偏置项。

参照了b站土堆的演示图

代码演示

import torch
import torch.nn.functional as F

input = torch.tensor([[1, 2, 0, 3, 1],
                      [0, 1, 2, 3, 1],
                      [1, 2, 1, 0, 0],
                      [2, 1, 0, 1, 1],
                      [2, 1, 0, 1, 1]])

ker_nal = torch.tensor([[1, 2, 1],
                        [0, 1, 0],
                        [2, 1, 0]])
# 二维卷积操作需要输入四元素
input = torch.reshape(input, (1, 1, 5, 5))
ker_nal = torch.reshape(ker_nal, (1, 1, 3, 3))
output = F.conv2d(input, ker_nal, stride=1)
print(output)

打印

 将padding设置为1,默认为padding为0,填充的位置值为0

out_channel为2时

2. 卷积层操作

(1)引入库

也可以先写代码,使用pycharm的import引入

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWrite

(2)获取数据集

dataset = torchvision.datasets.CIFAR10("./data", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)

(3)创建数据加载器

loader = DataLoader(dataset, batch_size=64)

(4)创建类

class Yk(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=(3, 3), stride=(1, 1), padding=0)

    def forward(self, x):
        x = self.conv1(x)
        return x

(5)测试

writer = SummaryWriter("../logs")
yk = Yk()
step = 0
for data in loader:
    imgs, targets = data
    output = yk(imgs)
    writer.add_images("input", imgs, step)
    output = torch.reshape(output, (-1, 3, 20, 30))
    print(imgs.shape)
    print(output.shape)
    writer.add_images("output", output, step)

    step = step + 1
writer.close()

三. 池化层

1. 介绍

在PyTorch中,池化层(Pooling layer)是用于卷积神经网络中的一种常见层,主要用于减少数据的空间尺寸(即宽度和高度),从而减少参数的数量和计算量,同时也有助于提取特征中的主要信息,增加模型的抗噪声能力。

常见的池化层类型包括:

  1. 最大池化层(Max Pooling Layer):该层通过从覆盖区域中选择最大值来工作。例如,在一个 2x2 的池化窗口中,它会从四个数字中选择最大的一个。这有助于保留特征中的显著信息。

  2. 平均池化层(Average Pooling Layer):与最大池化相比,平均池化层会计算其覆盖区域的平均值。这使得网络在特征的整体平均响应上更加关注,有时可以减少最大池化可能带来的特征损失。

  3. 全局池化层(Global Pooling Layer):该层通常在网络的末端使用,可以将整个特征图的尺寸减少到 1x1,这通常用于将空间特征映射到类别预测上。

这些池化层在PyTorch中可以通过 torch.nn 模块中的 MaxPool2dAvgPool2d 等类来实现。

2. 参数

  1. kernel_size:池化窗口的大小。如果设置为一个整数,那么池化窗口将是正方形的,即宽度和高度相同。如果设置为一个元组,可以指定不同的宽度和高度。

  2. stride:池化窗口移动的步长。如果未指定,则默认为 kernel_size 的值。步长决定了池化窗口在输入特征图上移动的距离。如果步长小于池化窗口的大小,则池化窗口之间会有重叠;如果步长等于窗口大小,则没有重叠。

  3. padding:在输入特征图的边缘添加的填充。如果设置为一个整数,那么在所有边缘上添加相同数量的填充;如果设置为一个元组,则可以指定在不同边缘上添加不同数量的填充。填充通常用于控制输出特征图的大小。

  4. dilation:控制池化窗口中元素之间的间隔。通常设置为1,表示没有间隔。如果增加dilation值,池化窗口将包含输入特征图中更广泛区域的元素,但实际上并不增加池化窗口的大小。

  5. return_indices:是否返回池化操作中每个最大值的索引。这在使用 torch.nn.MaxUnpool2d 进行上采样时很有用,因为它可以帮助将值放回到正确的位置。

  6. ceil_mode:计算输出尺寸时使用的模式。默认情况下(ceil_mode=False),输出尺寸是通过向下取整计算得到的。如果设置为 True,则使用向上取整。这会影响输出特征图的大小,特别是当输入尺寸不能被池化窗口大小整除时。

整理课堂笔记(土堆)

演示(最大池化)

3. 操作实例

获取数据集,并创建dataloader实例

dataset = torchvision.datasets.CIFAR10("./data", download=False, train=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)

创建类

class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=False)

    def forward(self, input):
        output = self.maxpool1(input)
        return output

创建对象,并创建writer实例

yk = Yk()
writer = SummaryWriter("../logs")

循环获取批量图片并通过池化层处理

step = 0
for data in dataloader:
    imgs, target = data
    writer.add_images("input", imgs, step)
    output = yk(imgs)
    writer.add_images("output", output, step)
    step = step + 1

最后关闭writer

writer.close()

全部代码

import torch
import torchvision
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./data", download=False, train=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)


class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=False)

    def forward(self, input):
        output = self.maxpool1(input)
        return output


yk = Yk()
writer = SummaryWriter("../logs")
step = 0
for data in dataloader:
    imgs, target = data
    writer.add_images("input", imgs, step)
    output = yk(imgs)
    writer.add_images("output", output, step)
    step = step + 1
writer.close()

展示

四. 非线性激活

1. 介绍

非线性激活函数是神经网络中的一种函数,它的作用是在神经元的输出上引入非线性变换。这种非线性是神经网络能够学习和执行复杂任务的关键因素之一,因为没有非线性激活函数,无论神经网络有多少层,最终都只能表示线性变换,这大大限制了网络的表达能力和复杂度。

非线性激活函数有很多种,以下是一些常用的激活函数:

  1. ReLU (Rectified Linear Unit):目前最流行的激活函数之一,定义为 f(x) = max(0, x)。它的优点是计算简单,能够加快训练速度,并且在正区间内梯度恒定,有助于缓解梯度消失问题。

  2. Sigmoid:早期神经网络中常用的激活函数,定义为 f(x) = 1 / (1 + exp(-x))。它将输入压缩到 (0, 1) 范围内,常用于二分类问题的输出层。然而,它容易导致梯度消失和饱和,且计算相对复杂。

  3. Tanh (Hyperbolic Tangent):类似于 Sigmoid 函数,但将输入压缩到 (-1, 1) 范围内,定义为 f(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))。它的中心化特性使得在某些情况下优于 Sigmoid。

  4. Leaky ReLU:ReLU 的变体,旨在解决 ReLU 在负区间导致的神经元死亡问题。定义为 f(x) = x if x > 0 else alpha * x,其中 alpha 是一个小的正数。

  5. Softmax:常用于多分类问题的输出层,将输入向量转换为概率分布,每个元素的范围在 (0, 1) 之间,且所有元素之和为 1。

  6. Swish:是一种相对较新的激活函数,定义为 f(x) = x * sigmoid(x)。它结合了 Sigmoid 和 ReLU 的特性,实验表明在某些情况下性能优于 ReLU。

非线性激活函数使得神经网络能够捕捉数据中的复杂模式和关系,而不仅仅是简单的线性关系。在设计神经网络时,选择合适的激活函数是非常重要的,因为它会影响网络的学习能力和性能。

2. 操作示例

代码

import torch
import torchvision
from torch import nn
from torch.nn import MaxPool2d, ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./data", download=False, train=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)


class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.relu1 = ReLU()
        self.sigmoid1 = Sigmoid()

    def forward(self, input):
        output = self.sigmoid1(input)
        return output


yk = Yk()
writer = SummaryWriter("../logs")
step = 0
for data in dataloader:
    imgs, target = data
    writer.add_images("input", imgs, step)
    output = yk(imgs)
    writer.add_images("output", output, step)
    step += 1
writer.close()

Tensorboard页面展示

五. 归一化

1. 介绍

归一化在数据预处理和机器学习模型设计中扮演着重要角色,主要作用包括:

  1. 提升模型训练效率

    • 归一化通过将输入数据的范围缩放到一个统一的尺度(如0到1或-1到1),有助于提高梯度下降等优化算法的收敛速度。因为它使得所有维度的特征具有相似的尺度,从而避免了某些特征在计算中占主导地位。
  2. 防止数据溢出

    • 在处理具有极端值或不同量级的特征时,未归一化的数据可能导致计算时数值不稳定或溢出。归一化能够减少这种情况的发生。
  3. 提高模型的泛化能力

    • 归一化有助于减少模型在训练数据中的偏见,特别是当数据的某些特征比其他特征具有更大的变数或范围时。这有助于提升模型在新未见数据上的表现。
  4. 满足模型算法的假设要求

    • 某些机器学习算法(如支持向量机SVM和K-最近邻KNN)需要归一化输入数据来保证模型运行正确。这些算法在处理距离计算时尤其敏感,不同的尺度会影响最终的结果。
  5. 使特征之间比较公平

    • 归一化确保没有任何一个特征会由于其值范围较大而对模型的预测结果产生不成比例的影响。

2. 参数

这些参数是批量归一化(Batch Normalization)层在机器学习库如PyTorch中的常见配置项,它们分别控制不同的功能和行为:

  1. num_features (int)

    • 该参数指定输入数据中的特征数量(即通道数C),是批量归一化层需要处理的特征维度。对于卷积层来说,这通常是输入数据的通道数;对于全连接层,则是输入向量的维数。
  2. eps (float)

    • 用于数值稳定性的一个小常数,添加到方差的分母中,防止在方差非常小的情况下除以零的错误发生。默认值通常设为1e-5。
  3. momentum (float)

    • 用于计算运行均值(running_mean)和运行方差(running_var)的动量。这个参数决定了每个批次统计量在更新时保留多少历史信息。如果设置为None,则使用累积移动平均(简单平均),即每次都根据所有过去批次的平均值来更新。
  4. affine (bool)

    • 如果设置为True,则该层将包含可学习的仿射变换参数,即每个特征有其对应的缩放参数(scale/gamma)和偏移参数(shift/beta)。这允许模型在归一化后对数据进行进一步的线性变换。
  5. track_running_stats (bool)

    • 如果设置为True,该层将在训练过程中跟踪(即计算和更新)运行均值和运行方差。这些统计量在模型评估(验证或测试)阶段被用来代替批次统计量。如果设置为False,则该层不会跟踪这些运行统计量,无论在训练还是评估阶段,都将使用当前批次的统计量。

这些参数共同决定了批量归一化层的行为和效果,使得网络训练更加稳定,加快收敛速度,同时提高模型的泛化能力。

六. 线性层

1. 介绍

在 PyTorch 中,线性层(linear layer)是一种常见的神经网络层,也被称为全连接层(fully connected layer)或密集层(dense layer)。线性层的作用是将输入张量与权重矩阵相乘,并添加偏置项,从而实现对输入数据的线性变换。

具体来说,线性层的作用包括:

  1. 线性变换:线性层接收一个输入张量,其形状为 (batch_size, input_size),其中 batch_size 表示批量大小,input_size 表示输入特征的数量。线性层还有一个权重矩阵,其形状为 (input_size, output_size),其中 output_size 表示输出特征的数量。线性层将输入张量与权重矩阵相乘,得到形状为 (batch_size, output_size) 的输出张量。

  2. 添加偏置项:线性层还可以选择是否添加偏置项。偏置项是一个长度为 output_size 的向量,每个元素对应输出张量中的一个特征。偏置项的作用是对线性变换的结果进行平移,从而引入非线性变换,增加模型的表达能力。

线性层通常用于神经网络的隐藏层和输出层,它们能够学习输入数据的线性映射,从而实现特征提取和转换。在深度学习模型中,线性层通常与非线性激活函数(如ReLU、sigmoid、tanh等)结合使用,以增加模型的非线性表达能力。

在 PyTorch 中,可以使用 torch.nn.Linear 类来创建线性层,该类提供了一个简单的接口来定义和初始化线性层的参数。

3. 实例操作

获取数据集,并使用数据加载器

dataset = torchvision.datasets.CIFAR10("./data", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())
dataLoad = DataLoader(dataset, batch_size=64,drop_last=True)

我建议先计算一下图片的shape(可以先跳过这一步)

for data in dataLoad:
    imgs, targets = data
    print(imgs.shape)

打印得到每一张图片的shape为 torch.Size([64, 3, 32, 32])

创建类

class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.learner1 = Linear(196608, 10)

    def forward(self, input):
        output = self.learner1(input)
        return output

遍历,需要将图片reshape

yk = Yk()
for data in dataLoad:
    imgs, targets = data
    print(imgs.shape)
    # output = torch.reshape(imgs, (1, 1, 1, -1))
    output = torch.flatten(imgs)
    print(output.shape)
    output = yk(output)
    print(output.shape)

运行

全部代码

import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("./data", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())
dataLoad = DataLoader(dataset, batch_size=64,drop_last=True)


class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.learner1 = Linear(196608, 10)

    def forward(self, input):
        output = self.learner1(input)
        return output


yk = Yk()
for data in dataLoad:
    imgs, targets = data
    print(imgs.shape)
    # output = torch.reshape(imgs, (1, 1, 1, -1))
    output = torch.flatten(imgs)
    print(output.shape)
    output = yk(output)
    print(output.shape)

七. 循环层

1. 介绍

在PyTorch中,循环神经网络(RNN)层用于处理序列数据,如文本、时间序列或任何具有序列结构的数据。RNN层在每个时间步接受输入并输出隐藏状态,这个隐藏状态会传递到下一个时间步。这种递归结构使得RNN能够捕捉序列中的时间相关性,并对序列数据进行建模。

RNN在自然语言处理(NLP)中广泛应用,用于文本生成、语言建模、机器翻译等任务。此外,RNN也被用于时间序列分析、股票预测、音频处理等领域。

PyTorch提供了多种类型的RNN层,如nn.RNNnn.LSTMnn.GRU,它们分别对应于标准的RNN、长短期记忆网络(LSTM)和门控循环单元(GRU)。这些不同的层具有不同的内部结构和能力,可以根据具体任务的需求选择适当的RNN类型。

2. 参数

在PyTorch中,循环神经网络(RNN)层的参数意义如下:

  • input_size: 输入 x 中的特征数目。对于文本数据,通常是词嵌入的维度大小;对于时间序列数据,可能是每个时间步的特征数量。

  • hidden_size: 隐藏状态 h 的特征数目,即RNN层的输出大小或者说隐藏层的大小。这个参数决定了模型能够学习和存储的信息量。

  • num_layers: 循环层的数量,即堆叠RNN的层数。如果设置为大于1的值,则会形成一个堆叠的RNN,其中第二个RNN会接收第一个RNN的输出并计算最终结果。

  • nonlinearity: 使用的非线性激活函数,可以选择’tanh’或’relu’。默认为’tanh’。

  • bias: 是否使用偏置项。如果设置为False,则RNN层将不使用偏置权重 ��ℎbih​ 和 �ℎℎbhh​。默认为True。

  • batch_first: 如果为True,则输入和输出张量的形状为(batch, seq, feature),而不是(seq, batch, feature)。注意,这不适用于隐藏状态或单元状态。默认为False。

  • dropout: 如果非零,则在每个RNN层的输出上引入一个Dropout层,除了最后一层以外的所有层都会应用dropout,dropout的概率等于dropout参数值。默认为0,即不应用dropout。

  • bidirectional: 是否使用双向循环神经网络。如果为True,则RNN层将变为双向。默认为False。

这些参数可以根据具体任务的需求进行调整,例如调整隐藏状态的大小、增加层数以增加模型的复杂度、使用双向RNN以捕捉前后文信息等。

八. 正则化层

1. 介绍

PyTorch中的正则化层主要用于帮助神经网络模型避免过拟合,提高模型的泛化能力。常见的正则化层有以下几种:

  1. 批量归一化(Batch Normalization)

    • 功能:在网络的每一个批次数据通过激活函数前,对数据进行标准化处理(即减去均值,除以标准差),使得输出数据更加稳定,加快训练速度,提高模型的收敛速率。
    • 使用场景:通常用在全连接层或卷积层与激活层之间。
  2. 层归一化(Layer Normalization)

    • 功能:与批量归一化类似,但是层归一化不是对批次的特征进行标准化,而是对单个样本中的所有特征进行归一化。这使得层归一化不依赖于批次大小,适用于不稳定批次大小或很小批次的场景。
    • 使用场景:常用在循环神经网络(RNN)中,也可以用在变换器(Transformer)模型中。
  3. Dropout

    • 功能:在训练过程中随机地将网络中的部分权重或激活输出置零,这种随机性帮助减少模型对训练数据的依赖,从而减轻过拟合。
    • 使用场景:可以用在各种类型的网络中,如全连接层、卷积层等。
  4. 权重衰减(L2正则化)

    • 功能:通过在损失函数中添加一项与权重的平方成正比的惩罚项,促使模型学习到更小、更分散的权重值,有助于防止模型过于复杂导致过拟合。
    • 使用场景:通常用于全连接层或卷积层的参数训练中。

这些正则化技术在PyTorch中往往通过在模型定义中添加相应的层或在损失函数中增加额外的项来实现。使用这些方法可以显著提升模型在实际应用中的表现和鲁棒性。

九. transformer 层

1. 介绍

Transformer层是Transformer模型的基本组成部分之一,用于处理序列数据。Transformer模型由多个Transformer层组成,每个Transformer层又由多个子层组成,包括自注意力机制层和前馈神经网络层。

一个标准的Transformer层通常包含以下两个子层:

  1. 自注意力机制层(Self-Attention Layer):这个层允许模型在序列中建立全局依赖关系,即在序列中的每个位置上,模型都能够同时考虑到序列中其他位置的信息。通过计算每个位置与其他位置的相关性得分,自注意力机制可以捕捉序列中不同位置之间的依赖关系。

  2. 前馈神经网络层(Feedforward Neural Network Layer):这个层通常由两个线性层组成,中间经过一个非线性激活函数(如ReLU),用于对每个位置的特征进行非线性变换。这有助于模型学习更复杂的序列表示。

Transformer层的核心思想是通过多头自注意力机制来捕捉序列中的全局依赖关系,并通过前馈神经网络层来进行局部特征的变换和提取。这种结构使得Transformer模型能够有效地处理不同长度的序列数据,并在自然语言处理等任务中取得了显著的成功。

十. 序列 SEQUENTIAL

1. 介绍

在PyTorch中,SEQUENTIAL是一个容器类,它允许将多个层或操作按顺序组合在一起,形成一个神经网络模型。SEQUENTIAL的作用是简化模型的定义和管理。

具体来说,SEQUENTIAL可以用来定义一个由多个层组成的神经网络模型。通过将不同的层按顺序添加到SEQUENTIAL容器中,可以按照特定的顺序依次应用这些层来处理输入数据。

使用SEQUENTIAL的主要好处是简化了模型定义的过程。通过将层按顺序添加到SEQUENTIAL中,可以避免手动定义每个层的输入和输出,以及手动管理层之间的连接。SEQUENTIAL会自动处理这些细节,使得模型定义更加简洁和易于管理。

2. 示例

dilation默认是1,stride默认是1

根据以上流程,创建类并设计流程执行操作

直观写法,把各步骤都写一遍

class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.conv1 = Conv2d(3, 32, 5, padding=2)
        self.maxpool1 = MaxPool2d(2)
        self.conv2 = Conv2d(32, 32, 5, padding=2)
        self.maxpool2 = MaxPool2d(2)
        self.conv3 = Conv2d(32, 64, 5, padding=2)
        self.maxpool3 = MaxPool2d(2)
        self.flatten = Flatten()
        self.linear1 = Linear(1024, 64)
        self.linear2 = Linear(64, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.maxpool1(x)
        x = self.conv2(x)
        x = self.maxpool2(x)
        x = self.conv3(x)
        x = self.maxpool3(x)
        x = self.flatten(x)
        x = self.linear1(x)
        x = self.linear2(x)
        return x

测试

yk = Yk()
print(yk)
input = torch.ones((64, 3, 32, 32))
output = yk(input)
print(output.shape)

打印

使用squential简化操作

class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x

测试相同

yk = Yk()
print(yk)
input = torch.ones((64, 3, 32, 32))
output = yk(input)
print(output.shape)

打印

可将model展现在Tensorboard

十一. 损失函数和反向传播

在PyTorch中,损失函数和反向传播是神经网络训练的两个核心概念。

1. 损失函数

损失函数(Loss Function),也称为目标函数,是用来衡量模型的预测值与真实值之间差异的指标。它是一个非负实数,损失函数的值越小,表示模型的预测结果与真实结果越接近,模型的性能也就越好,并为我们的更新输出提供一定的依据(反向传播)。PyTorch提供了多种内置的损失函数,常用的有:

  1. 均方误差损失(MSE Loss) - 用于回归任务,计算预测值与真实值之间差的平方的平均值。

    import torch.nn as nn mse_loss = nn.MSELoss()
  2. 交叉熵损失(Cross Entropy Loss) - 用于分类任务,特别是多类分类问题。

    ce_loss = nn.CrossEntropyLoss()
  3. 二元交叉熵损失(Binary Cross Entropy Loss) - 用于二分类问题。

    bce_loss = nn.BCELoss()
  4. L1损失(L1 Loss) - 用于回归任务,计算预测值与真实值之间的绝对差的平均值。

    l1_loss = nn.L1Loss()

2. 反向传播

反向传播(Backpropagation)是训练神经网络中最重要的算法之一,用于计算损失函数对网络参数的梯度。这个过程涉及三个步骤:

  1. 前向传播 - 数据通过网络进行传播,从输入层移动到输出层。

  2. 损失计算 - 在输出层计算预测值和真实值之间的损失。

  3. 反向传播 - 计算损失函数相对于网络参数的梯度,并使用这些梯度通过优化算法(如SGD、Adam等)来更新网络的权重。

在PyTorch中,反向传播可以简单地通过调用.backward()方法来自动完成。示例如下:

import torch

# 创建数据和标签
data = torch.randn(10, 3)
labels = torch.randn(10, 3)

# 定义模型
model = nn.Linear(3, 3)

# 前向传播
predictions = model(data)

# 计算损失
loss = mse_loss(predictions, labels)

# 反向传播
loss.backward()

# 更新模型参数
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
optimizer.step()

以上就是使用PyTorch进行模型训练时涉及到的损失函数和反向传播的基本过程。通过这些工具,我们可以有效地训练各种神经网络,进行各种机器学习任务。

3. 梯度下降

4. 示例

首先获取数据集,并使用dataloader获取,然后创建类,使用各层处理

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./data", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)


class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x

然后创建损失函数

loss = nn.CrossEntropyLoss()

循环测试,并在处理的最后加上反向传播

yk = Yk()
for data in dataloader:
    imgs, targets = data
    output = yk(imgs)
    result_loss = loss(output, targets)

加上反向传播

    result_loss.backward()

打印

    print(result_loss)

全部代码

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./data", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)


class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x


loss = nn.CrossEntropyLoss()
yk = Yk()
for data in dataloader:
    imgs, targets = data
    output = yk(imgs)
    result_loss = loss(output, targets)
    result_loss.backward()
    print(result_loss)

打印测试

十二. 优化器

在PyTorch中,优化器是实现梯度下降(及其变体)的核心组件之一,用于自动更新神经网络的权重和参数以最小化损失函数。PyTorch提供了多种内置优化器,每种优化器都适用于不同的应用场景和具有不同的数学属性。

1. 优化器的作用

优化器的主要作用是根据损失函数相对于网络参数的梯度来更新参数。它们执行以下步骤:

  1. 接收梯度:在模型的反向传播过程后,优化器将接收每个参数的梯度。
  2. 参数更新:根据特定的算法,优化器利用梯度信息来更新网络的权重。

2. 常用的PyTorch优化器

以下是PyTorch中几种常见的优化器:

(1)SGD(随机梯度下降)

  • 最基本的优化器,只要提供梯度和学习率,它就会更新参数。
  • 可选项如动量和权重衰减可以帮助缓解SGD的一些问题(如鞍点和局部最小值)

(2)Adam(Adaptive Moment Estimation)

  • 结合了动量和学习率自适应的优点,通常在很多深度学习应用中表现优异。
  • 维护每个参数的学习率,可以帮助更快地收敛。

(3)RMSprop

  • 类似于Adam,主要区别在于它使用平方梯度的移动平均来调整每个参数的学习率。
  • 适用于非平稳目标和非常噪声的问题。

(4)AdamW

  • 对Adam的修改,它对权重衰减进行了更合理的处理,这在不同的测试中有所改善。
  • 适用于需要正则化的任务,可以防止过拟合。

3. 使用优化器的流程

(1)介绍

在使用PyTorch进行模型训练时,通常的步骤包括:

  1. 定义模型和优化器。
  2. 在一个训练循环中:
    • 执行前向传播得到输出和损失。
    • 执行反向传播得到参数的梯度。
    • 调用优化器的step方法来更新模型的参数。
    • (可选)调用优化器的zero_grad()方法来清除之前的梯度,以避免累积。
for epoch in range(num_epochs):
    for data, target in dataloader:
        optimizer.zero_grad()  # 清除旧的梯度
        output = model(data)   # 前向传播
        loss = loss_function(output, target)  # 计算损失
        loss.backward()        # 反向传播,计算梯度
        optimizer.step()       # 更新参数

通过这些优化器,PyTorch使得神经网络的训练过程不仅更简单,还可以根据不同的应用需求选择最合适的优化算法。

(2)实例

先创建优化器,第一个参数为创建的类的参数,第二个参数为学习速率,然后每轮学习。先清除优化器中保存的上一次迭代的梯度信息,以便进行下一次迭代的梯度更新。计算损失函数对模型参数的梯度,并将梯度信息保存在各个参数的.grad属性中。这一步是通过反向传播算法实现的。根据上一步计算得到的梯度信息,更新模型参数,使损失函数值减小。这一步是通过优化器(如SGD、Adam等)实现的。

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./data", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)


class Yk(nn.Module):
    def __init__(self):
        super(Yk, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x


loss = nn.CrossEntropyLoss()
yk = Yk()
optim = torch.optim.SGD(yk.parameters(), lr=0.01)
for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
        imgs, targets = data
        output = yk(imgs)
        result_loss = loss(output, targets)
        optim.zero_grad()
        result_loss.backward()
        optim.step()
        running_loss = result_loss + running_loss
    print(running_loss)

打印结果

可见损失值逐次减小。

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

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

相关文章

Web3解密:理解去中心化应用的核心原理

引言 在当前数字化时代,去中心化技术和应用正在逐渐引起人们的关注和兴趣。Web3技术作为去中心化应用(DApps)的基础,为我们提供了一个全新的互联网体验。但是,对于许多人来说,这个复杂的概念仍然充满了神秘…

【源码】WBF多语言交易所/申购+自发币平台币+币币+杠杆+合约/附带安装教程/带VUE工程源码

【源码介绍】 WBF多语言交易所/申购自发币平台币币币杠杆合约/附带安装教程/带VUE工程源码 【源码说明】 带VUE工程源码最新申购,自发币平台币,币币,法币,杠杆,合约多语言交易所,附带pc和手机VUE&#x…

Grafana系列 | Grafana监控TDengine库数据 |Grafana自定义Dashboard

开始前可以去grafana官网看看dashboard文档 https://grafana.com/docs/grafana/latest/dashboards 本文主要是监控TDengine库数据 目录 一、TDengine介绍二、Grafana监控TDengine数据三、Grafana自定义Dashboard 监控TDengine库数据1、grafana 变量2、添加变量3、配置panel 一…

CasinoRoyale靶机练习实践报告

CasinoRoyale靶机练习实践报告 下载地址: https://drive.google.com/open?id1FYP246L63zShV00wOckAQ5F5XJ4HkZ0Lhttps://download.vulnhub.com/casinoroyale/CasinoRoyale.ovahttps://download.vulnhub.com/casinoroyale/CasinoRoyale.ova.torrent ( Magnet) 1 安装靶机 …

乘数而上,创邻科技入选2024数商典型应用场景“乘数榜”

4月18日,由浙江省科学技术协会指导的2024未来数商大会在杭州成功举办。本次大会以“场景突破 乘数而上”为主题,国际国内数商共聚未来科技城学术交流中心,聚焦数据要素市场的制度创新、数据治理、场景应用与生态构建等话题展开研讨。 大会现…

【算法刷题 | 贪心算法04】4.26(跳跃游戏、跳跃游戏||)

文章目录 6.跳跃游戏6.1题目6.2解法:贪心6.2.1贪心思路6.2.2代码实现 7.跳跃游戏||7.1题目7.2解法:贪心7.2.1贪心思路7.2.2代码实现 6.跳跃游戏 6.1题目 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你…

数据分析:宏基因组分析-从Raw data到profile的简单流程

简介 该宏基因组流程主要有四步,分别是1.检查raw data;2.获得高质量reads;3.合并PE数据;4. reads map到参考数据库得到profile。 初步想法: 先分别撰写每一步的基础脚本,如过滤,mapping等过程…

HarmonyOS实战开发-如何在鸿蒙开发中使用数据库

鸿蒙中的数据库基于SQLite组件,用来处理关系比较复杂的数据,本文将以WORKER表为例,为大家演示在鸿蒙开发中对数据库的增删改查操作。 1、首先导入数据库模块: import relationalStore from ohos.data.relationalStore;2、配置数…

Linux平台Unity下RTMP|RTSP低延迟播放器技术实现

技术背景 国产操作系统对于确保信息安全、促进技术创新、满足特定需求以及推动经济发展等方面都具有重要意义,多以Linux为基础二次开发。2014年4月8日起,美国微软公司停止了对Windows XP SP3操作系统提供支持,这引起了社会和广大用户的广泛关…

从零入门区块链和比特币(第二期)

欢迎来到我的区块链与比特币入门指南!如果你对区块链和比特币感兴趣,但不知道从何开始,那么你来对地方了。本博客将为你提供一个简明扼要的介绍,帮助你了解这个领域的基础知识,并引导你进一步探索这个激动人心的领域。…

四:物联网ARM开发

一:ARM体系结构概述 1:控制外设led灯还有一些按键这些就要用到gpio,采集传感器的数据需要adc进行转化数据格式,特殊的外设和传感器是通过特殊的协议接口去进行连接的比如一些轴传感器和主控器的连接是通过spi,IIC 控制…

Python+Django网站指纹信息侦测探查

程序示例精选 PythonDjango网站指纹信息侦测探查 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《PythonDjango网站指纹信息侦测探查》编写代码,代码整洁,规则&#…

Docker与Linux容器:“探索容器化技术的奥秘”

目录 一、Docker概述 二、容器技术的起源: 三、Linux容器 四、Docker的出现 五、Docker容器特点: 六、Docker三大概念: 容器: 镜像: 仓库: 七、Docker容器常用命令 一、Docker概述 在云原生时代&…

玩机进阶教程------高通刷机 纯adb脚本操作刷写分区 备份分区的一些简单操作步骤解析

目前来说大多数刷机平台都是使用官方提供的工具。但一般这类工具刷写校验较多。例如小米刷机平台miflash和高通qpst平台。都对于电脑系统刷写环境有一定的要求。而且平台刷写校验md5等等。虽然可以通过修改脚本去除类似校验。但还是有必要了解一些纯adb脚本来刷写9008固件的方法…

智能变频三模正弦波控制器

智能变频三模正弦波控制器 前言一、图片介绍总结 前言 不敢动,完全不敢动。多做笔记,完全了解之后再说吧 一、图片介绍 轮毂电机 主角登场 淘宝关于这款控制器的介绍 当然不同的型号功能不同 学习线插上就会转,可以使用继电器控制通断。 电门…

[论文阅读] 3D感知相关论文简单摘要

Adaptive Fusion of Single-View and Multi-View Depth for Autonomous Driving 提出了一个单、多视图融合深度估计系统,它自适应地集成了高置信度的单视图和多视图结果 动态选择两个分支之间的高置信度区域执行融合 提出了一个双分支网络,即一个以单…

本地生活服务平台哪家强,怎么申请成为服务商?

当下,本地生活服务已经成为了多家互联网大厂布局的重要板块,在巨大的市场需求和强大的资本加持下,不少人都看到了本地生活服务平台广阔的前景和收益空间。在此背景下,许多普通人都跃跃欲试,想要成为本地生活服务商&…

Spark AQE 导致的 Driver OOM问题

背景 最近在做Spark 3.1 升级 Spark 3.5的过程中,遇到了一批SQL在运行的过程中 Driver OOM的情况,排查到是AQE开启导致的问题,再次分析记录一下,顺便了解一下Spark中指标的事件处理情况 结论 SQLAppStatusListener 类在内存中存…

怎么用PHP语言实现远程控制电器

怎么用PHP语言实现远程控制电器呢? 本文描述了使用PHP语言调用HTTP接口,实现控制电器,通过控制电器的电源线路来实现电器控制。 可选用产品:可根据实际场景需求,选择对应的规格 序号设备名称厂商1智能WiFi通断器AC3统…

Vue从0-1学会如何自定义封装v-指令

文章目录 介绍使用1. 理解指令2. 创建自定义指令3. 注册指令4. 使用自定义指令5. 自定义指令的钩子函数6. 传递参数和修饰符7. 总结 介绍 自定义封装 v-指令是 Vue.js 中非常强大的功能之一,它可以让我们扩展 Vue.js 的模板语法,为 HTML 元素添加自定义行…