【501】pytorch教程之nn.Module類詳解


參考: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()

  

 

 

 

 

 


免責聲明!

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



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