pytorch常用函数定义是怎样的
Admin 2022-08-12 群英技术资讯 289 次浏览
import torch from torch import nn class MyLinear(nn.Module): def __init__(self, in_features, out_features): super().__init__() self.weight = nn.Parameter(torch.randn(in_features, out_features)) self.bias = nn.Parameter(torch.randn(out_features)) def forward(self, input): return (input @ self.weight) + self.bias
一个有序的容器,神经网络模块将按照在传入构造器的顺序依次被添加到计算图中执行,同时以神经网络模块为元素的有序字典也可以作为传入参数。Sequential适用于快速验证结果,简单易读,但使用Sequential也会使得模型定义丧失灵活性,比如需要在模型中间加入一个外部输入时就不适合用Sequential的方式实现。
net = nn.Sequential( ('fc1',MyLinear(4, 3)), ('act',nn.ReLU()), ('fc2',MyLinear(3, 1)) )
ModuleList 接收一个子模块(或层,需属于nn.Module类)的列表作为输入,然后也可以类似List那样进行append和extend操作。同时,子模块或层的权重也会自动添加到网络中来。
net = nn.ModuleList([nn.Linear(784, 256), nn.ReLU()]) net.append(nn.Linear(256, 10)) # # 类似List的append操作 print(net[-1]) # 类似List的索引访问 print(net)
Linear(in_features=256, out_features=10, bias=True) ModuleList( (0): Linear(in_features=784, out_features=256, bias=True) (1): ReLU() (2): Linear(in_features=256, out_features=10, bias=True) )
要特别注意的是,nn.ModuleList 并没有定义一个网络,它只是将不同的模块储存在一起。
ModuleList中元素的先后顺序并不代表其在网络中的真实位置顺序,需要经过forward函数指定各个层的先后顺序后才算完成了模型的定义。
具体实现时用for循环即可完成:
class model(nn.Module): def __init__(self, ...): super().__init__() self.modulelist = ... ... def forward(self, x): for layer in self.modulelist: x = layer(x) return x
ModuleDict和ModuleList的作用类似,只是ModuleDict能够更方便地为神经网络的层添加名称。
net = nn.ModuleDict({ 'linear': nn.Linear(784, 256), 'act': nn.ReLU(), }) net['output'] = nn.Linear(256, 10) # 添加 print(net['linear']) # 访问 print(net.output) print(net)
Linear(in_features=784, out_features=256, bias=True) Linear(in_features=256, out_features=10, bias=True) ModuleDict( (act): ReLU() (linear): Linear(in_features=784, out_features=256, bias=True) (output): Linear(in_features=256, out_features=10, bias=True) )
ModuleList和ModuleDict在某个完全相同的层需要重复出现多次时,非常方便实现,可以”一行顶多行“;当我们需要之前层的信息的时候,比如 ResNets 中的残差计算,当前层的结果需要和之前层中的结果进行融合,一般使用 ModuleList/ModuleDict 比较方便。
展平输入的张量: 28x28 -> 784
input = torch.randn(32, 1, 5, 5) m = nn.Sequential( nn.Conv2d(1, 32, 5, 1, 1), nn.Flatten() ) output = m(input) output.size()
有了上面的一些常用方法,我们可以修改现有的一些开源模型,这里通过介绍修改模型层、添加额外输入的案例来帮助我们更好地理解。
以pytorch官方视觉库torchvision预定义好的模型ResNet50为例,探索如何修改模型的某一层或者某几层。
我们先看看模型的定义:
import torchvision.models as models net = models.resnet50() print(net)
ResNet( (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False) (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) (relu): ReLU(inplace=True) (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False) (layer1): Sequential( (0): Bottleneck( (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False) .............. (avgpool): AdaptiveAvgPool2d(output_size=(1, 1)) (fc): Linear(in_features=2048, out_features=1000, bias=True) )
为了适配ImageNet,fc层输出是1000,若需要用这个resnet模型去做一个10分类的问题,就应该修改模型的fc层,将其输出节点数替换为10。另外,我们觉得一层全连接层可能太少了,想再加一层。
可以做如下修改:
from collections import OrderedDict classifier = nn.Sequential(OrderedDict([('fc1', nn.Linear(2048, 128)), ('relu1', nn.ReLU()), ('dropout1',nn.Dropout(0.5)), ('fc2', nn.Linear(128, 10)), ('output', nn.Softmax(dim=1)) ])) net.fc = classifier # 将模型(net)最后名称为“fc”的层替换成了我们自己定义的名称为“classifier”的结构
有时候在模型训练中,除了已有模型的输入之外,还需要输入额外的信息。比如在CNN网络中,我们除了输入图像,还需要同时输入图像对应的其他信息,这时候就需要在已有的CNN网络中添加额外的输入变量。
基本思路是:将原模型添加输入位置前的部分作为一个整体,同时在forward中定义好原模型不变的部分、添加的输入和后续层之间的连接关系,从而完成模型的修改。
我们以torchvision的resnet50模型为基础,任务还是10分类任务。不同点在于,我们希望利用已有的模型结构,在倒数第二层增加一个额外的输入变量add_variable来辅助预测。
具体实现如下:
class Model(nn.Module): def __init__(self, net): super(Model, self).__init__() self.net = net self.relu = nn.ReLU() self.dropout = nn.Dropout(0.5) self.fc_add = nn.Linear(1001, 10, bias=True) self.output = nn.Softmax(dim=1) def forward(self, x, add_variable): x = self.net(x) # add_variable (batch_size, )->(batch_size, 1) x = torch.cat((self.dropout(self.relu(x)), add_variable.unsqueeze(1)),1) x = self.fc_add(x) x = self.output(x) return x
修改好的模型结构进行实例化,就可以使用
import torchvision.models as models net = models.resnet50() model = Model(net).cuda() # 使用时输入两个inputs outputs = model(inputs, add_var)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
清理重复的文件清理重复文件的优化清理重复的文件已知条件:什么都不知道,只需要知道它是文件就可以了实现方法:可以从指定路径(或最上层路径)开始读取,利用 glob 读取每个文件
这篇文章主要介绍了用python制作北上广深——地铁线路动态图,文中的示例代码讲解详细,对我们的工作或学习都有一定的价值,感兴趣的同学可以学习一下
这篇文章主要介绍了Python 实现一个全连接的神经网络,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
这篇文章主要介绍了Python中的Numpy 面向数组编程常见操作,使用Numpy数组可以使你利用简单的数组表达式完成多项数据操作任务,而不需要编写大量的循环,这个极大的帮助了我们高效的解决问题
这篇文章给大家分享的是有关python内置数据结构的内容,下文介绍了array、defaultdict、Named Tuple和Counter这几种python内置数据结构的作用和用法,小编觉得挺实用的,因此分享给大家做个参考。感兴趣的朋友跟随小编一起来看看吧。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008