深入浅出pytorch(三)

Task02:pytorch基础模块

机器学习一般流程

数据预处理
格式统一
数据划分
数据变换
训练集
模型评估
测试集
损失函数
拟合训练
优化函数
模型
测试表现

基本配置

导入必要的数据处理包,常见的有如下几种

import os
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
import torch.optim as optimizer

对于深度学习任务,一般有几个超参数可以统一设置,主要有

  • batch size
  • 初始学习率
  • 训练次数
  • GPU配置
    参数可统一设置为
batch_size = 16
lr = 1e-4
max_epochs = 100

GPU设置有两种常见方式,

# 方案一:使用os.environ,这种情况如果使用GPU不需要设置
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1'

# 方案二:使用“device”,后续对要使用GPU的变量用.to(device)即可
device = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")

数据读入

主要指通过Dataset和Dataloader方式读入数据

  • Dataset:定义数据格式、数据变换形式
  • Dataloader:以iterative方式读入数据
    Dataset类主要包括三个函数
  • __init__:向类中传入外部参数,同时定义样本集
  • __getitem__:逐个读取样本集合中的元素,可以进行一定的变换,并将返回训练/验证所需的数据
  • __len__:返回样本集的样本数
    Dataloader类主要属性
  • batch_size:样本按“批”读入,指每次读入的样本数
  • num_workers:用于读取数据的进程数
  • shuffle:是否将样本数据打乱
  • drop_last:抛弃最后一部分未达到批次数的样本

模型构建

构造神经网络

pytorch中神经网络构造基于Module类模型进行。Module 类是 nn 模块里提供的一个模型构造类,是所有神经⽹网络模块的基类。
这里主要是通过一个简单实例,认识pytorch中的神经网络模型,多层感知机,创建模型参数,前向计算任务。

神经网络中的常见层

  • 不含模型参数的层
  • 含模型参数的层
  • 二维卷积层
    将输入和卷积核做互相关运算,加上一个标量偏差得到输出。模型参数包括卷积核和标量偏差,训练模型时,通常对卷积核随机初始化,迭代运算卷积核和偏差。
    卷积窗口形状为 p × q p \times q p×q,卷积核的高和宽分别为 p p p q q q
    填充:在输入的高和宽的两侧填充元素(通常为0)
    卷积核的高和宽不同时,通过设置相应的不同填充数使输入和输出具有相同的高和宽。
    二维互相关运算中,卷积窗口从输入数组的最左上方开始,按从左往右、从上往下 的顺序,依次在输⼊数组上滑动。我们将每次滑动的行数和列数称为步幅(stride)。
    步幅:在输出的高和宽的两侧减少元素
  • 池化层
    每次对输入数据一个固定形状窗口(池化窗口)中的元素计算输出。
    直接计算池化窗口内元素的最大值或者均值,对应运算分别称为最大池化或者平均池化。
    在二维最⼤池化中,池化窗⼝口从输⼊数组的最左上⽅方开始,按从左往右、从上往下的顺序,依次在输⼊数组上滑动。当池化窗口滑动到某⼀位置时,窗口中的输入子数组的最大值即输出数组中相应位置的元素。
    torch.nn包用来构建神经网,只支持小批量样本输入,不支持单个样本输入,而nn包则依赖于autogrand来定义模型并对进行求导。

模型示例

一个神经网络的典型训练过程包括:

  • 定义包含一些可学习参数(或者叫权重)的神经网络
  • 输入数据集进行迭代
  • 通过网络处理输入数据
  • 计算 loss (输出和正确答案的距离)
  • 将梯度反向传播给网络的参数
  • 使用规则更新网络的权重

LeNet
一些模块

  • torch.tensor:一个多维数组,支持诸如backward()等的自动求导操作,同时也保存了张量的梯度
  • nn.module:神经网络模块。是一种方便封装参数的方式,具有将参数移动到GPU、导出、加载等功能
  • nn.parameter:张量的一种,当它作为一个属性分配给一个Module时,它会被自动注册为一个参数
  • auto.function:实现了自动求导前向和反向传播的定义,每个Tensor至少创建一个Function节点,该节点连接到创建Tensor的函数并对其历史进行编码
    AlexNet

损失函数

模型的负反馈

二分类交叉熵损失函数

torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')
#功能:计算二分类任务时的交叉熵(Cross Entropy)函数。在二分类中,label是{0,1}。对于进入交叉熵函数的input为概率分布的形式。一般来说,input为sigmoid激活层的输出,或者softmax的输出
#主要参数: weight:每个类别的loss设置权值
#size_average:数据为bool,为True时,返回的loss为平均值;为False时,返回的各样本的loss之和。
#reduce:数据类型为bool,为True时,loss的返回是标量

