深入浅出PyTorch task02 打卡

task02 PyTorch的各个组件和实战

一、PyTorch的主要组成模块

1. 深度学习的必要部分

1.1 整体流程
  1. 数据预处理,划分训练集和测试集
  2. 模型设计,设定损失函数和优化方法
  3. 设定超参数,使用训练集进行训练(前向传播、反向传播、更新参数)
  4. 使用模型拟合数据,在测试集上进行验证评估模型
1.2 深度学习的特点
  1. 样本量大,分批(batch)加载
  2. 网络层数多,逐层、模块化搭建网络
  3. 多样化损失函数和优化器
  4. GPU运算
  5. 模块之间的配合

2. FashionMNIST时装分类实战

2.1 基本配置
  • 常用packages
  • 超参数(batch_size、learning_rate、max_epochs)
  • GPU的设置
2.2 数据读入

​ 使用Dataset+DataLoader进行数据读入

2.2.1 Dataset

​ 获取Dataset数据集的两种方式:

  • 使用PyTorch内置数据集
  • 自定义Dataset类:

Dataset类重载方法:

  • __len__(): 返回数据数量
  • __getitem__(index): 可以根据索引号获取数据
2.2.2 DataLoader

​ DataLoader载入数据,DataLoader参数:

  • batch_size: 批数
  • num_workers: 读取数据的进程数
  • shuffle: 是否打乱数据
  • drop_last: 是否丢弃最后一部分不完整的数据

​ 通过next(iter(dataloder))完成读取数据

2.3 模型构建
2.3.1 Moudul类

​ 所有神经网络模块的基类

  • __init__ (self,**kwargs): 定义所有的子模块
  • forward(self,x): 连接起各个子模块,构建起前向传播链
class MLP(nn.Module):
  def __init__(self, **kwargs):
    super(MLP, self).__init__(**kwargs)
    self.hidden = nn.Linear(784, 256)
    self.act = nn.ReLU()
    self.output = nn.Linear(256,10)
    
  def forward(self, x):
    o = self.act(self.hidden(x))
    return self.output(o)   

X = torch.rand(2,784)
net = MLP()
net(X) # 前向传播
2.3.2 常见的层
  • 不含参数的层(不含Parameter类)
  • 函参数的层(包含Parameter、ParameterList 或 ParameterDict)
  • 卷积层
  • 池化层(最大池化层、平均池化层)
  • 循环层
2.4 模型初始化

​ 通过torch.nn.init 里提供的方法对模型的参数进行初始化;通过isinstance()判别出不同类型的模型,进行对应模型的参数初始化

2.5 损失函数

​ 损失函数是评价模型结果和真实结果的指标,模型按照损失函数所定的目标进行训练改进。

2.5.1 常用损失函数
函数名 方法名 功能
二分类交叉熵损失函数 torch.nn.BCELoss 计算二分类任务时的交叉熵(Cross Entropy)函数
交叉熵损失函数 torch.nn.CrossEntropyLoss 计算交叉熵函数
L1损失函数 torch.nn.L1Loss 计算输出y和真实标签target之间的差值的绝对值
MSE损失函数 torch.nn.MSELoss 计算输出y和真实标签target之差的平方
平滑L1损失函数 torch.nn.SmoothL1Loss L1的平滑输出,其功能是减轻离群点带来的影响
KL散度 torch.nn.KLDivLoss 计算KL散度,也就是计算相对熵。用于连续分布的距离度量,并且对离散采用的连续输出空间分布进行回归通常很有用。
2.6 优化器

​ 优化器根据网络反向传播的梯度信息来更新网络的参数,以加你损失函数的值

2.6.1 Optimizer类
class Optimizer(object):
    def __init__(self, params, defaults):        
        self.defaults = defaults
        self.state = defaultdict(dict)
        self.param_groups = []
  • defaults:存储的是优化器的超参数
  • state:参数的缓存
  • param_groups:管理的参数组,是一个list,其中每个元素是一个字典

Optimizer类的方法:

  • zero_grad():清空所管理参数的梯度,PyTorch的特性是张量的梯度不自动清零,因此每次反向传播后都需要清空梯度。
  • step():执行一步梯度更新,参数更新
  • add_param_group():添加参数组
  • load_state_dict() :加载状态参数字典,可以用来进行模型的断点续训练,继续上次的参数进行训练

Optimizer在一个神经网络的epoch中需要实现下面两个步骤:

  1. 梯度置零
  2. 梯度更新
optimizer = torch.optim.SGD(net.parameters(), lr=1e-5)
for epoch in range(EPOCH):
	...
	optimizer.zero_grad()  #梯度置零
	loss = ...             #计算loss
	loss.backward()        #BP反向传播
	optimizer.step()       #梯度更新
2.7 训练与评估

​ 模型具有训练状态和验证状态,通过model.train()model.eval()进行切换

def train(epoch):
    model.train()
    for data, label in train_loader:
        data, label = data.cuda(), label.cuda()
        optimizer.zero_grad()	# 梯度置零
        output = model(data)	# 前向传播
        loss = criterion(label, output) # 计算loss
        loss.backward()			# 反向传播
        optimizer.step()		# 更新参数
def val(epoch):       
    model.eval()
    with torch.no_grad():
        for data, label in val_loader:
            data, label = data.cuda(), label.cuda()
            output = model(data)
            loss = criterion(output, label)

验证过程不同于训练:

  • 不需要跟踪梯度,以及将model调至eval模式
  • 不需要将优化器的梯度置零
  • 不需要将loss反向回传到网络
  • 不需要更新optimizer
2.8 实战

​ 通过FashionMNIST时装分类完整的项目实战,熟悉了PyTorch项目的完整流程

浙ICP备19012682号