nn.Module、nn.Sequential和torch.nn.parameter学习笔记
nn.Module、nn.Sequential和torch.nn.parameter是利用pytorch構(gòu)建神經(jīng)網(wǎng)絡(luò)最重要的三個(gè)函數(shù)。搞清他們的具體用法是學(xué)習(xí)pytorch的必經(jīng)之路。
目錄
- nn.Module
- nn.Sequential
- torch.nn.Parameter
nn.Module
nn.Module中,自定義層的步驟:
1.自定義一個(gè)Module的子類,實(shí)現(xiàn)兩個(gè)基本的函數(shù):
(1)構(gòu)造 init 函數(shù) (2)層的邏輯運(yùn)算函數(shù),即正向傳播的函數(shù)
2.在構(gòu)造 init 函數(shù)中實(shí)現(xiàn)層的參數(shù)定義。 比如Linear層的權(quán)重和偏置,Conv2d層的in_channels, out_channels, kernel_size, stride=1,padding=0, dilation=1, groups=1,bias=True, padding_mode='zeros’這一系列參數(shù);
3.在forward函數(shù)里實(shí)現(xiàn)前向運(yùn)算。 一般都是通過torch.nn.functional.***函數(shù)來實(shí)現(xiàn),如果該層含有權(quán)重,那么權(quán)重必須是nn.Parameter類型。
4.補(bǔ)充:一般情況下,我們定義的參數(shù)是可以求導(dǎo)的,但是自定義操作如不可導(dǎo),需要實(shí)現(xiàn)backward函數(shù)。
例:
# 定義一個(gè) my_layer.pyimport torchclass MyLayer(torch.nn.Module):'''因?yàn)檫@個(gè)層實(shí)現(xiàn)的功能是:y=weights*sqrt(x2+bias),所以有兩個(gè)參數(shù):權(quán)值矩陣weights偏置矩陣bias輸入 x 的維度是(in_features,)輸出 y 的維度是(out_features,) 故而bias 的維度是(in_fearures,),注意這里為什么是in_features,而不是out_features,注意體會(huì)這里和Linear層的區(qū)別所在weights 的維度是(in_features, out_features)注意這里為什么是(in_features, out_features),而不是(out_features, in_features),注意體會(huì)這里和Linear層的區(qū)別所在'''def __init__(self, in_features, out_features, bias=True):super(MyLayer, self).__init__() # 和自定義模型一樣,第一句話就是調(diào)用父類的構(gòu)造函數(shù)self.in_features = in_featuresself.out_features = out_featuresself.weight = torch.nn.Parameter(torch.Tensor(in_features, out_features)) # 由于weights是可以訓(xùn)練的,所以使用Parameter來定義if bias:self.bias = torch.nn.Parameter(torch.Tensor(in_features)) # 由于bias是可以訓(xùn)練的,所以使用Parameter來定義else:self.register_parameter('bias', None)def forward(self, input):input_=torch.pow(input,2)+self.biasy=torch.matmul(input_,self.weight)return y自定義模型并訓(xùn)練import torchfrom my_layer import MyLayer # 自定義層N, D_in, D_out = 10, 5, 3 # 一共10組樣本,輸入特征為5,輸出特征為3 # 先定義一個(gè)模型class MyNet(torch.nn.Module):def __init__(self):super(MyNet, self).__init__() # 第一句話,調(diào)用父類的構(gòu)造函數(shù)self.mylayer1 = MyLayer(D_in,D_out)def forward(self, x):x = self.mylayer1(x)return xmodel = MyNet()print(model)'''運(yùn)行結(jié)果為:MyNet((mylayer1): MyLayer() # 這就是自己定義的一個(gè)層)'''下面開始訓(xùn)練# 創(chuàng)建輸入、輸出數(shù)據(jù)x = torch.randn(N, D_in) #(10,5)y = torch.randn(N, D_out) #(10,3)#定義損失函數(shù)loss_fn = torch.nn.MSELoss(reduction='sum')learning_rate = 1e-4#構(gòu)造一個(gè)optimizer對(duì)象optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)for t in range(10): # # 第一步:數(shù)據(jù)的前向傳播,計(jì)算預(yù)測(cè)值p_predy_pred = model(x)# 第二步:計(jì)算計(jì)算預(yù)測(cè)值p_pred與真實(shí)值的誤差loss = loss_fn(y_pred, y)print(f"第 {t} 個(gè)epoch, 損失是 {loss.item()}")# 在反向傳播之前,將模型的梯度歸零,這optimizer.zero_grad()# 第三步:反向傳播誤差loss.backward()# 直接通過梯度一步到位,更新完整個(gè)網(wǎng)絡(luò)的訓(xùn)練參數(shù)optimizer.step()nn.Sequential
torch.nn.Sequential是一個(gè)Sequential容器,模塊將按照構(gòu)造函數(shù)中傳遞的順序添加到模塊中。
與nn.Module相同,nn.Sequential也是用來構(gòu)建神經(jīng)網(wǎng)絡(luò)的,但nn.Sequential不需要像nn.Module那么多過程,可以快速構(gòu)建神經(jīng)網(wǎng)絡(luò)。
使用nn.Module可以根據(jù)自己的需求改變傳播過程。
這個(gè)構(gòu)建網(wǎng)絡(luò)的方法工作量略有減少,但有特殊需求的網(wǎng)絡(luò)還是要用nn.Module。
torch.nn.Parameter
torch.nn.Parameter是繼承自torch.Tensor的子類,其主要作用是作為nn.Module中的可訓(xùn)練參數(shù)使用。它與torch.Tensor的區(qū)別就是nn.Parameter會(huì)自動(dòng)被認(rèn)為是module的可訓(xùn)練參數(shù),即加入到parameter()這個(gè)迭代器中去;而module中非nn.Parameter()的普通tensor是不在parameter中的。
nn.Parameter的對(duì)象的requires_grad屬性的默認(rèn)值是True,即是可被訓(xùn)練的,這與torh.Tensor對(duì)象的默認(rèn)值相反。
在nn.Module類中,pytorch也是使用nn.Parameter來對(duì)每一個(gè)module的參數(shù)進(jìn)行初始化的。
例:
顯然,在__init__(self, in_features, out_features, bias=True)中,下面的代碼使用了nn.Parameter()對(duì)weights進(jìn)行了初始化
參考:
https://blog.csdn.net/qq_27825451/article/details/90705328
https://blog.csdn.net/qq_28753373/article/details/104179354
總結(jié)
以上是生活随笔為你收集整理的nn.Module、nn.Sequential和torch.nn.parameter学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ccd视觉定位教程_CCD视觉定位的激光
- 下一篇: 生产者消费者案例