日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

(pytorch-深度学习系列)模型参数的初始化与访问操作-学习笔记

發布時間:2024/8/23 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (pytorch-深度学习系列)模型参数的初始化与访问操作-学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

模型參數的初始化與訪問操作

學習 如何初始化以及訪問模型參數,以及如何在多層之間共享模型參數
首先定義一個含有單個隱藏層的多層感知機,使用默認方式初始化該模型的參數,并且進行一次前向計算:

import torch from torch import nn from torch.nn import initnet = nn.Sequential(nn.Linear(4, 3), nn.ReLU(), nn.Linear(3, 1)) # pytorch已進行默認初始化print(net) X = torch.rand(2, 4) Y = net(X).sum()

輸出:

Sequential((0): Linear(in_features=4, out_features=3, bias=True)(1): ReLU()(2): Linear(in_features=3, out_features=1, bias=True) )

接著嘗試訪問模型參數
由于Sequentail類與Module類的繼承關系,可以通過Module類的parameters()函數或者named_parameters()來訪問所有的參數:

print(type(net.named_parameters())) for name, param in net.named_parameters():print(name, param.size())

輸出:
named_parameters()返回參數的名稱以及其該參數值(tensor變量)

<class 'generator'> 0.weight torch.Size([3, 4]) 0.bias torch.Size([3]) 2.weight torch.Size([1, 3]) 2.bias torch.Size([1])

其中“0“、”2“為層數索引,我們可以通過下面的方法訪問網絡的任意一層:

for name, param in net[0].named_parameters():print(name, param.size(), type(param))

輸出結果:

weight torch.Size([3, 4]) <class 'torch.nn.parameter.Parameter'> bias torch.Size([3]) <class 'torch.nn.parameter.Parameter'>

由于我們采用了下標索引訪問網絡的某一層,所以結果中沒有了層數索引,返回的參數類型為:“torch.nn.parameter.Parameter”,這是Tensor的子類,需要注意的是,如果一個Tensor是Parameter,他就會自動被添加到模型的參數列表中。
我們可以用下面的例子來理解:

class MyModel(nn.Module):def __init__(self, **kwargs):super(MyModel, self).__init__(**kwargs)self.weight1 = nn.Parameter(torch.rand(20, 20))self.weight2 = torch.rand(20, 20)def forward(self, x):passn = MyModel() for name, param in n.named_parameters():print(name)

輸出:

weight1

發現只輸出了參數weight1,但是沒有輸出參數weight2,這說明參數weight1在參數列表中,而參數weight2不在參數列表中

初始化模型參數

將權重參數初始化成均值為0、標準差為0.01的正態分布隨機數,并依然將偏差參數清零:

for name, param in net.named_parameters():if 'weight' in name:init.normal_(param, mean=0, std=0.01)print(name, param.data)for name, param in net.named_parameters():if 'bias' in name:init.constant_(param, val=0)print(name, param.data)

我們查看torch.nn.init.normal_函數,觀察torch默認初始化的方式:

def normal_(tensor, mean=0, std=1):with torch.no_grad():return tensor.normal_(mean, std)

這里使用一個inplace改變Tensor的值,這個過程不記錄梯度
根據相同的實現方式,我們來實現一個自定義的初始化方法。在下面的例子里,我們令權重有一半概率初始化為0,有另一半概率初始化為[?10,?5][-10,-5][?10,?5][5,10][5,10][5,10]兩個區間里均勻分布的隨機數。

def init_weight_(tensor):with torch.no_grad():tensor.uniform_(-10, 10)tensor *= (tensor.abs() >= 5).float()for name, param in net.named_parameters():if 'weight' in name:init_weight_(param)

我們還可以使用在之前的blog中提到的改變Parameter的data屬性,來改寫模型參數的同時不改變參數的梯度:

for name, param in net.named_parameters():if 'bias' in name:param.data += 1print(name, param.data)

這里通過param.data改變模型參數,但是不會影響param的梯度。

共享模型的參數

如何實現在多層之間共享模型的參數
(1)對Sequential中傳入同一個Module實例,這兩個層的參數是共享的:

linear = nn.Linear(1, 1, bias=False) net = nn.Sequential(linear, linear) print(net) for name, param in net.named_parameters():init.constant_(param, val=3)print(name, param.data)

輸出:

Sequential((0): Linear(in_features=1, out_features=1, bias=False)(1): Linear(in_features=1, out_features=1, bias=False) ) 0.weight tensor([[3.]])

根據輸出結果可以發現,網絡有兩層,但是weight參數只有一個,這時候,這兩個層共享參數。

因為模型參數包含了梯度,所以在反向傳播計算時,這些共享參數的梯度是累加的:

x = torch.ones(1, 1) y = net(x).sum() print(y) y.backward() print(net[0].weight.grad) # 單次梯度是3,兩次所以就是6,weight的值在上面輸出了,是3

輸出:

tensor(9., grad_fn=<SumBackward0>) tensor([[6.]])

總結

以上是生活随笔為你收集整理的(pytorch-深度学习系列)模型参数的初始化与访问操作-学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。