• Pytorch学习整理笔记(二)



    损失函数与反向传播

    常见的损失函数:
    nn.L1Loss简单的做差值,nn.MSELoss平方差,nn.CrossEntropyLoss交叉熵见下图

    在这里插入图片描述

    import torch
    from torch.nn import L1Loss, MSELoss, CrossEntropyLoss
    
    inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
    target = torch.tensor([1, 2, 5], dtype=torch.float32)
    
    loss = L1Loss()  # 计算差值的绝对值之和 的 均值(默认,可修改reduction)
    result = loss(inputs, target)
    print(result)  # tensor(0.6667)
    
    
    # 平方差
    loss_mse = MSELoss()
    result_mse = loss_mse(inputs, target)
    print(result_mse)
    
    # 交叉熵——分类问题
    x = torch.tensor([0.1, 0.2, 0.3])  # 预测输出的概率
    y = torch.tensor([1])  # 真实的下标数据
    # 调整数据格式(N, C)
    x = torch.reshape(x, (1, 3))
    loss_cross = CrossEntropyLoss()
    result_cross = loss_cross(x, y)
    print(result_cross)
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    输出:

    tensor(0.6667)
    tensor(1.3333)
    tensor(1.1019)
    
    • 1
    • 2
    • 3

    具体使用:

    import torchvision.datasets
    from torch import nn
    from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
    from torch.utils.data import DataLoader
    
    dataset = torchvision.datasets.CIFAR10("./data", train=False,
                                           transform=torchvision.transforms.ToTensor(),
                                           download=True)
    dataloader = DataLoader(dataset, batch_size=1)
    
    
    class NN(nn.Module):
        def __init__(self):
            super(NN, self).__init__()
            self.model1 = Sequential(
                Conv2d(3, 32, kernel_size=5, stride=1, padding=2),
                MaxPool2d(2),
                Conv2d(32, 32, kernel_size=5, stride=1, padding=2),
                MaxPool2d(2),
                Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
                MaxPool2d(2),
                Flatten(),
                Linear(1024, 64),
                Linear(64, 10)
            )
    
        def forward(self, x):
            x = self.model1(x)
            return x
    
    
    loss = nn.CrossEntropyLoss()
    nnn = NN()
    for data in dataloader:
        imgs, targets = data
        outputs = nnn(imgs)
        result_loss = loss(outputs, targets)
        # result_loss.backward()  # 是对求出来的loss求梯度gard 对应的参数
        print(result_loss)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    优化器

    官方文档:https://pytorch.org/docs/stable/optim.html
    主要搭配我们的反向传播backward()进行使用
    在这里插入图片描述params:传入的模型参数
    lr参数:学习速率

    import torch.optim
    import torchvision.datasets
    from torch import nn
    from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
    from torch.utils.data import DataLoader
    
    dataset = torchvision.datasets.CIFAR10("./data", train=False,
                                           transform=torchvision.transforms.ToTensor(),
                                           download=True)
    dataloader = DataLoader(dataset, batch_size=1)
    
    
    class NN(nn.Module):
        def __init__(self):
            super(NN, self).__init__()
            self.model1 = Sequential(
                Conv2d(3, 32, kernel_size=5, stride=1, padding=2),
                MaxPool2d(2),
                Conv2d(32, 32, kernel_size=5, stride=1, padding=2),
                MaxPool2d(2),
                Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
                MaxPool2d(2),
                Flatten(),
                Linear(1024, 64),
                Linear(64, 10)
            )
    
        def forward(self, x):
            x = self.model1(x)
            return x
    
    
    loss = nn.CrossEntropyLoss()
    nnn = NN()
    optim = torch.optim.SGD(params=nnn.parameters(), lr=0.01)  # 随机梯度下降优化器
    for epoch in range(20):  # 多轮学习训练
        running_loss = 0.0
        for data in dataloader:
            imgs, targets = data
            outputs = nnn(imgs)
            result_loss = loss(outputs, targets)
            optim.zero_grad()  # 梯度清0
            result_loss.backward()  # 反向传播
            optim.step()  # 对参数进行调优
            running_loss += result_loss
        print(running_loss)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    在这里插入图片描述


    VGG模型使用与修改

    https://pytorch.org/vision/stable/models.html

    在这里插入图片描述提前安装scipy 包,在anaconda所在的环境下

    pip install scipy -i https://pypi.tuna.tsinghua.edu.cn/simple/
    
    • 1

    数据集太大,暂时放弃测试
    补充如何修改原有的torchvision.models里面的模型

    import torchvision.datasets
    from torch import nn
    vgg16 = torchvision.models.vgg16(weights=None)
    
    # print(vgg16)
    
    # vgg16.classifier.add_module("add_linear", nn.Linear(1000, 10))  # classifier层添加一个线性处理
    vgg16.classifier[6] = nn.Linear(4096, 10)  # 将classifier层的下标为6的处理进行修改
    
    print(vgg16)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    vgg模型原有的架构:
    在这里插入图片描述添加线性层
    在这里插入图片描述修改原有的层:
    在这里插入图片描述


    模型保存与读取

    方式1:
    在这里插入图片描述方式2:
    在这里插入图片描述具体代码:
    保存

    import torch
    import torchvision.models
    
    vgg16 = torchvision.models.vgg16(weights=None)  # weights=("pretrained") 默认参数是经过训练的
    
    #  保存1 : 网络模型结构+参数
    # torch.save(vgg16, "vgg16_method1.pth")
    
    #  保存2: 网络结构的参数保存成字典state_dict,只保存了参数
    torch.save(vgg16.state_dict(), "vgg16_method2.pth")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    读取:

    import torch
    import torchvision.models
    
    # 与保存1对应的读取
    # model = torch.load("vgg16_method1.pth")
    # print(model)
    
    # 与保存2对应:需要先恢复网络结构
    vgg16 = torchvision.models.vgg16(weights=None)
    vgg16.load_state_dict(torch.load("vgg16_method2.pth"))  # 加载保存的字典
    # model = torch.load("vgg16_method2.pth")
    print(vgg16)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    保存2是官方推荐的,保存1虽然同时保存了网络结构和参数,但有时存在一定问题,如下:

    import torch
    from torch import nn
    
    class NNN(nn.Module):
        def __init__(self):
            super(NNN, self).__init__()
            self.conv1 = nn.Conv2d(3, 64, kernel_size=3)
    
        def forward(self, x):
            x = self.conv1(x)
            return x
    
    
    nnn = NNN()
    torch.save(nnn, "NNN_method1.pth")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    读取时会报错:这个结构不存在
    在这里插入图片描述引入这个结构才能正常运行:
    在这里插入图片描述


  • 相关阅读:
    2022前端面试题上岸手册-HTML+CSS部分
    mysql中的加密函数以及在高版本中被移除的加密函数
    lvm删除分区、扩容分区
    【机器学习技巧】如何快速对离散型数据进行编码: LabelEncoder的使用方法
    【操作系统】内存管理(四)—— 内存的分配与回收(2)
    Jmeter(八):jmeter接口自动化测试操作流程、计数器、定时器详解
    git 命令怎么回退到指定的某个提交 commit hash 并推送远程分支?
    【论文精读3】CasMVSNet
    LeetCode 961. N-Repeated Element in Size 2N Array
    虚拟内存地址和物理内存地址?为什么我们程序里地址连续?为什么需要TLB Translation lookaside buffer
  • 原文地址:https://blog.csdn.net/qq_43466788/article/details/132892309