PyTorch-07 卷积神经网络(什么是卷积、卷积神经网络、池化层、Batch normalization、经典卷积网络、深度残差网络 ResNet、nn.Module、数据增强)
PyTorch-07 卷積神經網絡(什么是卷積、卷積神經網絡、池化層、Batch normalization、經典卷積網絡(LeNet-5、AlexNet、VGG、GoogLeNet)、深度殘差網絡 ResNet、nn.Module(使用nn.Module的好處)、數據增強(Data Argumentation))
一、什么是卷積
deep learning 一般使用0-1這個范圍,但是數據存儲是0-255,所以我們加載進來時除以255這個分數,使其達到0-1這個區間內。
What’s wrong with Linear
全連接層,在pytorch中也叫線性層,線性層僅僅表達了全連接網絡的線性部分,線性層后面會增加一個非線性單元,叫做激活函數,因此不論是叫線性層還是叫全連接層,都指的是整個網絡。我們實現的時候linear是沒有包含激活函數這部分的。
對于下圖,這個神經網絡一共有4層,3個隱藏層和1個輸出層,input layer輸入層是不把它計算在內的,僅僅作為數據的輸入。對于某一層,是指這一層的權值w和這一層的輸出加在一起叫做一層。
輸入的本來是28*28的matrix,這里為了方便全連接層的處理,因此打平為784維的向量。中間節點全部去256,一共有4個hidden layer,每個hidden layer是256,和一個輸出層10類。
這個網絡一共有多少參數量呢?多少參數量就意味著有多少條線,784256 + 256256 + 256256 + 25610 = 390k parameter參數量。每一個參數是用一個四字節的浮點數來表示的。390k *4 = 1.6MB memory的顯存
Receptive Field 感受領域(局部相關性)
模仿人眼感受局部相關性的一個機制,提出了卷積神經網絡,這里卷積指的就是局部相關性,一次感受的就是一個小方塊,而不是一個大區間,一次感受的是一個小的視野,。
Weight sharing 權值共享
這樣一個小窗口,會掃過一個大的圖片,在掃合格大的圖片過程中使用了同一個權值w,也就是w這個參數是不變的,掃完一次之后,只有在back propagate反向傳播之后才更新一次w。因此小窗口掃描大圖片的過程中,通過局部相關性促成這種共享的機制存在,使用相同的w掃描大圖的過程叫做權值共享。以后會在RNN中使用權值共享這個概念在里面。使用權值共享會讓參數量下降。
用于郵編的識別:LeNet-5,會讓參數量下降了原來的1/6。
Convolution Operation卷積操作
卷積操作就是小窗口33不斷的與大窗體對應位置進行計算,獲得一個輸出點,通過不斷的循環,完成對所有點的計算后生成新的窗體,該新窗體大小和原來的窗體大小是相同的。
之前的連接是2828整個大窗體的連接,每個點都通過整個大窗體來進行計算,每個節點都有784條連線;而卷積計算只會和每個節點相關的9個節點相連線,這個小窗口只有9根線進行連接,其他的775條都是斷開的。
小窗體和小窗體對應大窗體位置的小窗體可以進行矩陣的計算,也可以進行相應元素上的相乘后再累加,從而會的一個點,這種相乘在累加后生成一個點的操作叫做卷積操作。
Why call Convolution?為什么叫卷積?
卷積操作在信號處理鄰域中:
是一個偏移的積分運算過程。
這種信號鄰域的計算如何才能對應到圖片中的卷積運算中呢?
圖像上的積分運行,就是對應窗口位置相乘再累加。
Convolution卷積
對一個圖片進行Sharpen操作,讓圖片變得更銳化,因此我們就使用一個5*5的kernal核,和圖片進行卷積運算。圖像上的積分運行,就是對應窗口位置相乘再累加。
除了上面的Sharpen銳化操作,還有一個是Blur模糊化。
除了上面兩個還有一個是Edge Detect邊緣檢測。
CNN on feature maps CNN專題圖
每次掃描使用的不同kernal,則獲得的圖片是不一樣的,下面可以看到小窗體在開始是紅色框,第二次是綠色框,這兩次計算后生成的結果是不同,因為kernal不同。
二、卷積神經網絡
計算結束后,原來的圖片如果是2828,由于kernal是33,在靠近到原圖片的邊緣時,最邊緣的一圈kernal是無法靠近的,因為如果將kernal中心點對準原圖片邊緣的像素,則kernal會有一些超出原圖像,為了不讓kernal不超出原圖片,所以新圖片是26*26,會比原來的小一圈。
如果進行padding填充操作,即讓原來的2828周圍增加一圈0,就可以保證輸出的新函數是2828。
多個kernal代表著有多個不同的觀察角度。
原圖像(1,28,28)
kernal(7,3,3)
新圖像(7,26,26)
卷積運算:
Notation注意
1、Input_channels:表示輸入圖片有幾個通道,黑白圖片通道數是1,彩色圖片通道數3。
2、Kernal_channels:2 ch,這里是指kernal有一個Blur和一個Edge Detect組成的2 ch,(注意,如果輸入圖片是三通道的,則kernal就有三個與原圖片對應,但是kernal的channel不是與原圖片通道數來相互對應的,是與Blur和Edge Detect來對應的,所以kernal有2 ch,可以理解為kernal的類型數量,但是有3個一樣的Blur和3個一樣Edge與彩色圖片相互對應,這里的3表示1個ch的與原彩色圖片對應的三個通道)(這個很容易混淆,需要理解)。
3、Kernal_size:3*3
4、Stride:這里指的是移動的步長,kernal小窗體移動的步長。
5、Padding:這里指填充于原圖片周圍的一圈0,padding=1,表示一圈0,padding=2為二圈。
更加常見的情況 Multi-Kernels
LeNet-5 郵政編碼的識別的網絡:
Pyramid Architecture金字塔結構
representation learning 特征學習的由來:特征不斷的提取的過程。
nn.Conv2d 類接口
stride=2,會有降維的效果,輸出的新圖會比原圖小。
這里盡量不要直接使用layer.forward()。推薦使用實例的方法,out = layer(x),這個其實是調用的是python的魔法 .call 函數。pytorch在__call__函數中封裝了一些hooks,這些hooks有一些高階的特性,如果要使用這些hooks,就必須要使用layer()類的實例來調用,如果使用layer.forward()這種方法,就沒辦法使用pytorch提供的一些hooks方法。不要直接調用.forward()。
Inner weight & bias
F.conv2d 函數式接口
三、池化層 (Pooling層,即下采樣)Down/up sample
Outline
? upsample 上采樣,和圖片放大非常類似。
? Pooling 下采樣,就意味著是將feature map變小的操作。
卷積神經網絡配套的一個網絡層叫:Pooling層
? ReLU
1、Downsample 下采樣
對于圖片數據而言,Downsample下采樣類似于降維的這種操作。
Max pooling
在卷積神經網絡中,是使用max pooling來進行類似于上面那種降維操作的。
Avg pooling
就是獲取小窗口所有像元的均值。
使用pytorch來完成pooling這樣的操作
這里可以注意,convolution的kernal會改變原圖像的channel,而這里的pooling是不會改變原圖像channel的數量的。下面的代碼可以看出輸入和輸出的channel是沒有改變的,依然是16。
2、Upsample 上采樣
在pytorch中如何使用 F.interpolate
interpolate表示插值的意思。
這里依然是不會改變原圖像的channel數量。下面的代碼是pytorch自帶的實現擴大方法,的對于tensor這種數據類型的可以直接使用的。
ReLU
是將圖片feature map中負的像元給去掉的過程,那些像元響應太低了,就把那些小于0的像元給去掉。下圖中黑色部分就是響應太小了,去掉后就變成了右圖的樣子,像素值變為了0。
在pytorch中如何使用 F.relu()
inplace = True 表示可以使用原先變量的內存空間,這樣可以減少內存的使用。可以發現使用relu后,輸入和輸出的shape是沒有變化的,但是像元值發生了改變,最小值不在是負值,而變為了0。
四、Batch normalization(數據歸一化方法)
重要概念,Batch normalization,這個概念會在卷積神經網絡中、循環神經網絡中等都會用到。
Batch Normalization是2015年一篇論文中提出的數據歸一化方法,往往用在深度神經網絡中激活層之前。. 其作用可以加快模型訓練時的收斂速度,使得模型訓練過程更加穩定,避免梯度爆炸或者梯度消失。. 并且起到一定的正則化作用,幾乎代替了Dropout(dropout是指在深度學習網絡的訓練過程中,對于神經網絡單元,按照一定的概率將其暫時從網絡中丟棄)。
直觀的解釋Intuitive explanation
對于使用sigmoid函數來說,當輸入大于某個區間范圍后,sigmoid的導數會接近于0,這樣就容易出現梯度離散的情況。因此很有必要對輸入做一定的限制。normalization就是用來最這個限制的,讓輸入數據等效變換,使其輸入的數據滿足一定的正太分布N(0,σ^2),希望這個值能夠均勻落在0的附近,使其在小的范圍內變動,這樣再做下一層的時候,優化起來會更加方便。
可以發現下圖中,左側的圖,x1是在一個比較小的值,x2是在一個比較大的值,因此當w1進行改變時,x1的變化會比較小,當w2進行改變時,x2會急劇的變化,這樣在搜索全局最小值的過程會比較曲折一些,左圖的箭頭所示。
如果x1和x2的范圍是一樣的,w1和w2對最終loss是一樣的,會形成右圖圓形的路徑,在進行搜索的時候,不管從哪個點出發,梯度所指的方向都是全局最小解的方向。這樣搜索過程會比較快捷方便穩定。
Feature scaling特征縮放
Batch Normalization
我們這里只看Batch normalization。
這里需要注意的是,μ和σ是統計出來的,是不需要參與反向傳播(back propagation)的,是根據當前的batch里面的統計數據統計出來的;但是γ和β是學出來的,是需要梯度信息的,剛開始(γ=1, β=0)是沒有影響,慢慢會學到一個N(β為均值, γ為方差)的偏置。
此外μ和σ會有一個歷史記錄,記錄每一個batch的總的均值和總的方差,總的均值和總的方差在命名上μ和σ前面增加了一個running,running-μ和running-σ2,這樣命名就是表示運行時候的統計數據,表示所有training出來的總的均值和總的方差。
利用pytorch進行這樣的一個計算:這里是針對1維數據進行操作的。
batch normalize規范化的寫法
下面的步驟就是batch normalize train的過程。
1、第一步統計當前batch的μв均值和方差σ2в,這里還自動更新running-μ和running-σ2。
2、第二步進行normalize的操作。注意在進行normalize的時候分母會加一個很小的值10^-8,這樣做是為了避免除零錯誤。計算完成后再進行一個平移β和縮放γ,使其達到N(均值β,方差γ)的正太分布。在反向傳播(back propagation) 的時候,β和γ需要梯度信息,因此這兩個參數會自動更新。
利用pytorch進行這樣的一個計算:這里是針對2維數據進行操作的。
Test
這里需要注意的是,和drop out一樣,batch normalization這個layer在training和test情況下行為是不太一樣的。
在training的時候,μ和σ會統計出來,并自動更新一下running,之后再反向傳播(back propagation),更新一下γ和β。
在test的時候,一般我們只會test一個sample,因此μ和σ2是沒法統計的,因為只有一個sample,所以就沒有必要進行統計。因此在test的時候,μ和σ取的不是當前batch的μ和σ2,而在test的時候將全值running-μ和running-σ賦值為μ和σ2。此外在test的時候,是沒有backward的,γ和β是不需要更新的。要實現test,就需要提前切換到test這個模式下,必須調用.eval()這個函數,設置為test模式,再調用BatchNorm1d()進行變換。
可視化Visualization
曲線圖中的虛線是使用batch normalize的,實線的是沒有使用的。
可以發現使用了batch normalize,收斂速度更快,精度也有所提升。我們可以查看每一層參數分布的情況,使用了后,其分布情況是圍繞均值為0附近,總的來說會往0附近來靠近,并不一定是0,方差為1來進行分布,這樣操作后更加利于training。這里需要注意一下,為什么不完完全全在以N(均值=0, 方差=1)這樣進行分布呢?這是因為存在γ和β對其分布的調整,如果γ=1且β=0,那么其分布情況就不會是以N(均值=0, 方差=1)這樣進行分布,其分布就是N(β為均值, γ為方差)這樣的分布。
總結一下使用batch normalize的好處Advantage
? Converge faster
收斂速度更快,在使用sigmoid激活函數的時候,如果把數據限制到0均值單位方差,那么相當于只使用了激活函數中近似線性的部分,這顯然會降低模型表達能力,但是收斂速度更快。
? Better performance
更加容易搜索出最優解
? Robust
? stable
變得更穩定了
? larger learning rate
更大的設置學習率的范圍
五、經典卷積網絡(CNN)
下圖中是最近10年內的網絡變化,其中柱狀圖上面的數字表示錯誤率(準確率=1-錯誤率)。
LeNet-5
在1989年,Yann LeCun提出了一種用反向傳導進行更新的卷積神經網絡,稱為LeNet。
最開始的LeNet-5是用于一個手寫數字的識別,手寫數字的圖片只有28*28,當時的網絡結構并不深,而且每一層的參數量也不大,即使這樣這個網絡結構也是沒有辦法在GPU上跑的,因為當時GPU還沒有,是386的年代。
這個準確度達到了99.2%,就可以很成熟的使用起來了。
所以在當時美國的支票票號識別,郵編識別就已經廣泛使用了。
AlexNet
LeNet-5是80年代出來的,那個時候deep learning還沒有很熱,在2012年,出來了AlexNet,準確率有了很高的提升。當時是使用兩個GTX580(3GB)顯卡來進行該網絡的運算,該網絡是5個卷積層,總共是8個layers,AlexNet的小窗口是11*11的,此外第一次使用ReLU函數、Max pooling、Dropout。
VGG
VGGNet是來自于牛津大學的視覺研究組。VGG一共有6個版本(比如VGG11、VGG16、VGG19)。VGG探索出了,小的kernal窗口不但可以減少計算量,并且沒有損害精度,而且計算速度很快,這也是VGG最核心的價值。探索出了更小型的kernal更好的效果。
這里我們先了解一下1*1卷積核:
1*1 Convolution
可以注意到的是,輸入的channel是32,而到了輸出channel就是16了。這里的輸出的channel取決于kernal的channel。此外1*1的kernal可以保證輸入和輸出的圖片大小是一樣的。
GoogLeNet
這里有不同大小的kernal,此外還有一個合并的操作Filter concatenation,為滿足這個操作的要求,需要確保所有不同kernal輸出來的圖像大小相同,因為有一個33 max pooling,所有輸出來的圖像大小要與max pooling輸出來的相同即可。假設max pooling輸出的是77的圖像,則kernal輸出的也必須是77(為了保證輸出的是77,可以使用stride步長來控制),這樣可以獲得很多個(32,7,7),之后通過concatenation操作后,可以獲得(32,4,7,7)的feature map。
之前使用的都是統一的kernal,而這里為什么要使用不同類型的kernal呢?這是因為每一個不同大小的kernal所感受的視野是不同,11 kernal感受的視野是一個點,33 kernal感受的視野是一個小窗體,通過綜合不同大小的視野(綜合局部和全局的信息),可以感受到一個跟好的信息量。
具體的結構是:
堆疊更多層更好嗎?Stack more layers?
通過堆疊更多層數的時候,層數更多的時候,反而準確度并沒有提升,反而training比較困難,training的error比較高,這告訴我們并不能簡單的堆疊更多的層數(這里需要拋開4層到22層,這范圍內是堆疊更多層數效果會有提升,但是超過20層以上之后,僅是簡單的堆疊的話,training的難度非常大,training找到最優解的難度很大)。
現在我們的網絡結構以及是1000多層了,那如何解決這個問題的呢?也就是ResNet。
六、深度殘差網絡 ResNet
殘差神經網絡(ResNet)是由微軟研究院的何愷明、張祥雨、任少卿、孫劍等人提出的。ResNet 在2015 年的ILSVRC(ImageNet Large Scale Visual Recognition Challenge)中取得了冠軍。
殘差神經網絡的主要貢獻是發現了“退化現象(Degradation)”,并針對退化現象發明了 “快捷連接(Shortcut connection)”,極大的消除了深度過大的神經網絡訓練困難問題。神經網絡的“深度”首次突破了100層、最大的神經網絡甚至超過了1000層。
ResNet構建塊Unit,選擇什么樣的結構合適
這個Unit選擇一個2-3層的卷積層,再加一個short。為了能夠shortcut,就意味著經過shortcut輸出的結果要與輸入時的維度相同且channel也不能衰減,即輸入時256層,則shortcut時也要是256層。
我們來計算一下參數量,輸出256,輸入256,每一個kernal是33,則參數量大概有25625633 = 589,824 大約有600k左右。如果有三個這樣的Convolution的話,還需要再乘以3。
所以為了減少這個參數量,將unit中的kernal的size減小。比如說輸入時是(256,224,224),通過第一個11 kernal時的結果是(64,224,224);再通過第二個33 kernal時,進行padding處理后保持shape不變,依然是(64,224,224);最后通過第三個1*1 kernal后,將輸出結果恢復到原來的(256,224,224)。
輸入時一個(256,224,224),和shortcut的(256,224,224)進行對應元素位置的相加,同樣大小的矩陣相加,是同位置直接相加,不改變其維度,最后結果也是(256,224,224),是沒有改變的。
再來計算一下參數量,2566411 ~ 16k;646433 ~ 36k;642561*1 ~ 16k;這樣總共 Total是大約70k。和原來的600k參數量相比,大概少了9倍。
查看一下34層的ResNet的基本結構:
ResNet的爆炸性的效果
Why call Residual? 為什么叫殘差呢?
F(x)表示unit卷積層學習的內容,原來學習的是H(x),F(x) + x = H(x) 原來學習的情況。
對于unit中的卷積層來說,F(x) = H(x) - x。這個減號就是殘差的由來。
跨時間維度上不同網絡的比較
對于一個ResNet是如何實現的呢?
這里關鍵是如何實現一個Unit基本單元。
這里需要注意的是,我們可以將輸入數據的channel和輸出數據的channel設置成為不同的,我們只需在shortcut路徑上增加一個1*1 kernal 將輸入的channel通過這個kernal的channel進行調整,從而將輸入的channel和輸出channel有相同的數量。在shortcut的路徑上增加一個調整channel的kernal,就可以不用擔心輸入和輸出channel不同的問題了。
ResNet例子:
DenseNet
基于ResNet的短接層思路,可以推廣到,每一個unit都可以和前面所有層都有一個短接,這樣就有了DenseNet。
這里需要注意的是,DenseNet的每一次短接過程,其實是一個concat過程,是將之前的所有信息進行綜合,不是element wise的相加操作,這樣會使得最后的channel越來越大,所以DenseNet對于channel的選擇要設計的很精妙,舍得后面的channel不至于過大。
七、nn.Module(使用nn.Module的好處)
pytorch中使用非常廣泛的類叫nn.Module。
nn.Module類是所有網絡層的父類,當需要實現自己的一個層的時候就必須要繼承這個父類。
Magic
? Every Layer is nn.Module
nn.Module在pytorch中是一個基本的父類,當要實現一個前項計算圖的時候,如果繼承了nn.Module就可以非常方便的使用現成的一些類:
比如說: ? nn.Linear
? nn.BatchNorm2d
? nn.Conv2d
? nn.Module nested in nn.Module
除了使用這些類以外,還可以嵌套nested,每個nn.Module后又可以嵌套nn.Module。
使用nn.Module的好處
1、embed current layers
在nn.Module中啟用了大量現成的神經網絡計算的模塊。使用這些現成的模塊非常方便,只需要調用初始函數,再通過.__call__方法調用forward函數,就可以使用這個模塊提供的功能了。
比如: ? Linear
? ReLU
? Sigmoid
? Conv2d
? ConvTransposed2d
? Dropout
? etc.
2、Container容器
Container就是nn.Sequential()這個類。
nn.Sequetial:按順序包裝多個網絡層(使用容器的時候,容器里面的model屬于容器,而這個容器屬于本網絡)注意哦,這個容器后面括號里都是參數所以要用逗號隔開。
sequential是一個時序模型,根據每個submodule傳入的順序寫到計算圖里,在forward的時候也會順序執行。
self.net(x)就可以直接自動完成多次的forward的操作。
3、parameters 權值和偏置參數
使用nn.Module可以很好的對模型參數進行管理,named_parameters()/parameters()方法,這兩個方法都會返回一個用于迭代模型參數的迭代器(named_parameters還包括參數名字)。
比如說下圖中使用Container容器,將兩個線性層容在一起,名為net;通過net.parameters()這個方法可以返回一個生成器,其保存著每層的weight權值和bias偏置。
import torch from torch import nn print(nn.Linear(4,2)) print('=======================') net = nn.Sequential(nn.Linear(4,2),nn.Linear(2,2)) # torch.nn.Linear(in_features, # 輸入的神經元個數 # out_features, # 輸出神經元個數 # bias=True # 是否包含偏置 # ) print(net.parameters()) print('=======================') print(list(net.parameters())) print('=======================') print(list(net.parameters())[0]) print(list(net.parameters())[0].shape) #這里為什么是(2,4)呢?因為w是輸出維度在前面,所以是(2,4),是layer0的w。 print('=======================') print(list(net.parameters())[3]) #這里是layer1的bias偏置,所以是(2)print('=======================') #通過.parameters可以很好的返回一個迭代器,返回當前這個net的所有參數。 #因此繼承了nn.Module就不需要額外管理這些參數。 print('=======================')#這個參數有兩種形式, # 一個是帶名字的parameters,返回一個dictionary字典,字典第一個是名字,這個名字是pytorch自動生成的。 #這里我們將字典轉換為了list。 #'0.weight' 表示第0層的weight print(list(net.named_parameters())[0]) #'0.bias' 表示第0層的bias print(list(net.named_parameters())[1]) print('=======================') #這里我們以字典形式打印出來 print(dict(net.named_parameters()).items()) #這里item()方法是返回這個字典中的所有屬性 print('******************************') #一個是不帶名字的parameters。 print(list(net.parameters())[0])#我們可以通過.parameter,將所有參數傳入到優化器中。 #之前我們是通過[w1,b1,w2,b2]這種方式自己管理參數,將這些傳入到optimizer中的。 #現在就直接將這個類的.parameters()傳入其中即可,這樣使用時非常非常方便的。
4. modules 查看子類
? modules: all nodes
對于內部的類可以做到很好的管理。所有的子節點可以稱為modules。
? children: direct children
直接的子節點,我們稱其為children。
使用nn.modules()可以查看所有的子類情況。
其返回的是module其本身0號、其直系兒子1號和其它所有子節點。
5、to(device) 切換GPU或CPU
可以非常方便的將一個類所有的成員函數、所有內部的tensor和所有的操作轉移到GPU或CPU上。
這里需要特別注意,當a是tensor類型時,a.to 返回的是 a_GPU,注意這里的a_GPU和原來的a.to的a不是同一個東西,a.to的a是CPU上的。而對于nn.Module來說,net = net.to。
6、save and load 保存和加載網絡中間狀態
在使用pytorch進行深度學習訓練的時候,經常會有些內容需要保存下來,保存到硬盤張,不管什么時候我們都可以讀取到,那么這個時候,使用torch.save()就可以將內容存儲器來,使用torch.load()就可以將存取的內容讀取出來。
save and load保存和加載 Checkpoint 用于推理/繼續訓練,Checkpoint是網絡的中間狀態。
保存和加載是可以用于在斷電等特殊情況下,不至于失去之前訓練的結果,避免讓其從頭開始從新訓練。
Save操作:
#save: torch.save(net.state_dict(), 'ckpt.mdl')Load操作:
net.load_state_dict(torch.load('ckpt.mdl'))7、train / test 切換
train和test的方便切換狀態。如果每個類都繼承與nn.Module的話,直接通過對根節點net.train(),或.eval(),就可以切換了。
8、implement own layer 實現自己的類
比如說在pytorch中沒有一個展平的功能Flatten,因此我們可以自己實現一個繼承與nn.Module的用于展平功能的類。
此外還有一個是reshape操作,這個功能只有方法,沒有一個類,所以很多情況下我們也需要自己創建一個繼承與nn.Module的用于Reshape的類。
實現一個自己的MyLinear,這個自己創建的類和nn.Linear功能是一樣的,這里可以發現nn.Parameter()會自動將需要梯度設置為true,requires_grad=True,而且參數也會受到nn.parameters()的管理,注意類是大寫的Parameter,方法是小寫的parameters。
我們在forward()函數中寫好我們的邏輯,再return,一定要返回。
八、數據增強(Data Argumentation)
Big Data
很大的數據集是train的好壞的前提。有了Big Data神經網絡就能train的很好,有了Big Data這個網絡就不容易over fitting,這個是防止過擬合的關鍵The key to prevent Overfitting。
Limited Data 有限的數據進行優化
? Small network capacity
首先如果數據比較少的話,就要減少網絡的參數量,這樣就不容易overfitting。
? Regularization
如果網絡結構是固定的話,我們就正則化Regularization,迫使網絡的一部分權值w接近于0,這樣也減少了網絡的參數量。
? Data argumentation
對原來的數據進行增強,比如對原來的圖像進行調色,旋轉角度等,獲得新的圖片,將這些圖片和原先的圖片一起用于網絡的訓練。
Data argumentation
? Flip 翻轉
? Rotate 旋轉
? Scale 縮放
? Crop Part 裁剪部分
? Noise 白噪聲
? Random Move 隨機移動
? GAN 生成對抗網絡
Flip翻轉
水平翻轉和豎直翻轉:
.RandomHorizontalFlip()水平翻轉、.RandomVerticalFlip()豎直翻轉,這兩個都是隨機的,有可能做,也有可能不做。
Rotate旋轉
.RandomRotation(15)會在-15°<0<15°會在個區間內隨機的進行選擇;如果我們要固定這個角度,.RandomRotation([0, 90, 180, 270])會隨機的在0°、90°、180°和270°三個角度中選取進行旋轉,如果要不旋轉的那就在加一個0°,這樣會將原來的照片數量變為原來的4被。
Scale縮放
Crop Part裁剪部分
隨機裁剪一部分,裁切的那部分用0來填補。
Noise白噪聲
pytorch沒有提供這個Noise接口,需要人為在Numpy基礎上添加這個。
這里需要總結一下數據增強,由于增強后的照片與原圖片是比較接近的,所有數據增強是有一定的幫助的,但是幫助不會很多。
總結
以上是生活随笔為你收集整理的PyTorch-07 卷积神经网络(什么是卷积、卷积神经网络、池化层、Batch normalization、经典卷积网络、深度残差网络 ResNet、nn.Module、数据增强)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AJAX-服务器响应
- 下一篇: c 打印 callback 函数名_Go