(pytorch-深度学习系列)模型参数的初始化与访问操作-学习笔记
模型參數(shù)的初始化與訪問操作
學(xué)習(xí) 如何初始化以及訪問模型參數(shù),以及如何在多層之間共享模型參數(shù)
首先定義一個(gè)含有單個(gè)隱藏層的多層感知機(jī),使用默認(rèn)方式初始化該模型的參數(shù),并且進(jìn)行一次前向計(jì)算:
輸出:
Sequential((0): Linear(in_features=4, out_features=3, bias=True)(1): ReLU()(2): Linear(in_features=3, out_features=1, bias=True) )接著嘗試訪問模型參數(shù):
由于Sequentail類與Module類的繼承關(guān)系,可以通過Module類的parameters()函數(shù)或者named_parameters()來訪問所有的參數(shù):
輸出:
named_parameters()返回參數(shù)的名稱以及其該參數(shù)值(tensor變量)
其中“0“、”2“為層數(shù)索引,我們可以通過下面的方法訪問網(wǎng)絡(luò)的任意一層:
for name, param in net[0].named_parameters():print(name, param.size(), type(param))輸出結(jié)果:
weight torch.Size([3, 4]) <class 'torch.nn.parameter.Parameter'> bias torch.Size([3]) <class 'torch.nn.parameter.Parameter'>由于我們采用了下標(biāo)索引訪問網(wǎng)絡(luò)的某一層,所以結(jié)果中沒有了層數(shù)索引,返回的參數(shù)類型為:“torch.nn.parameter.Parameter”,這是Tensor的子類,需要注意的是,如果一個(gè)Tensor是Parameter,他就會自動被添加到模型的參數(shù)列表中。
我們可以用下面的例子來理解:
輸出:
weight1發(fā)現(xiàn)只輸出了參數(shù)weight1,但是沒有輸出參數(shù)weight2,這說明參數(shù)weight1在參數(shù)列表中,而參數(shù)weight2不在參數(shù)列表中
初始化模型參數(shù)
將權(quán)重參數(shù)初始化成均值為0、標(biāo)準(zhǔn)差為0.01的正態(tài)分布隨機(jī)數(shù),并依然將偏差參數(shù)清零:
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_函數(shù),觀察torch默認(rèn)初始化的方式:
def normal_(tensor, mean=0, std=1):with torch.no_grad():return tensor.normal_(mean, std)這里使用一個(gè)inplace改變Tensor的值,這個(gè)過程不記錄梯度
根據(jù)相同的實(shí)現(xiàn)方式,我們來實(shí)現(xiàn)一個(gè)自定義的初始化方法。在下面的例子里,我們令權(quán)重有一半概率初始化為0,有另一半概率初始化為[?10,?5][-10,-5][?10,?5]和[5,10][5,10][5,10]兩個(gè)區(qū)間里均勻分布的隨機(jī)數(shù)。
我們還可以使用在之前的blog中提到的改變Parameter的data屬性,來改寫模型參數(shù)的同時(shí)不改變參數(shù)的梯度:
for name, param in net.named_parameters():if 'bias' in name:param.data += 1print(name, param.data)這里通過param.data改變模型參數(shù),但是不會影響param的梯度。
共享模型的參數(shù)
如何實(shí)現(xiàn)在多層之間共享模型的參數(shù)
(1)對Sequential中傳入同一個(gè)Module實(shí)例,這兩個(gè)層的參數(shù)是共享的:
輸出:
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.]])根據(jù)輸出結(jié)果可以發(fā)現(xiàn),網(wǎng)絡(luò)有兩層,但是weight參數(shù)只有一個(gè),這時(shí)候,這兩個(gè)層共享參數(shù)。
因?yàn)槟P蛥?shù)包含了梯度,所以在反向傳播計(jì)算時(shí),這些共享參數(shù)的梯度是累加的:
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.]])總結(jié)
以上是生活随笔為你收集整理的(pytorch-深度学习系列)模型参数的初始化与访问操作-学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 求两列数据组合_mysql
- 下一篇: python读取json格式的超参数