北京 互聯(lián)網公司網站優(yōu)化及推廣方案
改編自李沐老師《動手深度學習》5.2. 參數(shù)管理 — 動手學深度學習 2.0.0 documentation (d2l.ai)
? 在深度學習中,一旦我們選擇了模型架構并設置了超參數(shù),我們就會進入訓練階段。訓練的目標是找到能夠最小化損失函數(shù)的模型參數(shù)。這些參數(shù)在訓練后用于預測,有時我們也需要將它們提取出來,以便在其他環(huán)境中使用,或者保存模型以便在其他軟件中執(zhí)行,甚至是為了科學理解而進行檢查。
參數(shù)訪問
訪問模型參數(shù)
在PyTorch中,我們可以通過模型的層來訪問參數(shù)。每一層都有自己的參數(shù),比如權重和偏置。我們可以通過索引來訪問這些參數(shù)。
import torch
from torch import nn# 定義一個簡單的模型
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
X = torch.rand(size=(2, 4))
output = net(X)
我們可以通過索引來檢查模型中特定層的參數(shù)。
# 打印第二層(全連接層)的參數(shù)
print(net[2].state_dict())
這會顯示第二層的權重和偏置,它們是模型學習的關鍵部分。
訪問特定參數(shù)的值
我們可以進一步提取特定參數(shù)的值。這通常在我們需要對參數(shù)進行特定操作時非常有用。
# 打印第二層的偏置參數(shù)
print(net[2].bias)
print(net[2].bias.data)
參數(shù)是復合對象,包含值、梯度和其他信息。在沒有進行反向傳播的情況下,參數(shù)的梯度處于初始狀態(tài)。
一次性訪問所有參數(shù)
當需要對所有參數(shù)執(zhí)行操作時,可以一次性訪問所有參數(shù)。這在處理大型模型時尤其有用。
# 打印所有層的參數(shù)名稱和形狀
print(*[(name, param.shape) for name, param in net.named_parameters()])
從嵌套塊收集參數(shù)
當模型由多個子模塊組成時,我們可以通過類似列表索引的方式來訪問這些子模塊的參數(shù)。
# 定義一個子模塊
def block1():return nn.Sequential(nn.Linear(4, 8), nn.ReLU(),nn.Linear(8, 4), nn.ReLU())# 定義一個包含多個子模塊的模型
def block2():net = nn.Sequential()for i in range(4):net.add_module(f'block {i}', block1())return net# 創(chuàng)建一個包含嵌套子模塊的模型
rgnet = nn.Sequential(block2(), nn.Linear(4, 1))
output = rgnet(X)# 打印模型結構
print(rgnet)# 訪問嵌套子模塊的參數(shù)
print(rgnet[0][1][0].bias.data)
參數(shù)初始化
內置初始化
PyTorch提供了多種預置的初始化方法,我們可以根據(jù)需要選擇。
# 初始化所有權重為高斯隨機變量,偏置為0
def init_normal(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, mean=0, std=0.01)nn.init.zeros_(m.bias)
net.apply(init_normal)
自定義初始化
有時,我們需要自定義初始化方法來滿足特定的需求。
# 自定義初始化方法
def my_init(m):if type(m) == nn.Linear:print("Init", *[(name, param.shape)for name, param in m.named_parameters()][0])nn.init.uniform_(m.weight, -10, 10)m.weight.data *= m.weight.data.abs() >= 5net.apply(my_init)
參數(shù)綁定
有時我們希望在多個層間共享參數(shù)。在PyTorch中,我們可以通過引用同一個層的參數(shù)來實現(xiàn)這一點。
# 定義一個共享層
shared = nn.Linear(8, 8)# 使用共享層構建模型
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(),shared, nn.ReLU(),shared, nn.ReLU(),nn.Linear(8, 1))
output = net(X)# 檢查參數(shù)是否相同
print(net[2].weight.data[0] == net[4].weight.data[0])# 改變一個參數(shù),另一個也會改變
net[2].weight.data[0, 0] = 100
print(net[2].weight.data[0] == net[4].weight.data[0])
這個例子展示了如何在模型的不同層之間共享參數(shù),以及如何通過改變一個參數(shù)來影響另一個參數(shù)。這種技術在構建復雜的神經網絡時非常有用。