CNN輸出維度的計算


在 CNN 的一層中的 patch 中共享權重 w ,無論貓在圖片的哪個位置都可以找到。

 

當我們試圖識別一個貓的圖片的時候,我們並不在意貓出現在哪個位置。無論是左上角,右下角,它在你眼里都是一只貓。我們希望 CNNs 能夠無差別的識別,這如何做到呢?

如我們之前所見,一個給定的 patch 的分類,是由 patch 對應的權重和偏置項決定的。

如果我們想讓左上角的貓與右下角的貓以同樣的方式被識別,他們的權重和偏置項需要一樣,這樣他們才能以同一種方法識別。

這正是我們在 CNNs 中做的。一個給定輸出層學到的權重和偏置項會共享在輸入層所有的 patch 里。注意,當我們增大濾波器的深度的時候,我們需要學習的權重和偏置項的數量也會增加,因為權重並沒有共享在所有輸出的 channel 里。

共享參數還有一個額外的好處。如果我們不在所有的 patch 里用相同的權重,我們必須對每一個 patch 和它對應的隱藏層神經元學習新的參數。這不利於規模化,特別對於高清圖片。因此,共享權重不僅幫我們平移不變,還給我們一個更小,可以規模化的模型。

 

Padding

 

一個 5x5 的網格附帶一個 3x3 的濾波器。來源: Andrej Karpathy。

 

假設現在有一個 5x5 網格 (如上圖所示) 和一個尺寸為 3x3 stride值為 1 的濾波器(filter)。 下一層的 width 和 height 是多少呢? 如圖中所示,在水平和豎直方向都可以在3個不同的位置放置 patch, 下一層的維度即為 3x3。下一層寬和高的尺寸就會按此規則縮放。

在理想狀態下,我們可以在層間保持相同的寬度和高度,以便繼續添加圖層,保持網絡的一致性,而不用擔心維度的縮小。如何實現這一構想?其中一種簡單的辦法是,在 5x5 原始圖片的外層包裹一圈 0 ,如下圖所示。

 

加了 0 padding的相同網格。 來源: Andrej Karpathy。

這將會把原始圖片擴展到 7x7。 現在我們知道如何讓下一層圖片的尺寸維持在 5x5,保持維度的一致性。

維度

綜合目前所學的知識,我們應該如何計算 CNN 中每一層神經元的數量呢?

輸入層(input layer)維度值為W, 濾波器(filter)的維度值為 F (height * width * depth), stride 的數值為 S, padding 的數值為 P, 下一層的維度值可用如下公式表示: (W−F+2P)/S+1

我們可以通過每一層神經元的維度信息,得知模型的規模,並了解到我們設定的 filter size 和 stride 如何影響整個神經網絡的尺寸。

介紹

接下來的幾個練習將檢測你對 CNNs 維度的理解,理解維度可以幫你在模型大小和模型質量上,做精確的權衡。你將會了解,一些參數對模型大小的影響會遠大於另外一些。

設置

H = height, W = width, D = depth

  • 我們有一個輸入維度是 32x32x3 (HxWxD)
  • 20個維度為 8x8x3 (HxWxD) 的濾波器
  • 高和寬的stride(步長)都為 2。(S)
  • padding 大小為1 (P)

計算新的高度和寬度的公式是:

new_height = (input_height - filter_height + 2 * P)/S + 1 new_width = (input_width - filter_width + 2 * P)/S + 1

卷積層輸出維度

輸出的維度(shape)是什么?  14x14x20


代入公式可以得到下列結果:

(32 - 8 + 2 * 1)/2 + 1 = 14 (32 - 8 + 2 * 1)/2 + 1 = 14 

新的深度與濾波器的數量相同,都是 20。

對應如下代碼:

input = tf.placeholder(tf.float32, (None, 32, 32, 3))
filter_weights = tf.Variable(tf.truncated_normal((8, 8, 3, 20))) # (height, width, input_depth, output_depth)
filter_bias = tf.Variable(tf.zeros(20))
strides = [1, 2, 2, 1] # (batch, height, width, depth)
padding = 'VALID'
conv = tf.nn.conv2d(input, filter_weights, strides, padding) + filter_bias

注意,這里的conv 輸出的是 [1, 13, 13, 20]。這是對應 batch size 的 4D 大小,重要的是它不是 [1, 14, 14, 20]。這是因為 TensorFlow 的 padding 算法與上面的並不完全相同。一個可替換方案是把 padding 從 'VALID' 改為'SAME',這樣得到的結果是 [1, 16, 16, 20]。如果你想了解 TensorFlow 中的 padding 如何工作,可以看這個文檔

總之,TensorFlow 使用如下等式計算 SAME 、PADDING

SAME Padding, 輸出的高和寬,計算如下:

out_height = ceil(float(in_height) / float(strides1))

out_width = ceil(float(in_width) / float(strides[2]))

VALID Padding, 輸出的高和寬,計算如下:

out_height = ceil(float(in_height - filter_height + 1) / float(strides1))

out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM