日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 卷积神经网络 >内容正文

卷积神经网络

深度学习之卷积神经网络(11)卷积层变种

發布時間:2023/12/15 卷积神经网络 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习之卷积神经网络(11)卷积层变种 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

深度學習之卷積神經網絡(11)卷積層變種

  • 1. 空洞卷積
  • 2. 轉置卷積
    • 矩陣角度
    • 轉置卷積實現
  • 3. 分離卷積

卷積神經網絡的研究產生了各種各樣優秀的網絡模型,還提出了各種卷積層的變種,本節將重點介紹書中典型的卷積層變種。

1. 空洞卷積


?普通的卷積層為了減少為了的參數量,卷積核的設計通常選擇較小的1×11×11×13×33×33×3感受野大小。小卷積核使得網絡提取特征時的感受野區域有限,但是增大感受野區域又會增加網絡的參數量和計算代價,因此需要權衡設計。

?空洞卷積Dilated/Atrous Convolution)的提出較好地解決了這個問題,空洞卷積在普通卷積的感受野上增加一個Dilation Rate參數,用于控制感受野區域的采樣步長,如下圖所示:

感受野采樣步長示意圖


當感受野的采樣步長Dilation Rate為1時,每個感受野采樣點之間的距離為1,此時的空洞卷積退化為普通的卷積; 當Dilation Rate為2時,感受野每2個單元采樣一個點,如上圖中間綠色方框中綠色格子所示,每個采樣格子之間的距離為2; 同樣的方法,最右邊圖的Dilation Rate為3,采樣步長為3,盡管Dilation Rate的增大會使得感受野區域增大,但是實際參與運算的點數仍然保持不變。

?以輸入為單通道的7×77×77×7張量,單個3×33×33×3卷積核為例,如下圖所示。在初始位置,感受野從最上、最右位置開始采樣,每隔一個點采樣一次,共采集9個數據點,如下圖中綠色方框所示。這9個數據點與卷積核相乘運算,寫入輸出張量的對應位置。

空洞卷積計算示意圖-1


?卷積核窗口按著步長為s=1s=1s=1向右移動一個單位,如下圖所示,同樣進行個點采樣,共采樣9個數據點,與卷積核完成相乘累加運算,寫入輸出張量對應為,直至卷積核移動至最下方、最右邊位置。需要注意區分的是,卷積核窗口的移動步長s和感受野區域的采樣步長Dilation Rate是不同的概念。

空洞卷積計算示意圖-2


?空洞卷積在不增加網絡參數的條件下,提供了更大的感受野窗口。但是在使用空洞卷積設置網絡模型時,需要精心設計Dilation Rate參數來避免出現網格效應,同樣較大的Dilation Rate參數并不利于小物體的檢測、語義分割等任務。

?在TensorFlow中,可以通過設置layers.Conv2D()類的dilation_rate參數來選擇使用普通卷積還是空洞卷積。例如:

import tensorflow as tf from tensorflow.keras import layers, optimizers, datasets, Sequentialx = tf.random.normal([1,7,7,1]) # 模擬輸入 # 空洞卷積,1個3×3的卷積核 layer = layers.Conv2D(1, kernel_size=3, strides=1, dilation_rate=2) out = layer(x) # 向前計算 print(out.shape)
運行結果如下圖所示:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/6e3ecf2d1eff4b71acef8870dfcb42c5.png#pic_center)


當dilation_rate參數設置為默認值1時,使用普通卷積方式進行計算; 當dilation_rate參數大于1時,采用空洞卷積方式進行計算。

2. 轉置卷積

?轉置卷積(Transposed Convolution,或Fractionally Strided Convolution,部分資料也稱之為反卷積/Deconvolution,實際上反卷積在數學上定義為卷積的逆過程,單轉置卷積并不能恢復出原卷積的輸入,因此稱為反卷積并不妥當)通過在輸入之間填充大量的padding來實現輸出高寬大于輸入高寬的效果,從而實現向上采樣的目的,如下圖所示。我們先介紹轉置卷積的計算過程,再介紹轉置卷積與普通卷積的聯系。

?為了簡化討論,我們此處只討論輸入h=wh=wh=w,即輸入高寬相等的情況。

轉置卷積實現向上采樣


