• 【深度学习入门】PyTorch基础


    PyTorch是一款基于自动微分且越来越流行的神经网络框架。

    核心数据类型Tensor

    首先,手动初始化Tensor:

    a = torch.Tensor([[3., 3.],
                      [3., 3.]], requires_grad=True)
    
    • 1
    • 2
    • 像处理ndarray一样,可以通过将其中包含的数据简单地包装在torch.Tensor中来初始化Tensor。
    • 当用这种方式初始化Tensor时,必须传递require_grad = True的参数,来告诉Tensor累积梯度。

    执行计算:

    b = a * 4
    c = b + 3
    d = (a + 2)
    e = c * d
    e_sum = e.sum()
    e_sum.backward()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如示例,一旦对计算的输出调用backward方法,就可以自动正确计算梯度。

    使用PyTorch进行深度学习

    • 一个Model类,其中包含Layer类
    • 一个Optimizer类
    • 一个Loss类
    • 一个Trainer类

    Model类及其Layer类

    PyTorchLayer类可以写成如下形式:

    from torch import nn, Tensor
    
    class PyTorchLayer(nn.Module):
        
        def __init__(self) -> None:
            super().__init__()
        
        def forward(self, x: Tensor,
                    inference: bool = False) -> Tensor:
            raise NotImplementedError()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    PyTorchModel类可以写成如下形式:

    class PyTorchModel(nn.Module):
    
        def __init__(self) -> None:
            super().__init__()
    
        def forward(self, x: Tensor,
                    inference: bool = False) -> Tensor:
            raise NotImplementedError()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    PyTorchLayer类和PyTorchModel类的每个子类都只需要实现__init__()方法和forward()方法,以便直接使用它们。

    dropout技术

    dropout技术可以改变神经网络的容量,并降低发生过拟合的可能性。
    dropout只是简单地在一层中随机选择一定比例的神经元p,并在每次前向传递训练中将它们设置为0。
    Dropout类具有两种模式:应用了dropout的训练模式和没有应用dropout的推理模式。

    inference标志位

    在PyTorch中,可以通过在模型或层(或任何从nn.Module类中继承的对象)上运行m.eval,从而将模型或层从默认的训练模式切换到推理模式。
    使用apply函数快速更改层的所有子类的行为:

    def inference_mode(m: nn.Module):
        m.eval()
    
    • 1
    • 2

    在定义的PyTorchLayer类和PyTorchModel类的每个子类的forward方法中都包含如下代码,从而获得预期的标志位:

    if inference:
    	self.apply(inference_mode)
    
    • 1
    • 2

    基本要素:DenseLayer类

    神经元层的一个关键特征是,每个输出神经元都是所有输入神经元的函数。
    每一个新特征都是所有 n i n n_{in} nin个输入特征的加权线性组合,因此这些层通常称为全连接层(fully connected layer),在Keras库中,它们也被称为Dense层。

    class DenseLayer(PyTorchLayer):
        def __init__(self,
                     input_size: int,
                     neurons: int,
                     dropout: float = 1.0,
                     activation: nn.Module = None) -> None:
            super().__init__()
            self.linear == nn.Linear(input_size, neurons)
            self.activation = activation
            if dropout < 1.0:
                self.dropout = nn.Dropout(1 - dropout)
    
                def forward(self, x: Tensor,
                            inference: bool = False) -> Tensor:
                    if inference:
                        self.apply(inference_mode)
    
                    x = self.linear(x)  # does weight multiplication + bias
                    if self.activation:
                        x = self.activation(x)
                    if hasattr(self, "dropout"):
                        x = self.dropout(x)
    
                    return x
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    nn.Linear对象不仅在前向传递中处理权重乘积和增加偏差项,还会累积x的梯度,从而在后向传递中正确计算出损失相对于参数的导数。

    DataLoader类和transforms模块

    可以对数据应用一个简单的预处理步骤,即减去总体均值并除以标准偏差,从而对数据集进行大致的归一化:

    X_train, X_test = X_train - X_train.mean(), X_test - X_test.mean()
    X_train, X_test = X_train / X_train.std(), X_test / X_test.std()
    
    • 1
    • 2

    在这之前,需要将这两个数组完全读入内存。
    在神经网络中,随着批量数据的输入,动态执行此预处理步骤将更加高效。
    PyTorch的一些内置功能可以执行此操作,比如通过transforms模块执行转换,以及通过torch.utils.data引入DataLoader类:

    import torchvision.transforms as transforms
    from torch.utils.data import DataLoader
    
    • 1
    • 2

    首先,定义一个转换列表,对读取的每一批数据执行转换操作。

    my_transforms = transforms.Compose([
        transforms.ToTensor,
        transforms.Normalize((0.1305,), (0.3081,))
    ])
    
    • 1
    • 2
    • 3
    • 4

    接着,定义DataLoader类来接收此数据集,并定义用于生成批量数据的规则:

    dataloader = DataLoader(dataset, batch_size=60, shuffle=True)
    
    • 1
  • 相关阅读:
    【luckfox】3、计算重量差
    2205. The Number of Users That Are Eligible for Discount0
    css加载动画
    代码随想录二刷7.22|977.有序数组的平方
    PPI数据集分析
    SpringBoot使用spring.config.import多种方式导入配置文件
    Vue3-ref、reactive函数的watch
    Nuxt框架的3.6.0版本以上项目运行新增loading
    音视频技术在手机上的应用与挑战
    学习计划&&计划执行记录
  • 原文地址:https://blog.csdn.net/GW_Krystal/article/details/125513373