• Pytorch-学习记录-1-Tensor


    1. 张量 (Tensor):

    数学中指的是多维数组

    torch.Tensor

    data: 被封装的 Tensor
    dtype: 张量的数据类型
    shape: 张量的形状
    device: 张量所在的设备,GPU/CPU
    requires_grad: 指示是否需要计算梯度
    grad: data 的梯度
    grad_fn: 创建 Tensor 的 Function,是自动求导的关键
    is_leaf: 指示是否是叶子结点 (叶子结点指的是用户创建的节点,比如 y=(x+w)*(w+1)中,x和w就是叶子结点【可以用计算图来清楚地表示该过程】)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2. 创建张量:

    2.1 直接创建:

    2.1.1 从 data 创建 tensor

    data: 可以是 list, numpy
    dtype: 数据类型,默认与data一致
    device: 所在设备
    requires_grad: 是否需要梯度
    pin_memory: 是否存于锁页内存
    
    • 1
    • 2
    • 3
    • 4
    • 5
    # 创建方法
    torch.tensor(
        data,
        dtype=None,
        device=None,
        requires_grad=False,
        pin_memory=False
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.1.2 从 numpy 创建 tensor

    torch.from_numpy()创建的tensor与原始的ndarray共享内存,修改其中一个,另一个也会变。

    # 创建方法
    torch.from_numpy(ndarray)
    
    • 1
    • 2
    # 举例
    import torch
    import numpy as np
    
    # 直接创建
    ## torch.tensor()
    arr = np.ones((3,3))
    t = torch.tensor(arr, 
                     dtype=torch.float32, 
                     device="mps") # 把张量放到 GPU 上 (mac M1)
    
    print(t.dtype)
    print(t)
    
    
    ## torch.from_numpy()
    arr = np.array([[1,2,3],[4,5,6]])
    t = torch.from_numpy(arr)
    print(t.dtype)
    print(t)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    torch.float32
    tensor([[1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.]], device='mps:0')
    torch.int64
    tensor([[1, 2, 3],
            [4, 5, 6]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.2 根据数值进行创建:

    2.2.1 torch.zeros()

    创建全0张量

    size: 张量的形状
    out: 输出的张量 (暂时可以不考虑)
    layout:内存中布局形式,有 strided (通常情况下使用), sparse_coo (读取稀疏矩阵会用到)
    device: 所在设备
    requires_grad: 是否需要梯度
    
    • 1
    • 2
    • 3
    • 4
    • 5
    # 创建方法
    torch.zeros(
        *size,
        out=None,
        dtype=None,
        layout=torch.strided,
        device=False,
        requires_grad=False
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.2.2 torch.zeros_lisk()

    根据 input 形状创建全0张量

    input: 创建与 input 同形状的张量;
    dtype: 数据类型;
    layout: 内存中的布局形式;
    
    • 1
    • 2
    • 3
    # 创建方法
    torch.zeros_like(
        input,
        dtype=None,
        layout=None,
        device=None,
        requires_grad=False
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.2.3 torch.ones()torch.ones_like()

    创建全1张量

    2.2.4 torch.full()torch.full_like()

    创建自定义数值的张量

    size: 张量形状
    fill_value: 张量的值
    
    • 1
    • 2

    2.2.5 torch.arange()

    根据数列创建等差1维张量,[start, end)

    start: 起始值
    end: 结束值
    step: 数列公差,默认为1
    
    • 1
    • 2
    • 3

    2.2.6torch.linspace()

    创建均分的1维张量,[start, end]

    start: 起始值
    end: 结束值
    step: 数列长度
    
    • 1
    • 2
    • 3

    2.2.7torch.logspace()

    创建对数均分的1D张量

    start: 起始值
    end: 结束值
    steps: 数列长度
    base: 对数函数的底,默认为10
    
    • 1
    • 2
    • 3
    • 4
    # 创建方法
    torch.logspace(
        start,
        end,
        steps=100,
        base=10.0,
        out=None,
        dtype=None,
        layout=torch.strided,
        deivce=None,
        requires_grad=False
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.2.8 torch.eye()

    创建单位对角矩阵 (2D张量)

    n: 矩阵行数
    m: 矩阵列数
    
    • 1
    • 2
    # 创建方法
    torch.eye(
        n,
        m=None,
        out=None,
        dtype=None,
        layout=torch.strided,
        device=None,
        requires_grad=False
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    # 举例
    t = torch.zeros((3,3))
    print(t.dtype)
    print(t)
    
    t = torch.full((3,3),2) # 创建3x3的全2张量
    print(t)
    
    t = torch.arange(2, 8, 2)
    print(t)
    
    t = torch.linspace(2, 10, 5)
    print(t)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    torch.float32
    tensor([[0., 0., 0.],
            [0., 0., 0.],
            [0., 0., 0.]])
    tensor([[2, 2, 2],
            [2, 2, 2],
            [2, 2, 2]])
    tensor([2, 4, 6])
    tensor([ 2.,  4.,  6.,  8., 10.])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.3 根据概率分布创建张量:

    2.3.1 torch.normal()

    生成正态分布(高斯分布)

    四种模式:

    mean标量std标量
    mean标量std张量
    mean张量std标量
    mean张量std张量
    # 张量
    torch.normal(
        mean,
        std,
        out=None
    )
    
    # 标量
    torch.normal(
        mean,
        std,
        size,
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.3.2 torch.randn(), torch.randn_like()

    生成标准正态分布

    torch.randn(
        *size, ## 张量形状
        out=None,
        dtype=None,
        layout=torch.strided,
        device=None,
        requires_grad=False
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.3.3 torch.rand(), torch.rand_like()

    在[0,1)区间上生成均匀分布

    torch.rand(
        *size, ## 张量形状
        out=None,
        dtype=None,
        layout=torch.strided,
        device=None,
        requires_grad=False
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.3.4 torch.randint(), torch.randint_like()

    在 [low, high) 区间上生成整数均匀分布

    torch.randint(
        low,
        high,
        size,
        out=None,
        dtype=None,
        layout=torch.strided,
        device=None,
        requires_grad=False
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.3.5 torch.randperm()

    生成0到n-1的随机排列

    n: 张量长度
    
    • 1
    torch.randperm(
        n,
        out=None,
        dtype=torch.int64,
        layout=torch.strided,
        device=None,
        requires_grad=False
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.3.6torch.bernoulli()

    以 input 为概率,生成伯努利分布(0-1分布,两点分布)

    torch.bernoulli(
        input,
        *,
        generator=None,
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. 张量的操作:

    张量的操作:拼接、切分、索引和变换:

    1. 拼接:

    1.1 torch.cat()

    将张量按维度 dim 进行拼接 (不回扩张张量维度)

    torch.cat(
        tensors, ## 张量序列
        dim, ## 要拼接的维度
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.2 torch.stack()

    在新创建的维度 dim 上进行拼接 (会扩张张量的维度)

    torch.stack(
        tensors, ## 张量序列
        dim=0, ## 要拼接的维度
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    import torch
    
    t = torch.ones((2,3))
    
    # torch.cat()
    t1 = torch.cat([t,t], dim=0) ## 按照 dim=0 对t进行拼接,得到(4,3)
    
    # torch.stack()
    t2 = torch.stack([t,t], dim=0) ## 按照 dim=0 对t进行拼接,得到(2,2,3),会在dim=0创建一个新维度
    
    print("t1 shape: ", t1.shape)
    print("t2 shape: ", t2.shape)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    t1 shape:  torch.Size([4, 3])
    t2 shape:  torch.Size([2, 2, 3])
    
    • 1
    • 2

    2. 切分

    2.1 torch.chunk()

    将张量按照维度 dim 进行平均切分,返回张量列表 (如果不能整除,最后一份张量小于其他张量)

    torch.chunk(
        input, ## 要切分的张量
        chunks, ## 要切分的份数
        dim=0 ## 要切分的维度
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.2 torch.split()

    将张量按照维度 dim 进行切分,返回张量列表

    torch.split(
        tensor, ## 要切分的张量
        split_size_of_sections, ## 为 int 时,表示每一份的长度;为 list 时,按 list 元素切分
        dim=0 ## 要切分的维度
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    t1 = torch.ones((2,5))
    
    # torch.chunk()
    list_of_tensors = torch.chunk(t1, dim=1, chunks=2) ## 5不能被2整除,所以最后一个张量形状小雨前面的张量
    for idx, t in enumerate(list_of_tensors):
        print("order {}, shape is {}".format(idx+1, t.shape))
    
    # torch.split()
    list_of_tensors = torch.split(t1, [2,1,2], dim=1)
    for idx, t in enumerate(list_of_tensors):
        print("order {}, shape is {}".format(idx+1, t.shape))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    order 1, shape is torch.Size([2, 3])
    order 2, shape is torch.Size([2, 2])
    order 1, shape is torch.Size([2, 2])
    order 2, shape is torch.Size([2, 1])
    order 3, shape is torch.Size([2, 2])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3. 索引

    3.1 torch.index_select()

    在维度 dim 上,按照 index 索引数据,返回依index索引数据拼接的张量 (先索引,再拼接)

    torch.index_select(
        input, ## 要索引的张量
        dim, ## 要索引的维度
        index, ## 要索引数据的序号,数据类型必须是 torch.long
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.2 torch.masked_select()

    按照 mask 中的 True 进行索引,返回一维张量

    torch.masked_select(
        input,
        mask, ## 与 input 同形状的布尔类型张量
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    # torch_index_select()
    t = torch.randint(0,9,size=(3,3))
    idx = torch.tensor([0,2],dtype=torch.long)
    t_select = torch.index_select(t, dim=1, index=idx)
    print(t)
    print(t_select)
    
    # torch.masked_select()
    mask = t.ge(5) ## 表示张量中 >= 5的元素;ge()表示大于等于;gt()表示大于;le()表示小于等于;lt()表示小于
    t_select = torch.masked_select(t, mask=mask)
    print(t)
    print(mask)
    print(t_select)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    tensor([[3, 8, 1],
            [6, 0, 0],
            [7, 6, 8]])
    tensor([[3, 1],
            [6, 0],
            [7, 8]])
    tensor([[3, 8, 1],
            [6, 0, 0],
            [7, 6, 8]])
    tensor([[False,  True, False],
            [ True, False, False],
            [ True,  True,  True]])
    tensor([8, 6, 7, 6, 8])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4. 变换

    4.1 torch.reshape()

    变换张量形状 (张量在内存中是连续时,新张量与input共享数据内存)

    torch.reshape(
        input,
        shape ## 新张量的形状
    )
    
    • 1
    • 2
    • 3
    • 4

    4.2 torch.transpose()

    交换张量的两个维度

    torch.transpose(
        input,
        dim0,
        dim1
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.3 torch.t()

    2维张量转置

    torch.t(input)
    
    • 1

    4.4 torch.squeeze()

    压缩长度为1的维度

    torch.squeeze(
        input,
        dim=None, ## 若 dim=None,则移除所有长度为1的轴;若指定维度而且维度长度为1,则可以移除该维度
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.5 torch.unsqueeze()

    根据 dim 扩展维度

    torch.unsqueeze(
        input,
        dim,
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    ## torch.reshape
    
    t = torch.randperm(8)
    t_reshape = torch.reshape(t, (2,4)) ## 如果是 (-1,2,2),那么-1表示的是:不需要关心-1处的维度是多少,根据后两个维度进行计算得到(比如:这里就是 8/2/2 = 2,即-1处的维度是2)
    
    print(t.shape)
    print(t_reshape.shape)
    
    
    ## torch.transpose()
    t = torch.rand((2,3,4))
    t_transpose = torch.transpose(t, dim0=1, dim1=2) ## 把第1维和第2维进行交换
    print(t.shape)
    print(t_transpose.shape)
    
    
    ## torch.squeeze()
    t = torch.rand((1,2,3,1))
    t_squeeze = torch.squeeze(t)
    t_squeeze_0 = torch.squeeze(t,dim=0)
    t_squeeze_1 = torch.squeeze(t,dim=1)
    print(t_squeeze.shape)
    print(t_squeeze_0.shape)
    print(t_squeeze_1.shape)
    
    
    ## torch.unsqueeze()
    t = torch.rand((2,3))
    t_unsqueeze = torch.unsqueeze(t, dim=2)
    print(t_unsqueeze.shape)
    
    • 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
    torch.Size([8])
    torch.Size([2, 4])
    torch.Size([2, 3, 4])
    torch.Size([2, 4, 3])
    torch.Size([2, 3])
    torch.Size([2, 3, 1])
    torch.Size([1, 2, 3, 1])
    torch.Size([2, 3, 1])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.2 张量的数学运算:

    加减乘除

    torch.add()
    torch.addcdiv()
    torch.addcmul()
    torch.sub()
    torch.div()
    torch.mul()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    重点: torch.add()torch.addcmul()

    torch.add(): 逐元素计算 input + alpha x other

    torch.add(
        input, ## 第一个张量
        alpha=1, ## 乘项因子 (alpha x other + input)
        other, ## 第二个张量
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    torch.addcmul()

    out = input + value x tensor1 x tensor2

    torch.addcmul(
        input,
        value=1.
        tensor1,
        tensor2,
        out=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    对数、指数、幂函数

    torch.log(input, out=None)
    torch.log10(input, out=None)
    torch.log2(input, out=None)
    torch.exp(input, out=None)
    torch.pow()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三角函数

    torch.abs(input, out=None)
    torch.acos(input, out=None)
    torch.cosh(input, out=None)
    torch.cos(input, out=None)
    torch.asin(input, out=None)
    torch.atan(input, out=None)
    torch.atan2(input, other=None, out=None)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4. 计算图与动态图

    1. 计算图

    计算图是用来描述运算的有向无环图,包括两个主要元素:节点和边。节点表示数据(比如 向量、矩阵、张量);边表示运算(比如 加减乘除卷积等)。

    叶子结点:指的是由用户创建的节点,其他非叶子结点都是由叶子结点通过直接或间接的运算得到的。(之所以会有叶子结点的概念,是因为梯度反向传播结束后,只有叶子结点的梯度会被保留,非叶子结点的梯度会被从内存中释放掉。可以通过.is_leaf()方法查看是否为叶子结点)。

    如果想要使用非叶子结点的梯度,实现方法是 在计算梯度之后,用.retain_grad()方法保存非叶子结点的梯度。

    grad_fn: 记录创建该张量(非叶子结点)时所用的方法,比如 y=a*b,那么 y.grad_fn =

    2. 动态图

    计算图可以根据搭建方式的不同,分为:动态图 (运算与搭建同时进行,灵活,易调节,比如 pytorch) 和静态图 (先搭建,后运算,高效,不灵活,比如 tensorflow)。

    5. 自动求导系统 autograd

    1. torch.autograd.backward

    自动计算图中各个结点的梯度

    torch.autograd.backward(
        tensors, ## 用于求导的张量(比如 loss)
        grad_tensors=None, ## 多梯度权重
        retain_grap=None, ## 保存计算图
        create_graph=False ## 创建导数的计算图,同于高阶求导
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. torch.autograd.grad

    求取梯度

    torch.autograd.grad(
        outputs, ## 用于求导的张量 (比如 loss)
        inputs, ## 需要梯度的张量
        grad_outputs=None, ## 多梯度权重 
        retain_graph=None, ## 保存计算图
        create_graph=False ## 创建导数计算图,用于高阶求导
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3. Pytorch 自动求导系统中有3个需要注意的点:

    1. 梯度不自动清零 (手动清零 .grad.zero_());

    2. 依赖于叶子结点结点,requires_grad 默认为 True;

    3. 叶子结点不可执行 in-place,即叶子结点不能执行原位操作;

    4. 机器学习模型的5个训练步骤:

    数据, 模型, 损失函数, 优化器, 迭代训练

    6. DataLoader 与 Dataset

    数据
        数据收集
    
        数据划分
    
        数据读取
            DataLoader
                Sampler: 生成索引
                Dataset: 根据索引读取样本特征以及标签
    
        数据预处理
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1. torch.utils.data.DataLoader

    DataLoader(
        dataset, ## Dataset类,决定数据从哪里读取以及如何读取
        batch_size=1, ## 批量大小
        shuffle=False, ## 每个 epoch 是否打乱顺序
        sampler=None,
        batch_sampler=None,
        num_workers=0, ## 是否多进程读取数据
        collate_fn=None,
        pin_memory=False,
        drop_last=False, ## 当样本数不能被 batchsize 整除时,是否舍弃最后一批数据
        timeout=0,
        worker_init_fn=None,
        multiprocessing_context=None
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2. torch.utils.data.Dataset

    Dataset抽象类,所有自定义的Dataset都需要继承它,并且需要复写 __getitem__()方法;getitem:接收一个索引,返回一个样本。

    class Dataset(object):
        def __getitem__(self, index):
            raise NotImplementedError
    
        def __add__(self, other):
            return ConcatDataset([self, other])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Example: 猫狗图片分类 (“./example_week1_Cat_Dog_classification/”)

    1. 参考代码:https://github.com/JansonYuan/Pytorch-Camp/

    2. 猫狗数据集下载:https://www.kaggle.com/datasets/samuelcortinhas/cats-and-dogs-image-classification,但是将其中Test随机分成相等的两份,一份作为验证集,一份作为测试集(尽管测试集没有用到)。

    3. 代码在 “./example_week1_Cat_Dog_classification/” 目录下。

    4. 结果讨论:

    4.1 作者原来的代码的结果:

    在这里插入图片描述

    Training:Epoch[000/010] Iteration[010/010] Loss: 0.6204 Acc:60.62%
    Valid:	 Epoch[000/010] Iteration[002/002] Loss: 0.4436 Acc:90.00%
    Training:Epoch[001/010] Iteration[010/010] Loss: 0.3601 Acc:90.62%
    Valid:	 Epoch[001/010] Iteration[002/002] Loss: 0.0461 Acc:100.00%
    Training:Epoch[002/010] Iteration[010/010] Loss: 0.0788 Acc:98.12%
    Valid:	 Epoch[002/010] Iteration[002/002] Loss: 0.0234 Acc:100.00%
    Training:Epoch[003/010] Iteration[010/010] Loss: 0.0208 Acc:99.38%
    Valid:	 Epoch[003/010] Iteration[002/002] Loss: 0.0022 Acc:100.00%
    Training:Epoch[004/010] Iteration[010/010] Loss: 0.0042 Acc:100.00%
    Valid:	 Epoch[004/010] Iteration[002/002] Loss: 0.0018 Acc:100.00%
    Training:Epoch[005/010] Iteration[010/010] Loss: 0.0143 Acc:99.38%
    Valid:	 Epoch[005/010] Iteration[002/002] Loss: 0.0002 Acc:100.00%
    Training:Epoch[006/010] Iteration[010/010] Loss: 0.0220 Acc:98.75%
    Valid:	 Epoch[006/010] Iteration[002/002] Loss: 0.0004 Acc:100.00%
    Training:Epoch[007/010] Iteration[010/010] Loss: 0.0008 Acc:100.00%
    Valid:	 Epoch[007/010] Iteration[002/002] Loss: 0.0013 Acc:100.00%
    Training:Epoch[008/010] Iteration[010/010] Loss: 0.0083 Acc:99.38%
    Valid:	 Epoch[008/010] Iteration[002/002] Loss: 0.0001 Acc:100.00%
    Training:Epoch[009/010] Iteration[010/010] Loss: 0.0049 Acc:100.00%
    Valid:	 Epoch[009/010] Iteration[002/002] Loss: 0.0000 Acc:100.00%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    4.2 用 “./example_week1_Cat_Dog_classification/train_lenet.py” 代码处理 Pytorch-Camp 的结果和上面的是一致的(代码修改后,与 Pytorch-Camp 提供的代码可以对 RMB 实现同样的分类效果),如下所示:

    在这里插入图片描述

    Train:   Epoch[000/010] Iteration[010/010] Loss: 0.6204 Acc: 60.62%
    Valid:   Epoch[000/010] Iteration[002/002] Loss: 0.4436 Acc: 90.00%
    Train:   Epoch[001/010] Iteration[010/010] Loss: 0.3601 Acc: 90.62%
    Valid:   Epoch[001/010] Iteration[002/002] Loss: 0.0461 Acc: 100.00%
    Train:   Epoch[002/010] Iteration[010/010] Loss: 0.0788 Acc: 98.12%
    Valid:   Epoch[002/010] Iteration[002/002] Loss: 0.0234 Acc: 100.00%
    Train:   Epoch[003/010] Iteration[010/010] Loss: 0.0208 Acc: 99.38%
    Valid:   Epoch[003/010] Iteration[002/002] Loss: 0.0022 Acc: 100.00%
    Train:   Epoch[004/010] Iteration[010/010] Loss: 0.0042 Acc: 100.00%
    Valid:   Epoch[004/010] Iteration[002/002] Loss: 0.0018 Acc: 100.00%
    Train:   Epoch[005/010] Iteration[010/010] Loss: 0.0143 Acc: 99.38%
    Valid:   Epoch[005/010] Iteration[002/002] Loss: 0.0002 Acc: 100.00%
    Train:   Epoch[006/010] Iteration[010/010] Loss: 0.0220 Acc: 98.75%
    Valid:   Epoch[006/010] Iteration[002/002] Loss: 0.0004 Acc: 100.00%
    Train:   Epoch[007/010] Iteration[010/010] Loss: 0.0008 Acc: 100.00%
    Valid:   Epoch[007/010] Iteration[002/002] Loss: 0.0013 Acc: 100.00%
    Train:   Epoch[008/010] Iteration[010/010] Loss: 0.0083 Acc: 99.38%
    Valid:   Epoch[008/010] Iteration[002/002] Loss: 0.0001 Acc: 100.00%
    Train:   Epoch[009/010] Iteration[010/010] Loss: 0.0049 Acc: 100.00%
    Valid:   Epoch[009/010] Iteration[002/002] Loss: 0.0000 Acc: 100.00%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    4.3 将数据换成猫狗数据集之后,结果如下:

    在这里插入图片描述

    Train:   Epoch[000/010] Iteration[035/035] Loss: 0.7151 Acc: 53.50%
    Valid:   Epoch[000/010] Iteration[005/005] Loss: 0.6898 Acc: 51.43%
    Train:   Epoch[001/010] Iteration[035/035] Loss: 0.6954 Acc: 50.09%
    Valid:   Epoch[001/010] Iteration[005/005] Loss: 0.7321 Acc: 41.43%
    Train:   Epoch[002/010] Iteration[035/035] Loss: 0.6885 Acc: 53.86%
    Valid:   Epoch[002/010] Iteration[005/005] Loss: 0.6954 Acc: 52.86%
    Train:   Epoch[003/010] Iteration[035/035] Loss: 0.6813 Acc: 58.53%
    Valid:   Epoch[003/010] Iteration[005/005] Loss: 0.6909 Acc: 55.71%
    Train:   Epoch[004/010] Iteration[035/035] Loss: 0.6832 Acc: 57.99%
    Valid:   Epoch[004/010] Iteration[005/005] Loss: 0.6749 Acc: 52.86%
    Train:   Epoch[005/010] Iteration[035/035] Loss: 0.6838 Acc: 58.35%
    Valid:   Epoch[005/010] Iteration[005/005] Loss: 0.6865 Acc: 50.00%
    Train:   Epoch[006/010] Iteration[035/035] Loss: 0.6729 Acc: 58.89%
    Valid:   Epoch[006/010] Iteration[005/005] Loss: 0.7097 Acc: 57.14%
    Train:   Epoch[007/010] Iteration[035/035] Loss: 0.6700 Acc: 61.58%
    Valid:   Epoch[007/010] Iteration[005/005] Loss: 0.7361 Acc: 47.14%
    Train:   Epoch[008/010] Iteration[035/035] Loss: 0.6721 Acc: 59.07%
    Valid:   Epoch[008/010] Iteration[005/005] Loss: 0.7180 Acc: 52.86%
    Train:   Epoch[009/010] Iteration[035/035] Loss: 0.6476 Acc: 63.91%
    Valid:   Epoch[009/010] Iteration[005/005] Loss: 0.7193 Acc: 57.14%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    结论:

    1.直接将 Pytorch-Camp 处理 RMB 分类问题时用到的 LeNet模型用于猫狗数据集分类,从结果来看是不合适的,可能需要对 LeNet进行调整(我猜后面可能会学到该如何调整网络结构)。

    2.从这个例子中进一步理解了训练一个神经网络的过程:数据、模型、损失函数、优化器、训练,同时也了解了每个过程中所涉及到的一些细节的处理。

    3.目前存在的问题就是:和第1点中提到的一样,对于不同的实际问题,该如何构建合理的深度学习网络(有哪些需要微调的地方?为什么在这个地方进行微调、有什么依据?)。

    Pytorch 数据预处理模块 —— transforms

    因为不搞计算机视觉,所以 transforms 这部分的内容暂时不学习…

    torchvision: 计算机视觉工具包;
    
    torchvision.transforms: 常用的图像预处理方法;
    torchvision.datasets: 常用数据集的dataset实现,比如 MNIST, CIFAR-10, ImageNet等;
    torchvision.model: 常用的模型预训练,比如 AlexNet, VGG, ResNet, GoogLeNet等;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    torchvision.transforms

    数据中心化,标准化,缩放,裁剪,旋转,填充,翻转,噪声添加,灰度变换,线性变换,仿射变换,亮度、饱和度及对比对变换。

  • 相关阅读:
    LVS负载均衡集群 (NAT模式)
    Dubbo-Activate实现原理
    ubuntu 复制文件路径
    【无人机】模拟一群配备向下摄像头的移动空中代理覆盖平面区域(Matlab代码实现)
    游戏平台加盟该怎么做?需要准备什么?
    SpringBoot项目的搭建
    设计模式- 代理模式(Proxy Pattern)结构|原理|优缺点|场景|示例
    git常用命令
    js中的类型转换
    Python调用ChatGPT API使用国内中转key 修改接口教程
  • 原文地址:https://blog.csdn.net/weixin_44065416/article/details/133656790