学院评估+++网站建设整改,河北省邢台市seo,wordpress半透明主题,做盗版小说网站前面整理了第5章的前半部分可以移步m【李沐 | 动手实现深度学习】9-1 Pytorch神经网络基础
下面是后半部分。
3 自定义层 前面我们深刻感受到了深度学习神经网络的灵活性#xff1a;我们可以创造性地组合不同的层/块#xff0c;从而设计出适用于目标任务的架构。有些情况下…前面整理了第5章的前半部分可以移步m【李沐 | 动手实现深度学习】9-1 Pytorch神经网络基础下面是后半部分。3 自定义层前面我们深刻感受到了深度学习神经网络的灵活性我们可以创造性地组合不同的层/块从而设计出适用于目标任务的架构。有些情况下我们可能要自己“Create”一个高级API没有提供的层下面我们来看如何构建自定义层。3.1 自定义无参数的层我们自定义的CenteredLayer 在__init__中仅完成了父类的初始化没有通过sefl.xxx的方式定义任何参数其前向传播→从输入中减去均值。import torch import torch.nn.functional as F from torch import nn class CenteredLayer(nn.Module): def __init__(self): super().__init__() def forward(self, X): return X - X.mean()我们看看它能否按预期工作。layer CenteredLayer() layer(torch.FloatTensor([1, 2, 3, 4, 5]))//输出示例可以看到CenteredLayer()如期完成了工作现在将层作为组件合并到构建更复杂的模型中我们向该网络传入随机数据检查均值是否为0。net nn.Sequential(nn.Linear(8, 128), CenteredLayer()) Y net(torch.rand(4, 8)) Y.mean()//输出示例可以看到均值为0由于处理的是浮点数由于精度的原因看到是一个非常小的非零数3.2 自定义带参数的层在MyLinear()的初始化函数中使用nn.Parameter封装了两个torch.randn随机正态分布初始化的张量self.weight和self.bias。前向传播实现了线性变换 Y XW B 随后接上 ReLU 激活函数注意当在forward函数中使用.data时实质上是在告诉 PyTorch“这次计算中把self.weight和self.bias看作普通的、不参与梯度追踪的常量。”尽管参数的requires_grad属性仍然是True但在这次特定的前向计算中它们被当作非可训练张量使用导致模型无法学习和更新参数。class MyLinear(nn.Module): def __init__(self, in_units, units): super().__init__() # in_units-输入单元数units-输出的特征数量 self.weight nn.Parameter(torch.randn(in_units, units)) self.bias nn.Parameter(torch.randn(units,)) def forward(self, X): linear torch.matmul(X, self.weight.data) self.bias.data return F.relu(linear)下面我们实例化MyLinear类并访问其模型参数。我们可以使用自定义层直接执行前向传播计算。使用自定义层构建模型。4 读写文件有时候我们希望将训练好的参数保存下载复用到其他场景怎么做呢此外当运行一个耗时较长的训练过程时 最佳的做法是定期保存中间结果 以确保在服务器电源被不小心断掉时我们不会损失几天的计算结果。4.1 加载和保存张量import torch from torch import nn from torch.nn import functional as F x torch.arange(4) torch.save(x, x-file) # 保存为名为x-file的文件 x2 torch.load(x-file) # 下载名为x-file的文件 x2//输出示例我们可以存储一个张量列表再把它读回内存。y torch.zeros(4) torch.save([x, y], xy-file) x2, y2 torch.load(xy-file) (x2,y2)//输出示例我们可以读取或写入从字符串映射到张量的字典mydict {x:x, y:y} torch.save(mydict, mydict) mydict2 torch.load(mydict) mydict24.2 加载和保存模型参数保存单个权重张量确实有用不过往往在实际应用中可能会涉及成百上千个参数难以逐个保存。因此深度学习框架提供了内置函数来保存和加载整个网络。需要注意的是机器做的是保存模型参数而非整个模型因为模型本身本身可以包含任意代码是难以序列化的。因此为了恢复模型我们需要用代码生成架构 然后从磁盘加载参数。以一个3层MLP为例class MLP(nn.Module): def __init__(self): super().__init__() self.hidden nn.Linear(20, 256) self.output nn.Linear(256, 10) def forward(self, x): return self.output(F.relu(self.hidden(x))) net MLP() X torch.randn(size(2, 20)) Y net(X)我们将模型的参数存储为“xxx.params”的文件。第二个数指定路径若只有文件名默认与代码文件同一文件夹xxx.params格式:这是 PyTorch 中常用的文件扩展名用于存储模型的权重和缓冲区张量torch.save(net.state_dict(), mlp.params)//输出示例torch.load(mlp.params):从磁盘文件中加载一个序列化的 Python 对象clone.load_state_dict(...) 这是核心的加载操作。它将磁盘文件中加载的状态字典包含所有参数和缓冲区的张量值精确地复制到clone模型的对应参数位置上。clone.eval(): 将模型clone切换到评估模式 (Evaluation Mode)。→ nn.Module的模式管理:PyTorch 中的某些层例如nn.Dropout和nn.BatchNorm即批量归一化层在训练时和推理时需要有不同的行为训练模式 (.train()):Dropout随机丢弃神经元BatchNorm计算并更新运行平均值和方差 (running mean/var)。评估模式 (.eval()):Dropout失效不丢弃任何神经元BatchNorm冻结其统计数据使用在训练过程中学到的固定的运行平均值和方差。→在加载模型进行推理时必须调用clone.eval()来确保这些层以正确的方式运行保证输出的确定性和准确性。clone MLP() # 先把模型声明出来再把参数放回去 clone.load_state_dict(torch.load(mlp.params)) clone.eval()//输出示例可以看到 clone(X) 的结果与 net(X) 的结果完全一致说明模型参数成功加载到了 clone的相应位置。总结Pytorch深度学习框架为我们自定义层提供了强大的灵活性可以自定义带参/无参的层并可以约其他层/块组合使用。此外有时候训练模型是一件很“贵”的事情我们可以通过保存模型参数的方式使得模型可以复用到其他环境save-保存load-加载。愉快的一天鼬鼬鼬鼬过去了~~~我又学废了