这两天开始学习阿里云天池的系列课程,刚好也接触了markdown语言,因此打算写个系列学习笔记上传到网上来记录每天的课程学习进度。就当做是一种变相的打卡,也可以用作以后的复习吧。
涉及课程为阿里云天池的Pytorch实战课程的1.1-3.4课时,部分内容摘自该课程课件并作出一定注释与修改,方便理解。如有侵权,请联系删除!
一. 使用Pytorch构建神经网络的基本格式
1.总览
一般来讲使用pytorch实现一个完整的神经网络代码大致分以下几块
- 数据处理
- 数据载入
- 数据增强
- 将数据转化可以灌入网络的格式
- 通过构建继承于
nn.Module
类的子类来自定义网络结构- 定义网络层
- 定义前向传播
- 分批训练
- 设置损失函数,优化器
- 设置学习率等超参数
- 前向传播
- 数据灌入得到预测值
- 计算平均损失
- 反向传播
- 优化器梯度清零
- 对损失函数自动求导
- 优化器根据求导结果调整参数
2.举例
这里使用简单的全连接网络来举例
- 数据处理
import torch
from torch import nn
# 确定随机数种子
torch.manual_seed(7)
# ---------------- 自定义数据集-------------------
X = torch.rand((7, 2, 2)) # 输入数据
target = torch.randint(0, 2, (7,)) # 标签
- 定义网络结构
# ----------------自定义网络结构-------------------------
class LinearNet(nn.Module): #继承自nn.Module
def __init__(self): #定义网络层
super(LinearNet, self).__init__()
self.dense = nn.Linear(4, 3) # 定义一层全连接层
self.softmax = nn.Softmax(dim=1) # 定义Softmax
def forward(self, x): #定义前向传播
y = self.dense(x.view((-1, 4)))
y = self.softmax(y)
return y
- 分批训练
net = LinearNet()
loss = nn.CrossEntropyLoss() # 设置交叉熵损失函数
optimizer = torch.optim.SGD(net.parameters(), lr=0.1) # 设置优化器(随机梯度下降)
for epoch in range(70):
train_l = 0.0
y_hat = net(X)
l = loss(y_hat, target).sum()
# 梯度清零
optimizer.zero_grad()
# 自动求导梯度
l.backward()
# 利用优化函数调整所有权重参数
optimizer.step()
train_l += l
print('epoch %d, loss %.4f' % (epoch + 1, train_l))
二. torch的自动求导函数backward()
自动求导函数用于上文所述的分享传播部分,在对损失函数进行自动求导后即可用优化器进行更新参数
原型:torch.autograd.backward(tensors, grad_tensors=None, retain_graph=None, create_graph=False)
- 功能:自动计算调用该函数的tensor(往往是loss)关于每个初始tensor的导数,并将其赋给这些初始tensor的grad属性
- tensors:用于求导的张量(即调用该函数的张量),如 loss(torch.autograd.backward(tensors=loss)等价于loss.backward())
- retain_graph:保存计算图
- create_graph:创建导数计算图,用于高阶求导
- grad_tensors(重要:只要调用tensor不是只有一个元素就得用):你最终要求的张量关于调用该函数的张量的导数
这里主要分析两个方面:基本功能和grad_tensors参数
(1). 基本功能:
import torch
x = torch.tensor([3.], requires_grad=True)
w