Pytorch系列:(三)模型構建


nn.Module 函數詳解

nn.Module是所有網絡模型結構的基類,無論是pytorch自帶的模型,還是要自定義模型,都需要繼承這個類。這個模塊包含了很多子模塊,如下所示,_parameters存放的是模型的參數,_buffers也存放的是模型的參數,但是是那些不需要更新的參數。帶hook的都是鈎子函數,詳見鈎子函數部分。

self._parameters = OrderedDict()
self._buffers = OrderedDict()
self._non_persistent_buffers_set = set()
self._backward_hooks = OrderedDict()
self._is_full_backward_hook = None
self._forward_hooks = OrderedDict()
self._forward_pre_hooks = OrderedDict()
self._state_dict_hooks = OrderedDict()
self._load_state_dict_pre_hooks = OrderedDict()
self._modules = OrderedDict()

此外,每一個模塊還內置了一些常用的方法來幫助訪問和操作網絡。

load_state_dict() #加載模型權重參數 

parameters() #讀取所有參數

named_parameters() #讀取參數名稱和參數

buffers() #讀取self.named_buffers中的參數

named_buffers() #讀取self.named_buffers中的參數名稱和參數

children() #讀取模型中,所有的子模型

named_children() #讀取子模型名稱和子模型

requires_grad_() #設置模型是否開啟梯度反向傳播 

Parameter類

Parameter是Tensor子類,所以繼承了Tensor類的屬性。例如data和grad屬性,可以根據data來訪問參數數值,用grad來訪問參數梯度。

weight_0 = nn.Parameters(torch.randn(10,10))

print(weight_0.data)
print(weight_0.grad) 

定義變量的時候,nn.Parameter會被自動加入到參數列表中去

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel,self).__init__()
        self.weight1 = nn.Parameter(torch.randn(10,10))
        self.weight2 = torch.randn(10,10)
    def forward(self,x):
        pass 
  
model = MyModel()
for name,param in model.named_parameters():
    print(name)
  
output:  weight1 

ParameterList

接定義成Parameter類外,還可以使用ParameterList和ParameterDict分別定義參數的列表和字典。ParameterList接收一個Parameter實例的列表作為輸入然后得到一個參數列表,使用的時候可以用索引來訪問某個參數,另外也可以使用append和extend在列表后面新增參數。

params = nn.ParameterList(
  [nn.Parameter(torch.randn(10,10)) for i in range(5)]
)

params.append(nn.Parameter(torch.randn(3,3)))

ParameterDict

可以像添加字典數據那樣添加參數

params = nn.ParameterDict({
    'linear1':nn.Parameter(torch.randn(10,5)),
    'linear2':nn.Parameter(torch.randn(5,2))
}) 

模型構建

使用Sequential構建模型

# 寫法一
net = nn.Sequential(
    nn.Linear(num_inputs, 1)
    # 此處還可以傳入其他層
    )

# 寫法二
net = nn.Sequential()
net.add_module('linear', nn.Linear(num_inputs, 1))
# net.add_module ......

# 寫法三
from collections import OrderedDict
net = nn.Sequential(OrderedDict([
          ('linear', nn.Linear(num_inputs, 1))
          # ......
        ]))

print(net)

自定義模型

  1. 無參數模型

下面是一個展開操作,比如將2維圖像展開成一維

class Flatten(nn.Module):
    def __init__(self):
        super(Flatten,self).__init__()
      
    def forward(self,input):
        return input.view(input.size(0),-1) 
  1. 有參數模型

自定義一個Linear層

class MLinear(nn.Module):
    def __init__(self,input,output):
        super(MyLinear,self).__init__()
        
        self.w = nn.Parameter(torch.randn(input,output))
        self.b = nn.Parameter(torch.randn(output))
      
    def foward(self,x):
         x = self.w @ x + self.b
         return x  
  1. 組合模型
class Model(nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.l1 = nn.Linear(10,20)
        self.l2 = nn.Linear(20,5)
        

    def forward(self,x):
        x = self.l1(x)
        x = self.l2(x)
        
        return x

ModuleList & ModuleDict

ModuleList 和 ModuleDict都是繼承與nn.Module, 與Seuqential不同的是,ModuleList 和 ModuleDict沒有自帶forward方法,所以只能作為一個模塊和其他自定義方法進行組合。下面是使用示例:

class MyModuleList(nn.Module):
    def __init__(self):
        super(MyModuleList, self).__init__()
        self.linears = nn.ModuleList(
          [nn.Linear(10, 10) for i in range(3)]
        )
     def forward(self, x):
        for linear in self.linears:
            x = linear(x)
        return x
        
        
class MyModuleDict(nn.Module):
    def __init__(self):
        super(MyModuleDict, self).__init__()
        self.linears = nn.ModuleDict({
          "linear1":nn.Linear(10,10),
          "linear2":nn.Linear(10,10)
        })
     def forward(self, x):
        x = self.linears["linear1"](x)
        x = self.linears["linear2"](x)
        return x


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM