torch.nn.Sequential()詳解

  • 2021 年 10 月 20 日
  • 筆記

參考:官方文檔    源碼

 

官方文檔

nn.Sequential
  A sequential container. Modules will be added to it in the order they are passed in the constructor. Alternatively, an ordered dict of modules can also be passed in.
  一個有序的容器,神經網路模組將按照在傳入構造器的順序依次被添加到計算圖中執行,同時以神經網路模組為元素的有序字典也可以作為傳入參數。

 

方式一:

  作為一個有順序的容器,將特定神經網路模組按照在傳入構造器的順序依次被添加到計算圖中執行。

官方Example:

model = nn.Sequential(
          nn.Conv2d(1,20,5),
          nn.ReLU(),
          nn.Conv2d(20,64,5),
          nn.ReLU()
        )
# When `model` is run,input will first be passed to `Conv2d(1,20,5)`.
# The output of `Conv2d(1,20,5)` will be used as the input to the first `ReLU`;
# the output of the first `ReLU` will become the input for `Conv2d(20,64,5)`.
# Finally, the output of `Conv2d(20,64,5)` will be used as input to the second `ReLU`

例子:
net = nn.Sequential(
    nn.Linear(num_inputs, num_hidden)
    # 傳入其他層
    )

方式二:
  將以特定神經網路模組為元素的有序字典(OrderedDict)為參數傳入。
官方 Example:
model = nn.Sequential(OrderedDict([
          ('conv1', nn.Conv2d(1,20,5)),
          ('relu1', nn.ReLU()),
          ('conv2', nn.Conv2d(20,64,5)),
          ('relu2', nn.ReLU())
        ]))
例子:
net = nn.Sequential()
net.add_module('linear', nn.Linear(num_inputs, 1))
# net.add_module ......

源碼分析

初始化函數 init 

    def __init__(self, *args):
        super(Sequential, self).__init__()
        if len(args) == 1 and isinstance(args[0], OrderedDict):
            for key, module in args[0].items():
                self.add_module(key, module)
        else:
            for idx, module in enumerate(args):
                self.add_module(str(idx), module)

  首先使用 if 條件判斷,若傳入的參數為1個,且類型為 OrderedDict,將通過字典索引的方式利用 add_module 函數 將子模組添加到現有模組中。否則,通過 for 循環遍歷參數,將所有的子模組添加到現有中。 注意,Sequential 模組的初始換函數沒有異常處理。

forward 函數

    def forward(self, input):
        for module in self:
            input = module(input)
        return input

  因為每一個 module 都繼承於 nn.Module,都會實現 __call__ 與 forward 函數,所以 forward 函數中通過 for 循環依次調用添加到 self._module 中的子模組,最後輸出經過所有神經網路層的結果。