加载和规范化数据集
为了和模型训练解耦和代码模块化,pytorch提供了两种数据加载的工具torch.utils.data.DataLoader
and torch.utils.data.Dataset
。
Dataset存储了样本和标签,DataLoader是Dataset的遍历器。
pytorch提供了许多现成的Dataset子类,可以通过函数调用直接获得。
也可以定制自己的Dataset,只需要实现三个函数。
__init__:在Dataset实例化时执行一次
__len__:获得样本量
__getitem__:通过下标idx获得样本
Dataset一次返回一个样本,但是一次训练希望返回minibatch个样本;在不同epoch里也希望打乱顺序避免过拟合。所以DataLoader在Dataset上进行了封装。
TRANSFORMS 数据预处理
dataset中的数据并不一定满足模型训练的要求,所以需要对样本做一些处理。
所有torchvision的dataset都有两个参数transform和target_transform用来接收两个函数,分别对样本图片和标注做一些处理。
BUILD THE NEURAL NETWORK
所有模型都是nn.modules的子类,在定义模型之后,进行实例化时,可以将其to到指定的device上。
可以通过如下代码查看模型结构和 参数信息。
print(f"Model structure: {model}\n\n") for name, param in model.named_parameters(): print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")
AUTOMATIC DIFFERENTIATION WITH TORCH.AUTOGRAD 自动微分
BP是训练神经网络最常见的算法,它根据损失函数的梯度逐个依次计算各个参数的梯度。
torch.autograd是pytorch中自动计算梯度的引擎,借此可以计算各种计算图的梯度。
可以在创建tensor的时候,设置requires_grad=true,也可以调用tensor对象的requires_grad_(true)方法,来启用autograd(默认对tensor是开启的)。
tensor的grad_fn属性,记录了该tensor计算而来的方法,以便计算前者的梯度。
计算梯度
可以通过tensor对象的loss.backward()方法来自动计算梯度,并且通过tensor.grad 的属性来获取梯度。
出于性能考虑,backward()只能执行一次,如果需要再次执行,需要在方法中设置参数retain_graph=true。
autograd在FP中会做两件事
1、运行计算获得结果tensor
2、在DGA中保留梯度函数
autograd在BP中会做三件事,在DGA的root tensor调用backward()方法时
1、通过DGA中的梯度函数计算各个梯度
2、将梯度保存到各个tensor的grad属性中
3、 利用链式法则不断向根节点计算
注意:在计算完梯度之后,需要手动设置grad为零。在实际训练中,优化器会帮我们做这一件事。
关闭自动梯度更新
开启了需要梯度计算的tensor,有时候也需要关闭梯度更行,比如在微调任务中,所以可以通过以下两种方式进行关闭。
z = torch.matmul(x, w)+b
# way 1
with torch.no_grad(): z = torch.matmul(x, w)+b print(z.requires_grad)
# way two
z_det = z.detach()
print(z_det.requires_grad)
Note
Previously we were calling backward()
function without parameters. This is essentially equivalent to calling backward(torch.tensor(1.0))
, which is a useful way to compute the gradients in case of a scalar-valued function, such as loss during neural network training.
当损失是一个标量时,可以直接调用backward()
function这等价于调用backward(torch.tensor(1.0))。所以当tensor是一个矩阵时,我们需要传入一个和tensor大小一致且全为一的矩阵。
OPTIMIZING MODEL PARAMETERS
跑了一个完整的训练流程,具体不记录了,需要动手实践,从头到位完成一遍。
总结
这篇介绍写的还是挺好的,了解了pytorch的一些基本概念,可以开始写最简单的一些应用。
可是看到一些复杂的算法、模型时,还是会感到头大。不可心急,还是一步一步来吧。
想想下一步可以干的事情。
第一,自己在本地数据集上,从零开始完成这个FasionMINST的任务。
第二,看完李宏毅的教程,把里面的作业都做完。
第三,把bros的代码跑通弄懂。