【Pytorch神经网络理论篇】 12 卷积神经网络实现+卷积计算的图解
1 卷積神經(jīng)網(wǎng)絡(luò)接口
1.1 卷積接口介紹
- torch.nn.functional.conv1d:實現(xiàn)按照1個維度進行的卷積操作,常用于處理序列數(shù)據(jù)。
- torch.nn.functional.conv2d:實現(xiàn)按照2個維度進行的卷積操作,常用于處理二維平面圖片。
- torch.nn.functional.conv3d:實現(xiàn)按照3個維度進行的卷積操作,常用于處理三維圖形數(shù)據(jù)。
1.2?卷積函數(shù)的定義
torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)?- input:輸入圖像的大小(minibatch,in_channels,H,W),是一個四維tensor
- filters:卷積核的大小(out_channels,in_channe/groups,H,W),是一個四維tensor
- bias:每一個channel的bias,是一個維數(shù)等于out_channels的tensor
- stride:一個數(shù)或者一個二元組(SH,SW),代表縱向和橫向的步長
- padding:一個數(shù)或者一個二元組(PH,PW ),代表縱向和橫向的填充值
- dilation:一個數(shù),代表卷積核內(nèi)部每個元素之間間隔元素的數(shù)目(不常用,默認為0)
- groups:一個數(shù),代表分組卷積時分的組數(shù),特別的當groups = in_channel時,就是在做逐層卷積(depth-wise conv).
1.2 卷積函數(shù)的類實現(xiàn)
class torch.nn.Conv2d(in_channels, out_channels, kennel_size, stride=1, padding=0, dilation=1, groups=1, bias=true)- in_channels(int) 輸入特征圖的通道數(shù)
- out_channels(int) 輸出特征圖的通道數(shù)
- kenal_size(int or tuple) 卷積核大小
- stride(int or tuple, optional) 卷積核的步長,默認為1
- padding(int or tuple,optional) 輸入的每一條邊補充0的層數(shù),默認為0
- dilation(int or tuple, optional) 卷積核元素間的距離,默認為1
- groups(int,optional)將原始輸入通道劃分成的組數(shù),默認為1
- bias(bool,optional) 默認為True,表示輸出的bias可學(xué)習
?
1.3 兩者區(qū)別
torch.nn.Conv2D是一個類,而torch.nn.functional.conv2d是一個函數(shù),在Sequential里面只能放nn.xxx,而nn.functional.xxx是不能放入Sequential里面的。
nn.Module 實現(xiàn)的 layer 是由 class Layer(nn.Module) 定義的特殊類,nn.functional 中的函數(shù)是純函數(shù),由 def function(input) 定義。
nn.functional.xxx 需要自己定義 weight,每次調(diào)用時都需要手動傳入 weight,而 nn.xxx 則不用。
1.4 卷積函數(shù)的操作步驟
1.5 卷積操作的類型
1.5.1 窄卷積(vaild卷積)
即生成的特征圖比原來的原始圖片小。它的步長是可變的。假如,滑動步長為S,原始圖片的維度為N1×N1。卷積核的大小為卷積后圖像大小為[(N1-N2)/S + 1]。
1.5.2 同卷積(same卷積),
卷積后的圖片尺寸與原始的一樣大,同卷積的步長是固定的,滑動步長為1。一般操作時都要使用padding操作(在原始圖片的外圍補0,來確保生成的尺寸不變)。
1.5.3 全卷積(full卷積),也稱反卷積,主要用作反卷積網(wǎng)絡(luò)中,用于圖像的恢復(fù)與還原。
將原始圖片里面的每個像素點都用卷積操作展開。如圖7-16所示,白色的塊是原始圖片,淺色的是卷積核,深色的是正在卷積操作的像素點。在全卷積操作的過程中,同樣需要對原有圖片進行padding操作,生成的結(jié)果會比原有的圖片尺寸大。步長固定為1,卷積核的大小為卷積后圖像大小為[N1-N2-1]
2 卷積函數(shù)的使用
2.1 定義卷積輸入變量 --- CNN_New.py(第01部分)
import torch### 1.1 定義輸入變量 # [batch,in_channels,in_height,in_width] # [訓(xùn)練時一個batch的圖片數(shù)量,圖像通道數(shù),圖片高度,圖片寬度] input1 = torch.ones([1,1,5,5]) input2 = torch.ones([1,2,5,5]) input3 = torch.ones([1,1,4,4])2.2 驗證卷積的補0規(guī)則 --- CNN_New.py(第02部分)
### 1.2 驗證補0規(guī)則 # 設(shè)置padding為1,在輸入數(shù)據(jù)上補1排0 padding1 = torch.nn.functional.conv2d(input1,torch.ones([1,1,1,1]),stride=1,padding=1) print(padding1) # 設(shè)置padding為1,在輸入數(shù)據(jù)上補2行0 padding2 = torch.nn.functional.conv2d(input1,torch.ones([1,1,1,1]),stride=1,padding=(1,2)) print(padding2)tensor([[[[0., 0., 0., 0., 0., 0., 0.],
? ? ? ? ? [0., 1., 1., 1., 1., 1., 0.],
? ? ? ? ? [0., 1., 1., 1., 1., 1., 0.],
? ? ? ? ? [0., 1., 1., 1., 1., 1., 0.],
? ? ? ? ? [0., 1., 1., 1., 1., 1., 0.],
? ? ? ? ? [0., 1., 1., 1., 1., 1., 0.],
? ? ? ? ? [0., 0., 0., 0., 0., 0., 0.]]]])
tensor([[[[0., 0., 0., 0., 0., 0., 0., 0., 0.],
? ? ? ? ? [0., 0., 1., 1., 1., 1., 1., 0., 0.],
? ? ? ? ? [0., 0., 1., 1., 1., 1., 1., 0., 0.],
? ? ? ? ? [0., 0., 1., 1., 1., 1., 1., 0., 0.],
? ? ? ? ? [0., 0., 1., 1., 1., 1., 1., 0., 0.],
? ? ? ? ? [0., 0., 1., 1., 1., 1., 1., 0., 0.],
? ? ? ? ? [0., 0., 0., 0., 0., 0., 0., 0., 0.]]]])
2.3 卷積核的定義 --- CNN_New.py(第03部分)
### 1.3 定義卷積核變量 # [out_channels,in_channels,filter_height,filter_width] # [卷積核個數(shù),圖像通道數(shù),卷積核的高度,卷積核的寬度 filter1 = torch.tensor([-1.0,0,0,-1]).reshape([1,1,2,2]) # 1通道輸入和1通道輸出的2X2矩陣 filter2 = torch.tensor([-1.0,0,0,-1,-1.0,0,0,-1]).reshape([2,1,2,2])# 1通道輸入和2通道輸出的2X2矩陣 filter3 = torch.tensor([-1.0,0,0,-1,-1.0,0,0,-1,-1.0,0,0,-1]).reshape([3,1,2,2])# 1通道輸入和3通道輸出的2X2矩陣 filter4 = torch.tensor([-1.0,0,0,-1,-1.0,0,0,-1,-1.0,0,0,-1,-1.0,0,0,-1]).reshape([2,2,2,2])# 2通道輸入和2通道輸出的2X2矩陣 filter5 = torch.tensor([-1.0,0,0,-1,-1.0,0,0,-1]).reshape([1,2,2,2]) # 2通道輸入和1通道輸出的2X2矩陣2.4 卷積操作與其結(jié)果 --- CNN_New.py(第04部分)
### 1.4 卷積操作 ## 1個通道輸入,生成1個特征圖(卷積核個數(shù)) pl1 = torch.nn.functional.conv2d(input1,filter1,stride=2,padding=1) print("p1",pl1) ## 1個通道輸入,生成2個特征圖(卷積核個數(shù)) pl2 = torch.nn.functional.conv2d(input1,filter2,stride=2,padding=1) print("p2",pl2) ## 1個通道輸入,生成3個特征圖(卷積核個數(shù)) pl3 = torch.nn.functional.conv2d(input1,filter3,stride=2,padding=1) print("p3",pl3) ## 2個通道輸入,生成2個特征圖(卷積核個數(shù)) pl4 = torch.nn.functional.conv2d(input2,filter4,stride=2,padding=1) print("p4",pl4) ## 2個通道輸入,生成1個特征圖(卷積核個數(shù))====》對于卷積核對多通道輸入的卷積處理,多通道的結(jié)果的疊加 pl5 = torch.nn.functional.conv2d(input2,filter5,stride=2,padding=1) print("p5",pl5) ## padding不同,生成的結(jié)果也不同 pl6 = torch.nn.functional.conv2d(input1,filter1,stride=2,padding=0) print("p6",pl6)p1 tensor([[[[-1., -1., -1.],
? ? ? ? ? [-1., -2., -2.],
? ? ? ? ? [-1., -2., -2.]]]])
p2 tensor([[[[-1., -1., -1.],
? ? ? ? ? [-1., -2., -2.],
? ? ? ? ? [-1., -2., -2.]],
? ? ? ? ?[[-1., -1., -1.],
? ? ? ? ? [-1., -2., -2.],
? ? ? ? ? [-1., -2., -2.]]]])
p3 tensor([[[[-1., -1., -1.],
? ? ? ? ? [-1., -2., -2.],
? ? ? ? ? [-1., -2., -2.]],
? ? ? ? ?[[-1., -1., -1.],
? ? ? ? ? [-1., -2., -2.],
? ? ? ? ? [-1., -2., -2.]],
? ? ? ? ?[[-1., -1., -1.],
? ? ? ? ? [-1., -2., -2.],
? ? ? ? ? [-1., -2., -2.]]]])
p4 tensor([[[[-2., -2., -2.],
? ? ? ? ? [-2., -4., -4.],
? ? ? ? ? [-2., -4., -4.]],
? ? ? ? ?[[-2., -2., -2.],
? ? ? ? ? [-2., -4., -4.],
? ? ? ? ? [-2., -4., -4.]]]])
p5 tensor([[[[-2., -2., -2.],
? ? ? ? ? [-2., -4., -4.],
? ? ? ? ? [-2., -4., -4.]]]])
p6 tensor([[[[-2., -2.],
? ? ? ? ? [-2., -2.]]]])
Tip:多通道卷積的圖解
2.5 代碼匯總
import torch### 1.1 定義輸入變量 # [batch,in_channels,in_height,in_width] # [訓(xùn)練時一個batch的圖片數(shù)量,圖像通道數(shù),圖片高度,圖片寬度] input1 = torch.ones([1,1,5,5]) input2 = torch.ones([1,2,5,5]) input3 = torch.ones([1,1,4,4])### 1.2 驗證補0規(guī)則 # 設(shè)置padding為1,在輸入數(shù)據(jù)上補1排0 padding1 = torch.nn.functional.conv2d(input1,torch.ones([1,1,1,1]),stride=1,padding=1) print(padding1) # 設(shè)置padding為1,在輸入數(shù)據(jù)上補2行0 padding2 = torch.nn.functional.conv2d(input1,torch.ones([1,1,1,1]),stride=1,padding=(1,2)) print(padding2)### 1.3 定義卷積核變量 # [out_channels,in_channels,filter_height,filter_width] # [卷積核個數(shù),圖像通道數(shù),卷積核的高度,卷積核的寬度 filter1 = torch.tensor([-1.0,0,0,-1]).reshape([1,1,2,2]) # 1通道輸入和1通道輸出的2X2矩陣 filter2 = torch.tensor([-1.0,0,0,-1,-1.0,0,0,-1]).reshape([2,1,2,2])# 1通道輸入和2通道輸出的2X2矩陣 filter3 = torch.tensor([-1.0,0,0,-1,-1.0,0,0,-1,-1.0,0,0,-1]).reshape([3,1,2,2])# 1通道輸入和3通道輸出的2X2矩陣 filter4 = torch.tensor([-1.0,0,0,-1,-1.0,0,0,-1,-1.0,0,0,-1,-1.0,0,0,-1]).reshape([2,2,2,2])# 2通道輸入和2通道輸出的2X2矩陣 filter5 = torch.tensor([-1.0,0,0,-1,-1.0,0,0,-1]).reshape([1,2,2,2]) # 2通道輸入和1通道輸出的2X2矩陣### 1.4 卷積操作 ## 1個通道輸入,生成1個特征圖(卷積核個數(shù)) pl1 = torch.nn.functional.conv2d(input1,filter1,stride=2,padding=1) print("p1",pl1) ## 1個通道輸入,生成2個特征圖(卷積核個數(shù)) pl2 = torch.nn.functional.conv2d(input1,filter2,stride=2,padding=1) print("p2",pl2) ## 1個通道輸入,生成3個特征圖(卷積核個數(shù)) pl3 = torch.nn.functional.conv2d(input1,filter3,stride=2,padding=1) print("p3",pl3) ## 2個通道輸入,生成2個特征圖(卷積核個數(shù)) pl4 = torch.nn.functional.conv2d(input2,filter4,stride=2,padding=1) print("p4",pl4) ## 2個通道輸入,生成1個特征圖(卷積核個數(shù))====》對于卷積核對多通道輸入的卷積處理,多通道的結(jié)果的疊加 pl5 = torch.nn.functional.conv2d(input2,filter5,stride=2,padding=1) print("p5",pl5) ## padding不同,生成的結(jié)果也不同 pl6 = torch.nn.functional.conv2d(input1,filter1,stride=2,padding=0) print("p6",pl6) 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的【Pytorch神经网络理论篇】 12 卷积神经网络实现+卷积计算的图解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV_03 图像的算数操作:图像
- 下一篇: [Kaggle] Digit Recog