o+2p?k\boldsymbol {o+2p-k}o+2p?ks\boldsymbol ss倍數

?考慮輸入為2×22×22×2的單通道特征圖,轉置卷積核為3×33×33×3大小,步長為s=2s=2s=2,填充p=0p=0p=0的例子。首先再輸入數據點之間均勻插入s?1s-1s?1個空白數據點,得到3×33×33×3的矩陣,如下圖第2個矩陣所示,根據填充量3×33×33×3矩陣周圍填充相應k?p?1=3?0?1=2k-p-1=3-0-1=2k?p?1=3?0?1=2行/列,此時輸入張量的高寬為7×77×77×7,如下圖中第3個矩陣所示。

輸入填充步驟


?在7×77×77×7的輸入張量上,進行3×33×33×3卷積核,步長s′=1s'=1s=1,填充p=0p=0p=0的普通卷積運算(注意,此階段的普通卷積的步長s′s's始終為1,與轉置卷積的步長sss不同),根據普通卷積的輸出計算公式,得到輸出大小為:
o=[i+2?p?ks′]+1=[7+2?0?31]+1=5o=[\frac{i+2*p-k}{s'} ]+1=[\frac{7+2*0-3}{1}]+1=5o=[si+2?p?k?]+1=[17+2?0?3?]+1=5
5×55×55×5大小的輸出。我們直接按照此計算流程給出最終轉置卷積輸出與輸入關系。在o+2p?ko+2p-ko+2p?ksss倍數時,滿足關系:
o=(i?1)s+k?2po=(i-1)s+k-2po=(i?1)s+k?2p
?轉置卷積并不是普通的逆過程,但是二者之間有一定的聯系,同時轉置卷積也是基于普通卷積實現的。在相同的設定下,輸入x\boldsymbol xx經過普通卷積運算得到o=Conv(x)\boldsymbol o=\text{Conv}(\boldsymbol x)o=Conv(x),我們將o送入轉置卷積運算后,得到x′=ConvTranspose(o)\boldsymbol x'=\text{ConvTranspose}(\boldsymbol o)x=ConvTranspose(o),其中x′≠x\boldsymbol x'≠\boldsymbol xx?=x,但是x′\boldsymbol x'xx\boldsymbol xx形狀相同。我們可以用輸入為5×55×55×5,步長s=2s=2s=2,填充p=0p=0p=03×33×33×3卷積核的普通卷積運算進行驗證演示,如下圖所示:

利用普通卷積恢復等大小輸入


?可以看到,將轉置卷積的輸出5×55×55×5在同設定條件下送入普通卷積,可以得到2×22×22×2的輸出,此大小恰好就是轉置卷積的輸入大小,同時我們也觀察到,輸出2×22×22×2矩陣并不是轉置卷積輸入的2×22×22×2矩陣。轉置卷積與普通卷積并不是互為逆過程,不能恢復出對方的輸入內容,僅能恢復出等大小的張量。因此稱之為反卷積并不切貼。

&emspl;基于TensorFlow實現上述例子的轉置卷積運算,代碼如下:

import tensorflow as tf from tensorflow.keras import layers, optimizers, datasets, Sequential# 創建X矩陣,高寬為5×5 x = tf.range(25)+1 # Reshape為合法維度的張量 x = tf.reshape(x, [1, 5, 5, 1]) x = tf.cast(x, tf.float32) # 創建固定內容的卷積核矩陣 w = tf.constant([[-1, 2, -3.], [4, -5, 6], [-7, 8, -9]]) # 調整為合法維度的張量 w = tf.expand_dims(w, axis=2) w = tf.expand_dims(w, axis=3) # 進行普通卷積運算 out = tf.nn.conv2d(x, w, strides=2, padding='VALID') print(out)


運行結果如下圖所示:


?現在我們將普通卷積的輸出作為轉置卷積的輸入,驗證轉置卷積的輸出是否為5×55×55×5,代碼如下:

# 普通卷積的輸出作為轉置卷積的輸入,進行轉置卷積運算 xx = tf.nn.conv2d_transpose(out, w, strides=2,padding='VALID',output_shape=[1, 5, 5, 1]) # 輸出的高寬為5×5 print(xx)


運行結果如下:

tf.Tensor( [[[[ 67.][ -134.][ 278.][ -154.][ 231.]][[ -268.][ 335.][ -710.][ 385.][ -462.]][[ 586.][ -770.][ 1620.][ -870.][ 1074.]][[ -468.][ 585.][-1210.][ 635.][ -762.]][[ 819.][ -936.][ 1942.][-1016.][ 1143.]]]], shape=(1, 5, 5, 1), dtype=float32)


o+2p?k\boldsymbol{o+2p-k}o+2p?k不為s\boldsymbol ss倍數

?讓我們更加深入地分析卷積運算中輸入與輸出大小關系的一個細節。考慮卷積運算的輸出表達式:
o=[i+2?p?ks′]+1o=[\frac{i+2*p-k}{s'} ]+1o=[si+2?p?k?]+1
當步長s>1s>1s>1時,[i+2?p?ks′][\frac{i+2*p-k}{s'} ][si+2?p?k?]向下取整運算使得出現多種不同輸入尺寸iii對應到相同的輸出尺寸ooo上。舉個例子,考慮輸入大小為6×66×66×6,卷積核大小為3×33×33×3,步長為1的卷積運算,代碼如下:

import tensorflow as tf from tensorflow.keras import layers, optimizers, datasets, Sequential# 創建X矩陣,高寬為5×5 x = tf.random.normal([1, 6, 6, 1]) x = tf.cast(x, tf.float32) # 創建固定內容的卷積核矩陣 w = tf.constant([[-1, 2, -3.], [4, -5, 6], [-7, 8, -9]]) # 調整為合法維度的張量 w = tf.expand_dims(w, axis=2) w = tf.expand_dims(w, axis=3) # 進行普通卷積運算 out = tf.nn.conv2d(x, w, strides=2, padding='VALID') print(out) print(out.shape)

運行結果如下圖所示:


此種情況也能獲得2×22×22×2大小的卷積輸出,與利用普通卷積可以獲得相同大小的輸出。因此,不同輸入大小的卷積運算可能獲得相同大小的輸出。考慮到卷積與專制卷積輸入輸出大小關系互換,從轉置卷積的角度來說,輸入尺寸iii經過轉置卷積運算后,可能獲得不同的輸出ooo大小。因此通過填充aaa行、aaa列來實現不同大小的輸出ooo,從而恢復普通卷積不同大小的輸入的情況,其中aaa關系為:
a=(o+2p?k)a=(o+2p-k)%sa=(o+2p?k)
此時轉置卷積的輸出變為:
o=(i?1)s+k?2p+ao=(i-1)s+k-2p+ao=(i?1)s+k?2p+a
?在TensorFlow中間,不需要手動指定aaa參數,只需要指定輸出尺寸即可,TensorFlow會自動推導需要填充的行列數aaa,前提是輸出尺寸合法。例如:

# 恢復出6×6大小 out = tf.nn.conv2d(x, w, strides=2, padding='VALID') print(out) print(out.shape)# 普通卷積的輸出作為轉置卷積的輸入,進行轉置卷積運算 xx = tf.nn.conv2d_transpose(out, w, strides=2,padding='VALID',output_shape=[1, 6, 6, 1]) # 輸出的高寬為5×5 print(xx)


運行結果如下所示:

tf.Tensor( [[[[ -8.0665455][ 16.133091 ][ -4.7349663][ -38.92934 ][ 58.394012 ][ 0. ]][[ 32.266182 ][ -40.332726 ][ -29.459408 ][ 97.32335 ][-116.788025 ][ 0. ]][[ -59.992893 ][ 71.58651 ][ 38.390343 ][-126.35293 ][ 131.13538 ][ 0. ]][[ 14.108292 ][ -17.635365 ][ 79.89131 ][ -73.41109 ][ 88.09331 ][ 0. ]][[ -24.68951 ][ 28.216583 ][-134.51918 ][ 117.45774 ][-132.13995 ][ 0. ]][[ 0. ][ 0. ][ 0. ][ 0. ][ 0. ][ 0. ]]]], shape=(1, 6, 6, 1), dtype=float32)


通過改變參數output_shape=[1, 5, 5, 1]也可以獲得高寬為5×5的張量。

矩陣角度

?轉置卷積的轉置是指卷積核W\boldsymbol WW產生的稀疏矩陣W′\boldsymbol W'W在計算過程中需要先轉置W′T\boldsymbol W'^TWT,再進行矩陣相乘運算,而普通卷積并沒有轉置W′\boldsymbol W'W的步驟。這也是它被稱為轉置卷積的名字的由來。

?考慮普通Conv2d運算: X\boldsymbol XXW\boldsymbol WW,需要根據strides將卷積核在行、列方向循環移動獲取參與運算的感受野的數據,串行計算每個窗口的“相乘累加”值,計算效率極地。為了加速運算,在數學上可以將卷積核W\boldsymbol WW根據strides重排成稀疏矩陣W′\boldsymbol W'W,再通過W′@X′\boldsymbol W'@\boldsymbol X'W@X一次完成運算(實際上,W′\boldsymbol W'W矩陣過于稀疏,導致很多無用的0乘運算,很多深度學習框架也不是通過這種方式實現的)。

?以4行4列的輸入X\boldsymbol XX,高寬為3×3,步長為1,無padding的卷積核W\boldsymbol WW的卷積運算為例,首先將X\boldsymbol XX打平成X′\boldsymbol X'X,如下圖所示:

轉置卷積X'


然后將卷積核W\boldsymbol WW轉換成稀疏矩陣W′\boldsymbol W'W,如下圖所示:

轉置卷積W'


?此時通過一次矩陣相乘即可實現普通卷積運算:
O′=W′@X′\boldsymbol O'=\boldsymbol W'@\boldsymbol X'O=W@X
如果給定O\boldsymbol OO,希望能夠生成與X\boldsymbol XX相同形狀大小的張量,怎么實現呢?將W′\boldsymbol W'W轉置后與上圖方法重排后的O′\boldsymbol O'O完成矩陣相乘即可:
X′=W′T@O′\boldsymbol X'=\boldsymbol W'^T@\boldsymbol O'X=WT@O
得到的X′\boldsymbol X'X通過reshape操作變為與原來的輸入X\boldsymbol XX尺寸一致,但是內容不同。例如O′\boldsymbol O'O的shape為[4,1][4,1][4,1]W′T\boldsymbol W'^TWT的shape為[16,4][16,4][16,4],Reshape后即可產生[4,4][4,4][4,4]形狀的張量。由于轉置卷積在矩陣運算時,需要將W′\boldsymbol W'W轉置后才能與轉置卷積的輸入O′\boldsymbol O'O矩陣相乘,故稱為轉置卷積。

?轉置卷積具有“放大特征圖”的功能,在生成對抗網絡、語義分割等中得到了廣泛應用,如DCGAN[1]中的生成器通過堆疊轉置卷積層實現逐層“放大”特征圖,最后獲得十分逼真的生成圖片。

DCGAN生成器網絡結構


[1] A. Radford, L. Metz 和 S. Chintala, Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks, 2015.

轉置卷積實現

?在TensorFlow中,可以通過nn.conv2d_transpose實現轉置卷積運算。我們先通過nn.conv2d完成普通卷積運算。注意轉置卷積的卷積核的定義格式為[k,k,cout,cin][k,k,c_{out},c_{in}][k,k,cout?,cin?]。例如:

import tensorflow as tf from tensorflow.keras import layers, optimizers, datasets, Sequential# 創建4×4大小的輸入 x = tf.range(16)+1 x = tf.reshape(x, [1, 4, 4, 1]) x = tf.cast(x, tf.float32) # 創建3×3卷積核 w = tf.constant([[-1, 2, -3.], [4, -5, 6], [-7, 8, -9]]) w = tf.expand_dims(w, axis=2) w = tf.expand_dims(w, axis=3) # 普通卷積運算 out = tf.nn.conv2d(x, w, strides=1, padding='VALID') print(out)


運行結果如下圖所示:


?保持strides=1,padding=‘VALID’,卷積核不變的情況下,我們通過卷積核www與輸出outoutout的轉置卷積運算嘗試恢復與輸入xxx相同大小的高寬張量,代碼如下:

# 恢復4×4大小的輸入 xx = tf.nn.conv2d_transpose(out, w, strides=1,padding='VALID',output_shape=[1, 4, 4, 1]) tf.squeeze(xx) print(xx)

運行結果如下所示:

tf.Tensor( [[[[ 56.][ -51.][ 46.][ 183.]][[-148.][ -35.][ 35.][-123.]][[ 88.][ 35.][ -35.][ 63.]][[ 532.][ -41.][ 36.][ 729.]]]], shape=(1, 4, 4, 1), dtype=float32)


可以看到,轉置卷積生成了4×44×44×4的特征圖,單特征圖的數據與輸入xxx并不相同。

?在使用tf.nn.conv2d_transpose進行轉置卷積運算時,需要額外手動設置輸出的高寬。tf.nn.conv2d_transpose并不支持自定義padding設置,只能設置為VALID或者SAME。

?當設置padding=‘VALID’時,輸出大小表達為:
o=(i?1)s+ko=(i-1)s+ko=(i?1)s+k

?當設置padding=‘SAME’時,輸出大小表達為:
o=i?so=i\cdot so=i?s
?如果我們還是對轉置卷積原理細節暫時無法理解,可以先牢記上述兩個表達式即可。例如:

2×22×22×2的轉置卷積輸入與3×33×33×3的卷積核運算,strides=1,padding=‘VALID’時,輸出大小為:
h′=w′=(2?1)?1+3=4h'=w'=(2-1)\cdot1+3=4h=w=(2?1)?1+3=4

2×22×22×2的轉置卷積輸入與3×33×33×3的卷積核運算,strides=1,padding=‘VALID’時,輸出大小為:
h′=w′=2?3=6h'=w'=2\cdot3=6h=w=2?3=6
?轉置卷積也可以和其他層一樣,通過layers.Conv2DTranspose類創建一個轉置卷積層,然后調用實例即可完成向前計算。代碼如下:

# 創建轉置卷積類 layer = layers.Conv2DTranspose(1, kernel_size=3, strides=1, padding='VALID') xx2 = layer(out) print(xx2)

運行結果如下:

tf.Tensor( [[[[ 6.942313 ][ 33.887856 ][ 24.800087 ][ -4.222195 ]][[ 21.720724 ][ 68.23484 ][ 73.74913 ][ 28.219326 ]][[ 15.284215 ][ 10.42746 ][ 12.951116 ][ 20.34887 ]][[ -1.9099097][-26.6492 ][-56.841545 ][-32.62231 ]]]], shape=(1, 4, 4, 1), dtype=float32)

3. 分離卷積

?這里以深度可分離卷積Depth-wise Separable Convolution)為例。普通卷積在對多通道輸入進行運算時,卷積核的每個通道與輸入的每個通道分別進行卷積運算,得到多通道的特征圖,再對應元素相加產生單個卷積核的最終輸出,如下圖所示:

普通卷積計算示意圖


?分離卷積的計算流程則不同,卷積核的每個通道與輸入的每個通道進行卷積預算,得到多個通道的中間特征,如下圖所示。這個多通道的中間特征張量接下來進行多個1×11×11×1卷積核的普通卷積運算,得到多個高寬不變的輸出,這些輸出在通道軸上面進行拼接,從而產生最終的分離卷積層的輸出。可以看到,分離卷積層包含了兩步卷積運算,第一步卷積運算是單個卷積核,第二個卷積運算包含了多個卷積核。

深度可分離卷積計算示意圖


?那么采用分離卷積有什么優勢呢?一個很明顯的優勢在于,同樣的輸入和輸出,采用Separable Convolution的參數量約是普通卷積的13\frac{1}{3}31?。考慮上圖中的普通卷積和分離卷積的例子。普通卷積的參數量是
3?3?3?4=1083\cdot3\cdot3\cdot4=1083?3?3?4=108
分離卷積的第一部分參數量是
3?3?3?1=273\cdot3\cdot3\cdot1=273?3?3?1=27
第二部分參數量是
1?1?3?4=121\cdot1\cdot3\cdot4=121?1?3?4=12
分離卷積的總參數量只有39,但是卻能實現普通卷積同樣的輸入輸出尺寸變換。分離卷積在Xception和MobileNets等對計算代價敏感的領域中得到了大量應用。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的深度学习之卷积神经网络(11)卷积层变种的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。