参考:pytorch教程之nn.Module类详解——使用Module类来自定义模型
pytorch中对于一般的序列模型,直接使用torch.nn.Sequential类及可以实现,这点类似于keras,但是更多的时候面对复杂的模型,比如:多输入多输出、多分支模型、跨层连接模型、带有自定义层的模型等,就需要自己来定义一个模型了。本文将详细说明如何让使用Mudule类来自定义一个模型。
pytorch里面一切自定义操作基本上都是继承nn.Module类来实现的。
我们在定义自已的网络的时候,需要继承nn.Module类,并重新实现构造函数__init__构造函数和forward这两个方法。但有一些注意技巧:
- 一般把网络中具有可学习参数的层(如全连接层、卷积层等)放在构造函数__init__()中,当然我也可以吧不具有参数的层也放在里面;
- 一般把不具有可学习参数的层(如ReLU、dropout、BatchNormanation层)可放在构造函数中,也可不放在构造函数中,如果不放在构造函数__init__里面,则在forward方法里面可以使用nn.functional来代替
- forward方法是必须要重写的,它是实现模型的功能,实现各个层之间的连接关系的核心。
所有放在构造函数__init__里面的层的都是这个模型的“固有属性”。
import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self): # 固定内容 super(Model, self).__init__() # 定义相关的函数 self.conv1 = nn.Conv2d(1, 20, 5) self.conv2 = nn.Conv2d(20, 20, 5) def forward(self, x): # 构建模型结构,可以使用F函数内容,其他调用__init__里面的函数 x = F.relu(self.conv1(x)) # 返回最终的结果 return F.relu(self.conv2(x))
☀☀☀<< 举例 >>☀☀☀
代码一:
import torch N, D_in, H, D_out = 64, 1000, 100, 10 torch.manual_seed(1) x = torch.randn(N, D_in) y = torch.randn(N, D_out) #-----changed part-----# model = torch.nn.Sequential( torch.nn.Linear(D_in, H), torch.nn.ReLU(), torch.nn.Linear(H, D_out), ) #-----changed part-----# loss_fn = torch.nn.MSELoss(reduction='sum') learning_rate = 1e-4 optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) for t in range(500): y_pred = model(x) loss = loss_fn(y_pred, y) if t % 100 == 99: print(t, loss.item()) optimizer.zero_grad() loss.backward() optimizer.step()
代码二:
import torch N, D_in, H, D_out = 64, 1000, 100, 10 torch.manual_seed(1) x = torch.randn(N, D_in) y = torch.randn(N, D_out) #-----changed part-----# class Alex_nn(nn.Module): def __init__(self): super(Alex_nn, self).__init__() self.h1 = torch.nn.Linear(D_in, H) self.h1_relu = torch.nn.ReLU() self.output = torch.nn.Linear(H, D_out) def forward(self, x): h1 = self.h1(x) h1_relu = self.h1_relu(h1) output = self.output(h1_relu) return output model = Alex_nn() #-----changed part-----# loss_fn = torch.nn.MSELoss(reduction='sum') learning_rate = 1e-4 optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) for t in range(500): y_pred = model(x) loss = loss_fn(y_pred, y) if t % 100 == 99: print(t, loss.item()) optimizer.zero_grad() loss.backward() optimizer.step()
代码三:
import torch N, D_in, H, D_out = 64, 1000, 100, 10 torch.manual_seed(1) x = torch.randn(N, D_in) y = torch.randn(N, D_out) #-----changed part-----# class Alex_nn(nn.Module): def __init__(self, D_in_, H_, D_out_): super(Alex_nn, self).__init__() self.D_in = D_in_ self.H = H_ self.D_out = D_out_ self.h1 = torch.nn.Linear(self.D_in, self.H) self.h1_relu = torch.nn.ReLU() self.output = torch.nn.Linear(self.H, self.D_out) def forward(self, x): h1 = self.h1(x) h1_relu = self.h1_relu(h1) output = self.output(h1_relu) return output model = Alex_nn(D_in, H, D_out) #-----changed part-----# loss_fn = torch.nn.MSELoss(reduction='sum') learning_rate = 1e-4 optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) for t in range(500): y_pred = model(x) loss = loss_fn(y_pred, y) if t % 100 == 99: print(t, loss.item()) optimizer.zero_grad() loss.backward() optimizer.step()
<iframe height="240" style="display: none" width="320"></iframe>