人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

人工智能專欄限時打折中

以下幾個專欄限時打折中,歡迎訂閱


正文


為方便用戶使用,PyTorch實現了神經網絡中絕大多數的layer,這些layer都繼承於nn.Module,封裝了可學習參數parameter,並實現了forward函數,且很多都專門針對GPU運算進行了CuDNN優化,其速度和性能都十分優異。

如nn.Linear(in_features, out_features, bias),需關注這三個參數的作用。

如nn.Linear中有weight和bias兩個可學習參數輸入輸出的形狀,如nn.linear的輸入形狀是(N, input_features),輸出為(N,output_features),N是batch_size。

在PyTorch裡面編寫神經網絡,所有的層結構和損失函數都來自於torch.nn,所有的模型構建都是從這個基類 nn.Module 繼承的,於是有了下面這個模板。

class net_name(nn.Moudle) :

def __init__ (self,other_ments) :

super(net_name,self). __init__()

self.conv1=nn.Conv2d(in_channels, out_channels, kernel_size)

# other network l ayer 其它網絡層

def forward(self, x):

x=self.conv1(x)

return x

這樣就建立了一個計算圖 ,並且這個結構可以複用多次,每次調用就相當於用該計算圖定義的相同參數做一次前向傳播,這得益於 PyTorch 的自動求導功能,所以我們不需要自己編寫反向傳播,而所有的網絡層都是由 nn 這個包得到的,比如線性層nn.Linear,等之後使用的時候我們可以詳細地介紹每一種網絡對應的結構,以及如何調用。

定義完模型之後 ,我們需要通過nn這個包來定義損失函數。 常見的損失函數都已經定義在了nn巾,比如均方誤差 、多分類的交叉熵,以及二分類的交叉熵,等等,調用這些已經定義好的損失函數也很簡單:

criterion = nn.CrossEntropyLoss( )

loss = criterion(output, target)

這樣就能求得我們的輸出和真實目標之間的損失函數了

常見的神經網絡層:

卷積層conv = nn.Conv2d(1, 1, (3, 3), 1, bias=False)

池化層pool = nn.AvgPool2d(2,2)

Linear:全連接層linear = nn.Linear(3, 4)

BatchNorm:批規範化層bn = nn.BatchNorm1d(4)

Dropout:dropout層dropout = nn.Dropout(0.5)#0.5的概率捨棄

激活函數relu = nn.ReLU(True)

# Embedding層,有4個詞,每個詞用5維的向量表示

embedding = nn.Embedding(4, 5)

搭建網絡的兩種方式

我們在搭建神經網絡的時候,可以將多個神經網絡層組合在一起,我們可以使用Sequential和ModuleList這兩種方式。

我們先來看一下Sequential,它我們可以看作是一個module

# Sequential的三種寫法

寫法一:為每一個神經網絡層添加一個名字

net1 = nn.Sequential()

net1.add_module('conv', nn.Conv2d(3, 3, 3))

net1.add_module('batchnorm', nn.BatchNorm2d(3))

net1.add_module('activation_layer', nn.ReLU())

人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

因為有名字,所以我們可以根據名字來取出神經網絡的每一層

net1.conv

net1.batchnorm

前向傳播out=net1(input)

寫法二:

net2 = nn.Sequential(

nn.Conv2d(3, 3, 3),

nn.BatchNorm2d(3),

nn.ReLU()

)

人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

這個沒有名字,我們可以通過索引取出Sequential中神經網路的每一層

net2[0]

前向傳播out=net2(input)

寫法三:使用OrderedDict將神經網絡層封裝為一個字典,然後傳遞到Sequential中

from collections import OrderedDict

net3= nn.Sequential(OrderedDict([

('conv1', nn.Conv2d(3, 3, 3)),

('bn1', nn.BatchNorm2d(3)),

('relu1', nn.ReLU())

]))


人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

可以根據名字取出神經網絡的每一層

net3.conv1

前向傳播

方式一:output = net3(input)

方式二:output = net3.relu1(net1.batchnorm(net1.conv(input)))

ModuleList的使用方式,注意ModuleList在Module中使用它的時候(在實現nn.Module的__init__()方法中使用的時候),才能自動識別為子module。

class Net4(nn.Module):

def __init__(self):

super(Net4, self).__init__()

self.module_list = nn.ModuleList([nn.Conv2d(3, 3, 3), nn.ReLU()])

def forward(self):

model = MyModule()

ModuleList其實就是一個List,只不過在Module中它會自動識別為module,識別為module的好處就是它會作為整個module的一個整體,在反向傳播中跟新其參數。


除ModuleList之外還有ParameterList,其是一個可以包含多個parameter的類list對象。我們如果要是在init中用到list,我們應該用ModuleList或ParameterList,而不是使用list。

class MyLinear(nn.Module):

def __init__(self, inp, outp):

super(MyLinear, self).__init__()

# requires_grad = True

self.w = nn.Parameter(torch.randn(outp, inp))

self.b = nn.Parameter(torch.randn(outp))

def forward(self, x):

x = x @ self.w.t() + self.b

return x

人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

這個表示建立一個全連接層,w和b就是全連接層的權重參數,其中w的維度是(輸出,輸入)

nn.Parameter中會自帶梯度求梯度功能

人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

獲取參數

Net.parameters()表示獲取net的所有參數

List表示轉換為列表形式,此時這個列表應該是[w0,b0,w1,b1]

人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

遍歷所有的模型的參數,其中name表示模型的參數,注意這個名字中沒有net.1,這是因為nn.ReLU是模型的第二層,但是這裡並沒有參數,所以net.0之後沒有net.1,而直接是net.2

人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

Named——children表示獲取net的網絡的孩子結點

人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

獲取所有結點,從子結點開始逐漸到孫子結點

自定義展開層

人工智能編程:神經網絡的快速搭建模塊,以及網絡模型參數的獲取

class Flatten(nn.Module):

def __init__(self):

super(Flatten, self).__init__()

def forward(self, input):

return input.view(input.size(0), -1)

class TestNet(nn.Module):

def __init__(self):

super(TestNet, self).__init__()

self.net = nn.Sequential(nn.Conv2d(1, 16, stride=1, padding=1),

nn.MaxPool2d(2, 2),

Flatten(),

nn.Linear(1*14*14, 10))

def forward(self, x):

return self.net(x)


分享到:


相關文章: