4、pytorch 模型创建(Module)

一、网络模型的创建

模型构建的两个要素:

  • 构建子模块:在自己建立的模型(继承nn.Module)的_init_()方法
  • 拼接子模块:是在模型的forward()方法中

init 函数构建子模块

    def __init__(self, classes):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16*5*5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, classes)

forward 函数拼接子模块


 def forward(self, x):
        out = F.relu(self.conv1(x))
        out = F.max_pool2d(out, 2)
        out = F.relu(self.conv2(out))
        out = F.max_pool2d(out, 2)
        out = out.view(out.size(0), -1)
        out = F.relu(self.fc1(out))
        out = F.relu(self.fc2(out))
        out = self.fc3(out)
        return out

创建模型时:net = LeNet()会调用 __init__()

训练模型时:output = net(inputs)会进入nn.module中的__call__()函数

二、nn.Module的属性

  • 在模型的概念当中,有一个非常重要的概念叫做nn.Module, 我们所有的模型,所有的网络层都是继承于这个类的。

torch.nn是pytorch的神经网络模块,这里的Module就是它的模块之一,还有几个与Module并列的子模块, 这些子模块协同工作,各司其职。

2.1 nn.Module属性

在nn.Module的__init__()方法中,创建8个重要的属性,   

def __init__(self):   

        self._parameters = OrderedDict()
        self._buffers = OrderedDict()
        self._backward_hooks = OrderedDict()
        self._forward_hooks = OrderedDict()
        self._forward_pre_hooks = OrderedDict()
        self._state_dict_hooks = OrderedDict()
        self._load_state_dict_pre_hooks = OrderedDict()
        self._modules = OrderedDict()

  • _parameters: 存储管理属于nn.Parameter类的属性,例如权值,偏置这些参数 
  • _modules: 存储管理nn.Module类, 比如LeNet中,会构建子模块,卷积层,池化层,就会                        存储在_modules中
  • _buffers:存储管理缓冲属性, 如BN层中的running_mean, std等都会存在这里面
  • ***_hook:存储管理钩子函数(5个与hooks有关的字典,这个先不用管)

2.2 nn.Module属性构建:

在nn.Module类中进行属性赋值时,被setattr函数拦截,在该函数中,判断即将要赋值的这个数据类型是否是nn.Parameter类,是则存储到parameters这个字典中;如果是nn.Module类,则存储在module这个字典中进行管理

2.3 nn.module总结

一个module可以包含多个子module(LeNet包含卷积层,池化层,全连接层)
一个module相当于一个运算, 必须实现forward函数(从计算图的角度去理解)
每个module都有8个字典管理它的属性(最常用的就是_parameters,_modules)

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.conv2 = nn.Conv2d(20, 20, 5)
 
    def forward(self, x):
        x = F.relu(self.conv1(x))
        return F.relu(self.conv2(x))
 

三、模型容器Containers

3.1 nn.Seuential

nn.Sequential 是 nn.module的容器,用于按顺序包装一组网络层。

1、根据输入类型可分为:

  • 非字典

'''------------Sequential---------------'''
class LeNetSequential(nn.Module):
    def __init__(self, classes):
        super(LeNetSequential, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 6, 5),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(6, 16, 5),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2),)
 
        self.classifier = nn.Sequential(
            nn.Linear(16*5*5, 120),
            nn.ReLU(),
            nn.Linear(120, 84),
            nn.ReLU(),
            nn.Linear(84, classes),)
 
    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size()[0], -1)
        x = self.classifier(x)
        return x


  • 字典型
class LeNetSequentialOrderDict(nn.Module):
    def __init__(self, classes):
        super(LeNetSequentialOrderDict, self).__init__()
 
        self.features = nn.Sequential(OrderedDict({
            'conv1': nn.Conv2d(3, 6, 5),
            'relu1': nn.ReLU(inplace=True),
            'pool1': nn.MaxPool2d(kernel_size=2, stride=2),
 
            'conv2': nn.Conv2d(6, 16, 5),
            'relu2': nn.ReLU(inplace=True),
            'pool2': nn.MaxPool2d(kernel_size=2, stride=2),
        }))
 
        self.classifier = nn.Sequential(OrderedDict({
            'fc1': nn.Linear(16*5*5, 120),
            'relu3': nn.ReLU(),
 
            'fc2': nn.Linear(120, 84),
            'relu4': nn.ReLU(inplace=True),
 
            'fc3': nn.Linear(84, classes),
        }))
 
    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size()[0], -1)
        x = self.classifier(x)
        return x