计算公式(形式有误)
KaTeX parse error: Expected '}', got '\right' at position 180: … } \end{array} \̲r̲i̲g̲h̲t̲.

交叉熵损失函数

torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')
#功能:计算交叉熵函数
#主要参数: weight:每个类别的loss设置权值。
#size_average:数据为bool,为True时,返回的loss为平均值;为False时,返回的各样本的loss之和。
#ignore_index:忽略某个类的损失函数。
#reduce:数据类型为bool,为True时,loss的返回是标量

计 算 公 式 如 下 : loss ⁡ ( x ,  class  ) = − log ⁡ ( exp ⁡ ( x [  class  ] ) ∑ j exp ⁡ ( x [ j ] ) ) = − x [  class  ] + log ⁡ ( ∑ j exp ⁡ ( x [ j ] ) ) 计算公式如下: \operatorname{loss}(x, \text { class })=-\log \left(\frac{\exp (x[\text { class }])}{\sum_{j} \exp (x[j])}\right)=-x[\text { class }]+\log \left(\sum_{j} \exp (x[j])\right) loss(x, class )=log(jexp(x[j])exp(x[ class ]))=x[ class ]+log(jexp(x[j]))

损失函数

torch.nn.L1Loss(size_average=None, reduce=None, reduction='mean')
#功能: 计算输出y和真实标签target之间的差值的绝对值
#reduction参数决定了计算模式。有三种计算模式可选:none:逐个元素计算。 sum:所有元素求和,返回标量。 mean:加权平均,返回标量。 如果选择none,那么返回的结果是和输入元素相同尺寸的。默认计算方式是求平均

L n = ( ∣ x n − y n ∣ g ) L_{n} =( | x_{n}-y_{n}|g) Ln=(xnyng)

MSE损失函数

torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean')
#功能:计算输出y和真实标签target之差的平方
#reduction参数决定了计算模式。有三种计算模式可选:none:逐个元素计算。 sum:所有元素求和,返回标量。默认计算方式是求平均

l n = ( x n − y n ) 2 l_{n}=\left(x_{n}-y_{n}\right)^{2} ln=(xnyn)2

平滑L1 (Smooth L1)损失函数

目标泊松分布的负对数似然损失

KL散度

MarginRankingLoss

多标签边界损失函数

二分类损失函数

多分类的折页损失

三元组损失

HingEmbeddingLoss

余弦相似度

CTC损失函数

pytorch优化器

优化器

通过不断改变网络参数,使得参数能够对输入做各种非线性变换拟合输出,进而寻找最优解。
方法:

  • 暴力求解
  • BP+优化器逼近求解
    就是根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值,使得模型输出更加接近真实标签

pytorch优化器

torch.optim提供的优化器有

  • torch.optim.ASGD
  • torch.optim.Adadelta
  • torch.optim.Adagrad
  • torch.optim.Adam
  • torch.optim.AdamW
  • torch.optim.Adamax
  • torch.optim.LBFGS
  • torch.optim.RMSprop
  • torch.optim.Rprop
  • torch.optim.SGD
  • torch.optim.SparseAdam
    优化器继承于基类optimizer
class Optimizer(object):
    def __init__(self, params, defaults):        
        self.defaults = defaults
        self.state = defaultdict(dict)
        self.param_groups = []

属性

  • defaults:存储的是优化器的超参数

  • state:参数的缓存

  • param_groups:管理的参数组
    方法

  • zero_grad():清空所管理参数的梯度

  • step():执行一步梯度更新,参数更新

  • add_param_group():添加参数组

  • load_state_dict() :加载状态参数字典,可以用来进行模型的断点续训练,继续上次的参数进行训练

  • state_dict():获取优化器当前状态信息字典

训练与评估

设置模型的状态

  • 训练状态:模型参数应该支持反向传播的修改
  • 验证/测试状态:不应该修改模型参数
model.train()   # 训练状态
model.eval()   # 验证/测试状态


#for循环读取DataLoader中的全部数据
for data, label in train_loader:
#将数据放到GPU上用于后续计算,以.cuda()为例
data, label = data.cuda(), label.cuda()
#开始用当前批次数据做训练时,应当先将优化器的梯度置零
optimizer.zero_grad()
#将data送入模型中训练
output = model(data)
#根据预先定义的criterion计算损失函数
loss = criterion(output, label)
#将loss反向传播回网络
loss.backward()
#使用优化器更新模型参数:
optimizer.step()

这样便完成一个训练过程。
验证/测试的流程基本与训练过程一致,不同点在于:

  • 需要预先设置torch.no_grad,以及将model调至eval模式
  • 不需要将优化器的梯度置零
  • 不需要将loss反向回传到网络
  • 不需要更新optimizer

可视化

必要时对必要信息进行可视化处理

Guess you like

Origin blog.csdn.net/qq_42194332/article/details/120809578