导入必要的数据处理包,常见的有如下几种
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 = 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方式读入数据
__init__
:向类中传入外部参数,同时定义样本集__getitem__
:逐个读取样本集合中的元素,可以进行一定的变换,并将返回训练/验证所需的数据__len__
:返回样本集的样本数pytorch中神经网络构造基于Module类模型进行。Module 类是 nn 模块里提供的一个模型构造类,是所有神经⽹网络模块的基类。
这里主要是通过一个简单实例,认识pytorch中的神经网络模型,多层感知机,创建模型参数,前向计算任务。
torch.nn
包用来构建神经网,只支持小批量样本输入,不支持单个样本输入,而nn
包则依赖于autogrand
来定义模型并对进行求导。一个神经网络的典型训练过程包括:
LeNet
一些模块
torch.tensor
:一个多维数组,支持诸如backward()等的自动求导操作,同时也保存了张量的梯度nn.module
:神经网络模块。是一种方便封装参数的方式,具有将参数移动到GPU、导出、加载等功能nn.parameter
:张量的一种,当它作为一个属性分配给一个Module时,它会被自动注册为一个参数auto.function
:实现了自动求导前向和反向传播的定义,每个Tensor至少创建一个Function节点,该节点连接到创建Tensor的函数并对其历史进行编码模型的负反馈
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(j∑exp(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=(∣xn−yn∣g)
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=(xn−yn)2
通过不断改变网络参数,使得参数能够对输入做各种非线性变换拟合输出,进而寻找最优解。
方法:
库torch.optim
提供的优化器有
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()
这样便完成一个训练过程。
验证/测试的流程基本与训练过程一致,不同点在于:
必要时对必要信息进行可视化处理