(pytorch-深度学习系列)pytorch构造深度学习模型-学习笔记
pytorch構造深度學習模型
1. 通過繼承module類的方式來構造模型
Module類是nn模塊里提供的一個模型構造類,是所有神經網絡模塊的基類。
可以繼承基類并重構 __init()__函數和forward()forward()forward()函數的方式來構造模型。
以下是一個構造一個模型的例子:
import torch from torch import nnclass MLP(nn.Module):# 聲明帶有模型參數的層,這里聲明了兩個全連接層def __init__(self, **kwargs):# 調用MLP父類Module的構造函數來進行必要的初始化。這樣在構造實例時還可以指定其他函數super(MLP, self).__init__(**kwargs)self.hidden = nn.Linear(784, 256) # 隱藏層self.act = nn.ReLU()self.output = nn.Linear(256, 10) # 輸出層# 定義模型的前向計算,即如何根據輸入x計算返回所需要的模型輸出def forward(self, x):a = self.act(self.hidden(x))return self.output(a)實例化剛剛構建的MLP類得到模型變量net,net(X)會調用MLP繼承自Module類的__call__函數,這個函數將調用MLP類定義的forward函數來完成前向計算。
X = torch.rand(2, 784) net = MLP() print(net) net(X)2. 通過Sequential類定義簡單的模型
如果定義的模型的前向計算就是簡單的串聯各層的計算時,可以通過Sequential類快速定義模型。它可以接收一個子模塊的有序字典(OrderedDict)或者一系列子模塊作為參數來逐一添加Module的實例,而模型的前向計算就是將這些實例按添加的順序逐一計算。
定義一個與Sequential類有相同功能的類:ep_sequential來解讀Sequential類的工作機制:
class ep_sequential(nn.Module):from collections import OrderedDictdef __init__(self, *args):super(ep_sequential, self).__init__()if len(args) == 1 and isinstance(args[0], OrderedDict): # 如果傳入的是一個OrderedDictfor key, module in args[0].items():self.add_module(key, module) # add_module方法會將module添加進self._modules(一個OrderedDict)else: # 傳入的是一些Modulefor idx, module in enumerate(args):self.add_module(str(idx), module)def forward(self, input):# self._modules返回一個 OrderedDict,保證會按照成員添加時的順序遍歷成員for module in self._modules.values():input = module(input)return input這里通過forward函數就可以看出Sequential類實現的是簡單的串聯各層
net = ep_equential(nn.Linear(128, 256),nn.ReLU(),nn.Linear(256, 10), ) print(net) net(X)3. 使用ModuleList類
ModuleList接收一個子模塊的列表作為輸入,可以像List那樣進行append和extend操作:
net = nn.ModuleList([nn.Linear(128, 256), nn.ReLU()]) net.append(nn.Linear(256, 10)) # # 類似List的append操作 print(net[-1]) # 類似List的索引訪問 print(net) # net(torch.zeros(1, 128)) # 會報NotImplementedErrorModuleList僅僅是一個儲存各種模塊的列表,這些模塊之間沒有聯系也沒有順序(所以不用保證相鄰層的輸入輸出維度匹配),而且沒有實現forward功能需要自己實現,所以上面執行net(torch.zeros(1, 128))會報NotImplementedError;而Sequential內的模塊需要按照順序排列,要保證相鄰層的輸入輸出大小相匹配,內部forward功能已經實現。
這是官網的例子:
class MyModule(nn.Module):def __init__(self):super(MyModule, self).__init__()self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])def forward(self, x):# ModuleList can act as an iterable, or be indexed using intsfor i, l in enumerate(self.linears):x = self.linears[i // 2](x) + l(x)return x但是,ModuleList并不是一般的list,加入到ModuleList里的所有模塊的參數會被自動添加到網絡中。
下面的例子進行了對比:
輸出:
net1: torch.Size([10, 10]) torch.Size([10]) net2:從結果可以看出,使用ModuleList 初始化網絡層,那么該層參數就會被自動加入調用ModuleList的網絡的模型中。
4. 使用ModuleDict類
ModuleDict接收一個子模塊的字典作為輸入, 類似ModuleList,可以像字典那樣進行添加訪問操作:
net = nn.ModuleDict({'linear': nn.Linear(128, 256),'act': nn.ReLU(), }) net['output'] = nn.Linear(256, 10) # 添加 print(net['linear']) # 訪問 print(net.output) print(net) # net(torch.zeros(1, 128)) # 會報NotImplementedError和ModuleList一樣,ModuleDict實例僅僅是存放了一些模塊的字典,并沒有定義forward函數。同樣,ModuleDict也與Python的普通的Dict不同,ModuleDict里的所有模塊的參數會被自動添加到整個網絡中。
總結
以上是生活随笔為你收集整理的(pytorch-深度学习系列)pytorch构造深度学习模型-学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么琴键要排成等比数列?
- 下一篇: (pytorch-深度学习系列)读取和存