PyTorch 入门:训练一个深度神经网络(DNN)
准备知识
1. NumPy
为什么要学 NumPy?弄懂了 NumPy 的 array,可以轻松上手 PyTorch 的 tensor。请看这个对比:torch v.s. numpy。
这里毛遂自荐一下我制作的 NumPy视频 ,结合例子、绘图讲解,看过之后会明白 shape, 轴运算和轴变换等等重要知识点。
2. OOP(面向对象编程)
PyTorch 里面数据集和模型都是以对象的方式定义的。因此,了解一点面向对象编程的知识很有帮助。当然,你也可以先试试看,觉得困惑再补充知识。
3.Deep Learning 基础知识
了解 Deep Neural Network 基础知识,比如:网络架构(可阅读我的文章:李宏毅老师《机器学习》课程笔记-1深度学习简介),Back Propagation 等,对于理解代码很有帮助。
PyTorch tutorial
我先根据 Pytorch 网站上的 tutorial 来学 PyTorch,有两个实例教程:
1.A 60 Minute Blitz-cifar10数据集例子
2.Quickstart-FashionMNIST数据集例子
收获:发现 Deep Neural Network 的流程为:准备数据–>定义 model, criterion,optimizer–>训练和测试
接着学习了李宏毅老师《机器学习2021》Homework1-2 助教老师的示例代码:
1.李宏毅老师《机器学习2021》homework1 sample code: (By Heng-Jui Chang) https://github.com/ga642381/ML2021-Spring/blob/main/HW01/HW01.ipynb
2.李宏毅老师《机器学习2021》homework2 sample code: https://github.com/ga642381/ML2021-Spring/blob/main/HW02/HW02-1.ipynb
收获:补充了一些知识,包括自定义数据集对象 Dataset,如何在训练中加入验证。
参考以上示例代码,我总结了一下用 PyTorch 实现 Deep Neural Network 的常用代码(或者说 pipeline)。这是基于我对知识点的学习和理解,可能有疏漏和错误之处,欢迎交流,请多多指教,谢谢!
Deep Neural Network pipeline
下图所示为训练一个 Deep Neural Network 模型的基本流程。一般有 5 个步骤,接下来我会依次介绍各步骤的工作和常用代码。代码中有的地方并没有写细节,只是给出了框架。你可以把这个代码当作模板或是 cheatsheet,对照着示例代码学习,帮助你更好地理清思路,然后可以照着这个框架试着写一写。