3.2 

nn.ModuleList:是nn.module的容器,用于包装一组网络层,以迭代方式调用网络层。

主要方法:

  • append():在ModuleList后面添加网络层
  • extend():拼接两个ModuleList
  • insert():指定在ModuleList中位置插入网络层
'''-------- ModuleList----------'''
 
class ModuleList(nn.Module):
    def __init__(self):
        super(ModuleList, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(20)])
 
    def forward(self, x):
        for i, linear in enumerate(self.linears):
            x = linear(x)
        return x
 
 
net = ModuleList()
 
print(net)
 
fake_data = torch.ones((10, 10))
 
output = net(fake_data)
 
print(output)

3.3 nn.ModuleDict

nn.ModuleDict是nn.module的容器,用于包装一组网络层,以索引方式调用网络层。

主要方法:

  • clear():清空ModuleDict
  • items():返回可迭代的键值对(key-value pairs)
  • keys():返回字典的键(key)
  • values():返回字典的值(values)
  • pop():返回一对键值,并从字典中删除
'''-----------ModuleDict---------------'''
class ModuleDict(nn.Module):
    def __init__(self):
        super(ModuleDict, self).__init__()
        self.choices = nn.ModuleDict({
            'conv': nn.Conv2d(10, 10, 3),
            'pool': nn.MaxPool2d(3)
        })
 
        self.activations = nn.ModuleDict({
            'relu': nn.ReLU(),
            'prelu': nn.PReLU()
        })
 
    def forward(self, x, choice, act):
        x = self.choices[choice](x)
        x = self.activations[act](x)
        return x
    
net = ModuleDict()
fake_img = torch.randn((4, 10, 32, 32))
output = net(fake_img, 'conv', 'relu')    # 在这里可以选择我们的层进行组合
print(output)

容器总结:

nn.sequential:顺序性,各网络层之间严格按照顺序执行,常用于block构建

nn.ModuleList:迭代性,常用于大量重复网络构建,通过for循环实现重复构建

nn.ModuleDict:索引性,常用于可选择的网络层

本文参考:Pytorch学习笔记(4):模型创建(Module)、模型容器(Containers)、AlexNet构建-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch 中,可以使用 nn.Module 类来创建模型。以下是一个简单的示例,创建一个具有两个全连接层的神经网络模型: ``` import torch.nn as nn class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.fc1 = nn.Linear(10, 20) self.fc2 = nn.Linear(20, 2) def forward(self, x): x = self.fc1(x) x = nn.functional.relu(x) x = self.fc2(x) return x ``` 在上面的代码中,我们首先定义了一个名为 Net 的类,并从 nn.Module 类继承。在类的构造函数中,我们使用 nn.Linear 定义了两个全连接层,并将其作为类的成员变量。在 forward 方法中,我们定义了模型的前向计算过程,即输入通过两个全连接层,最终输出一个大小为 2 的张量。 要使用这个模型进行训练和预测,我们需要将其实例化,并将输入张量传递给它的 forward 方法: ``` net = Net() input_tensor = torch.randn(1, 10) output_tensor = net(input_tensor) ``` 在训练模型时,我们通常会使用 optimizer 和 loss 函数来进行优化和计算损失。以下是一个简单的训练过程: ``` import torch.optim as optim # define optimizer and loss function optimizer = optim.SGD(net.parameters(), lr=0.01) criterion = nn.CrossEntropyLoss() # training loop for epoch in range(num_epochs): running_loss = 0.0 for i, data in enumerate(train_loader, 0): inputs, labels = data optimizer.zero_grad() # zero the parameter gradients outputs = net(inputs) # forward pass loss = criterion(outputs, labels) # calculate loss loss.backward() # backward pass optimizer.step() # update parameters running_loss += loss.item() print('Epoch %d, loss: %.3f' % (epoch+1, running_loss)) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值