1 BN的優(yōu)點(diǎn)
這里簡單的介紹一下BN,在之前的文章中已經(jīng)詳細(xì)的介紹了BN算法和過程。
BN于2015年由 Google 提出,Google在ICML論文中描述的非常清晰,即在每次SGD時,通過mini-batch來對相應(yīng)的activation做規(guī)范化操作,使得結(jié)果(輸出信號各個維度)的均值為0,方差為1。最后的“scale and shift”操作則是為了訓(xùn)練所需而“刻意”加入的BN能夠有可能還原最初的輸入,從而保證數(shù)據(jù)中有用信息的留存。
【BN的好處】
BN使得網(wǎng)絡(luò)中每層輸入數(shù)據(jù)的分布相對穩(wěn)定,加速模型學(xué)習(xí)速度;
BN使得模型對網(wǎng)絡(luò)中的參數(shù)不那么敏感,簡化調(diào)參過程,使得網(wǎng)絡(luò)學(xué)習(xí)更加穩(wěn)定;
BN允許網(wǎng)絡(luò)使用飽和性激活函數(shù)(例如sigmoid,tanh等),緩解梯度消失問題;
BN具有一定的正則化效果。
2 BN的缺點(diǎn)
2.1 受限于Batch size
BN 沿著 batch 維度進(jìn)行歸一化,其受限于 Batch Size,當(dāng) Batch Size 很小時,BN 會得到不準(zhǔn)確的統(tǒng)計(jì)估計(jì),會導(dǎo)致模型誤差明顯增加
【一般每塊 GPU 上 Batch Size =32 最合適?!?/p>
但對于目標(biāo)檢測,語義分割,視頻場景等,輸入圖像尺寸比較大,而限于GPU顯卡的顯存限制,導(dǎo)致無法設(shè)置較大的 Batch Size,如 經(jīng)典的Faster-RCNN、Mask R-CNN 網(wǎng)絡(luò)中,由于圖像的分辨率較大,Batch Size 只能是 1 或 2.
2.2 訓(xùn)練集與測試集的分布
BN處理訓(xùn)練集的時候,采用的均值和方差是整個訓(xùn)練集的計(jì)算出來的均值和方差(這一部分沒有看懂的話,可能需要去看一下BN算法的詳解)
所以測試和訓(xùn)練的數(shù)據(jù)分布如果存在差異,那么就會導(dǎo)致訓(xùn)練和測試之間存在不一致現(xiàn)象(Inconsistency)。
3 Group Normalzation
Group Normalization(GN)是由2018年3月份何愷明團(tuán)隊(duì)提出,GN優(yōu)化了BN在比較小的mini-batch情況下表現(xiàn)不太好的劣勢。
Group Normalization(GN) 則是提出的一種 BN 的替代方法,其是首先將 Channels 劃分為多個 groups,再計(jì)算每個 group 內(nèi)的均值和方法,以進(jìn)行歸一化。GB的計(jì)算與Batch Size無關(guān),因此對于高精度圖片小BatchSize的情況也是非常穩(wěn)定的,
下圖是比較BN和GN在Batch Size越來越小的變化中,模型錯誤率變化的對比圖:
因此在實(shí)驗(yàn)的時候,可以在嘗試使用GN來代替BN哦~
其實(shí)不難發(fā)現(xiàn),GN和LN是存在一定的關(guān)系的。
上圖中有四種Normalization的方法。就先從最簡單的Instance Normalization開始分析:
IN:僅僅對每一個圖片的每一個通道最歸一化。也就是說,對【H,W】維度做歸一化。假設(shè)一個特征圖有10個通道,那么就會得到10個均值和10個方差;要是一個batch有5個樣本,每個樣本有10個通道,那么IN總共會計(jì)算出50個均值方差;
LN:對一個特征圖的所有通道做歸一化。5個10通道的特征圖,LN會給出5個均值方差;
GN:這個是介于LN和IN之間的一種方法。假設(shè)Group分成2個,那么10個通道就會被分成5和5兩組。然后5個10通道特征圖會計(jì)算出10個均值方差。
BN:這個就是對Batch維度進(jìn)行計(jì)算。所以假設(shè)5個100通道的特征圖的話,就會計(jì)算出100個均值方差。5個batch中每一個通道就會計(jì)算出來一個均值方差。
在GN的論文中,給出了GN推薦的group Number:
第一個表格展示GN的group Number不斷減小,退化成LN的過程。其實(shí),分組32個group效果最好;
第二個表格展示GN的每一組的channel數(shù)目不斷減小,退化成IN的過程。每一組16個channel的效果最好,我個人在項(xiàng)目中也會有優(yōu)先嘗試16個通道為一組的這種參數(shù)設(shè)置。
4 PyTorch實(shí)現(xiàn)GN
importnumpyasnp importtorch importtorch.nnasnn classGroupNorm(nn.Module): def__init__(self,num_features,num_groups=32,eps=1e-5): super(GroupNorm,self).__init__() self.weight=nn.Parameter(torch.ones(1,num_features,1,1)) self.bias=nn.Parameter(torch.zeros(1,num_features,1,1)) self.num_groups=num_groups self.eps=eps defforward(self,x): N,C,H,W=x.size() G=self.num_groups assertC%G==0 x=x.view(N,G,-1) mean=x.mean(-1,keepdim=True) var=x.var(-1,keepdim=True) x=(x-mean)/(var+self.eps).sqrt() x=x.view(N,C,H,W)
當(dāng)然,你要是想問PyTorch是否已經(jīng)集成了GN?那必然的。下面的代碼比較了PyTorch集成的GN和我們手算的GN的結(jié)果。
importtorch importtorch.nnasnn x=torch.randn([2,10,3,3])+1 #Torch集成的方法 m=torch.nn.GroupNorm(num_channels=10,num_groups=2) #先計(jì)算前面五個通道的均值 firstDimenMean=torch.Tensor.mean(x[0,0:5]) #先計(jì)算前面五個通道的方差 firstDimenVar=torch.Tensor.var(x[0,0:5],False) #減去均值乘方差 y2=((x[0][0][0][1]-firstDimenMean)/(torch.pow(firstDimenVar+m.eps,0.5)))*m.weight[0]+m.bias[0] print(y2) y1=m(x) print(m.weight) print(m.bias) print(y1[0,0,0,1])
輸出結(jié)果:
tensor(0.4595,grad_fn=
-
Google
+關(guān)注
關(guān)注
5文章
1752瀏覽量
57333 -
圖像
+關(guān)注
關(guān)注
2文章
1078瀏覽量
40359 -
pytorch
+關(guān)注
關(guān)注
2文章
795瀏覽量
13088
原文標(biāo)題:小白學(xué)圖像 | Group Normalization詳解+PyTorch代碼
文章出處:【微信號:Unfinished_coder,微信公眾號:機(jī)器視覺CV】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論