1. Data
1.1 load the dataset
PyTorch tutorial 使用的是公开数据集。在 torchvision.datasets 模块有一些函数,可以下载并定义知名的公开数据集。
如果是外部数据集,就需要自己定义数据集对象。这里假设数据集名为 “MyDataset”,要定义三个函数,分别是:
__init__:初始化,把 data(输入) 和 label(如果是训练集)整理后成对放在一起,一般是用 pandas 或 NumPy 读取数据的,要转成 PyTorch 中的 tensor。__getitem__:根据索引,返回某条数据的值。__len__:返回数据集大小。
import torch
from torch.utils.data import Dataset,DataLoader
class MyDataset():
def __init__(self,data,label=None):
if label is not None: #train set/val set
self.data=...
self.label=...
else: #test set
self.data=...
def __getitem__(self,index):
if self.label is not None: #for train set/val set
return self.data[index],self.label[index]
else: #for test set(no label)
return self.data[index]
def __len__(self):
return len(self.data)
1.2 DataLoader
DataLoader 其实就是对数据分组 (batch) 打包。Load 是载重的意思,你可以把 DataLoader 想象成是去仓库 (Dataset)运东西的卡车,每次都装一样多的货物 (设置 batch_size)。
还有一点要注意的是,training set 要把数据打乱 (shuffle) 再分组。validation set 和 test set 不用做 shuffle。
train_loader=DataLoader(trainset,batch_size=batch_size,shuffle=True)
test_loader/val_loader=DataLoader(testset/valset,batch_size=batch_size,shuffle=False)
2. Define the model
建立 model object,我感觉这一步像搭积木,简单有趣。当然,这要感谢 Pytorch 的开发者们写好了这些模块,直接从 torch.nn 中调用就可以。这里假设模型名为 “MyNet”,要定义两个函数,分别是:
__init__(self):定义模块。可以写单个模块,如 nn.Linear(), nn.Sigmoid()。也可以用 nn.Sequential() 串起几个模块。forward(self,x):按网络架构从输入到输出走一遍。
import torch.nn as nn
class MyNet(nn.Module):
def __init__(self):
super(MyNet,self).__init__()
self.module1=nn.Linear(...)
self.module2=nn.Sigmoid(...)
#以pipeline的方式写几个函数
self.module3=nn.Sequential(nn.Linear(...),nn.ReLU(...))
def forward(self,x):
x=self.module1(x)
x=self.module2(x)
x=self.module3(x)
return x
3. Define criterion(loss function) and optimizer
我们知道,机器学习三要素:model, criterion, optimizer,这一步就要设定。先把上一步定义的 MyNet() 实例化,创建模型。如果使用 GPU 加速,也要在这一步设置模型移动到 (move to) GPU 上。然后设置 criterion 和 optimizer,在 torch 中都有函数可调用。
import torch.optim as optim
device="cuda" if torch.cuda.is_available else "cpu" #查看是否有GPU可用
model=MyNet().to(device)#实例化和GPU
criterion=nn.CrossEntropyLoss()/nn.MSELoss() #分类用CrossEntropy,回归用MSE
optimizer=optim.SGD(model.parameters(),lr=.., momentum=...) #或optim.Adam(...)
4. training and validation
这里写了两个函数:train(): 处理训练集数据和 val(): 处理验证集数据,train( ) 函数中会调用 val( ) 函数。具体来说,就是在每个 epoch, 在 training set 做完 training 之后,在 validation set 做 validation,计算 val_loss。如果 val_loss 小于最小值 min_val_loss,就保存此时的模型参数(model.state_dict()) ,也就是 weights, bias 等参数。
注意:1.使用 GPU 加速的话,要设置数据 move to GPU。
- dataloader 的两个参数,可能在计算 average loss, accuracy 时会用到:
(1)数据集的长度:size=len(dataloader.dataset)
(2)分组数:num_batches=len(dataloader)
4.1 training
def train(n_epochs,dataloader,model,criterion,optimizer):
train_loss=0
min_val_loss=1000
num_batches=len(dataloader)
model.train() #重要!设置模式
for i in range(n_epochs):
print(f"Epoch:{i+1}")
for batch_idx,(inputs,labels) in enumerate(dataloader):
inputs,labels=inputs.to(device),labels.to(device) #GPU
optimizer.zero_grad()
outputs=model(inputs)
loss=criterion(outputs,labels)
loss.backward()
optimizer.step()
#(可选)每隔100个batches,打印一次结果
if batch_idx%100==0:
print(f"current batch:{batch_idx}/all:{num_batches},
loss:{loss.item():.6f}")
train_loss+=loss.item()
train_loss=train_loss/num_batches
print(f"average training loss:{train_loss:.6f}")
#validation
val_loss=val(dataloader,model,criterion)
print(f"average val loss:{val_loss:.6f}")
if val_loss < min_val_loss:
min_val_loss=val_loss
#保存模型参数
print("saving the model...")
torch.save(model.state_dict(),".\model.pth")
4.2 validation
def val(dataloader,model,criterion):
val_loss=0
num_batches=len(dataloader)
model.eval() #重要!设置模式
with torch.no_grad():
for inputs,labels in dataloader:
inputs,labels=inputs.to(device),labels.to(device) #GPU
outputs=model(inputs)
val_loss+=criterion(outputs,labels).item()
val_loss=val_loss/num_batches
return val_loss
5. Test the model
首先要加载训练中得到的最佳模型参数,然后把测试集输入模型,输出结果。
注意:1.使用 GPU 加速的话,要设置数据 move to GPU。训练完的预测结果,又要转换回 cpu,numpy 的格式。
2.对于分类问题,预测得到的是各类别的概率,不能直接当作结果输出,需要判断类别(选择概率最大的类别)后得到结果。
#加载优化好的模型参数
model=MyNet().to(device)
model.load_state_dict(torch.load(".\model.pth"))
def test(dataloader,model):
predicts=[]
model.eval() #重要!设置模式
with torch.no_grad():
for inputs in dataloader:
inputs=inputs.to(device) #GPU
outputs=model(inputs)
#根据每个batch的outputs,输出预测结果
pred=...(from outputs)
#存入predicts_all中
predicts.append(pred)
return predicts
补充
在训练中会用到随机,比如在 DataLoader 中,要设置 shuffle,打乱训练数据。如果想保持每次产生的随机分组相同,可以在代码的开头设定 random seed。
def set_seed(seed):
np.random.seed(seed)
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
torch.backends.cudnn.benchmark=False
torch.backends.cudnn.deterministic=True
myseed=42
set_seed(myseed)
觉得本文不错的话,请点赞支持一下吧,谢谢!
关注我 宁萌Julie,互相学习,多多交流呀!
欢迎点击 李宏毅老师《机器学习》笔记–合辑目录,阅读更多笔记。
参考:
1.A 60 Minute Blitz-cifar10数据集例子: https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html
2.Quickstart-FashionMNIST数据集例子: https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html
3.李宏毅老师《机器学习2021》homework1 sample code: (By Heng-Jui Chang) https://github.com/ga642381/ML2021-Spring/blob/main/HW01/HW01.ipynb
4.李宏毅老师《机器学习2021》homework2 sample code: https://github.com/ga642381/ML2021-Spring/blob/main/HW02/HW02-1.ipynb
5.介绍了模型参数的保存和加载:https://pytorch.org/tutorials/beginner/saving_loading_models.html
更多推荐
所有评论(0)