Chapter5. 翻譯


[翻譯 chapter 5 ]


PS:? 有一部分在另外一臺電腦上, 明天稍后給出

Input and Kernel

我們在上面的例子中創建了兩個張量(tensor).? 張量 Input_batch 的形狀和上一節中見到的image_batch 的形狀很像。 這第一個張量將會是是被卷積的,第二個tensor 將會是卷積核。 Kernel 是一個很重要的術語,有的時候會被稱為權重(weights), 過濾器(filter),卷積矩陣(convolution matrix )或者是膜(mask)。由于這個任務(task)與計算機視覺相關,常常被看做image kernel ,所以使用kernel這個術語有一定意義。在Tensorflow中描述這個函數的時候,沒有本質上的區別。在Tensorflow中的參數被稱為 filter,? 它是一個從訓練中學習到的一組權重(weights)的集合。(PS: 嘿嘿, 這個時候看看 filter., weights )。

kernel ( filter parameter) 中包含的大量不同的權重將會在學習過程中被修改。

在示例代碼中,有一個內核是kernel變量的第一個維度。 kernel被構建后返回一個張量,其將包括第一個通道與原始輸入和原始輸入第二個通道加倍(2)。 在本文中,通道(channel)用于描述秩(rank)為1的張量(也就是向量)中的元素。 通道是計算機視覺中描述輸出向量的術語,例如RGB圖像具有三個通道,表示為rank為1的張量? [紅,綠,藍]。 現在,想不講stride和padding參數,這兩個參數將在以后的section中介紹,隨后也會集中關注卷積(tf.nn.conv2d)輸出。

conv2d = tf.nn.conv2d(input_batch, kernel, strides=[1, 1, 1, 1], padding='SAME')

sess.run(conv2d)

示例執行后輸出的結果是:

array([[[[ 0., 0.],

[ 1., 2.]],

[[ 2., 4.],

[ 3., 6.]]],

[[[ 2., 4.],

[ 4., 8.]],

[[ 6., 12.],

[ 8., 16.]]]], dtype=float32)

輸出的也是一個tensor, 它的rank 和input_batch 一樣, 而且維度的數量也可以在kernel 里面發現. 想象一下,如果 input_batch 代表一個只有一個通道的圖像, 也就是灰度級圖像. Tensor中的每個元素代表圖像上的每個像素點. 那么, 圖像右下角的像素值將為3.0。

將卷積操作tf.nn.conv2d 看作為 圖像( 用input_batch 表示) 和 張量kernel 的結合操作. 這兩個tensor的卷積會產生一個特征圖(a feature map). 特征圖是一個廣泛的術語,不僅僅只在計算機視覺中出現,它涉及與圖像內核一起使用的操作的輸出。當向output添加新圖層的時候, 特征圖代表了這些張量的卷積.

輸入圖像和特征圖輸出之間的關系可以從代碼中深入探索. 我們可以使用相同的索引,在輸入批次和特征圖中訪問元素。當訪問同一個像素下的輸入和特征的時候, 可以顯示出當輸入和kernel 卷積后的變化. 在下面的示例中, 可以發現圖像中右下角的像素被改變, 并可以通過乘法的方式找到改變后的值: 3.0*1.0 和 3.0*2.0 .? 相應的像素值以及對應的kernel 的值可以用以下方式找到:

lower_right_image_pixel = sess.run(input_batch)[0][1][1]

lower_right_kernel_pixel = sess.run(conv2d)[0][1][1]

lower_right_image_pixel, lower_right_kernel_pixel


上述代碼執行后,會輸出:

(array([ 3.], dtype=float32), array([ 3., 6.], dtype=float32))

在這個簡單的示例中, 圖像中的每個像素和卷積核中的對象值相乘, 并添加到相應的特征圖層(layer)中. 在上下文中, Layer(層)指的是輸出的新維度. 在這個例子中很難看到卷積運算過程中的值。


Strides(步長)

卷積在計算機視覺中的價值在于它能夠降低輸入維度,在本案中輸入指的是圖像。一個圖像(2D圖像)的維度是它的 寬,高和通道數。 對于神經網絡來說,掃描一個龐大的圖像維度并判斷哪些像素重要,這需要消耗大量的時間。使用卷積降低圖像的維數是通過改變內核的strides(步長)來完成的。

參數strides可以使得卷積核跳過圖像中的像素并在輸出的中不包含這些像素。說哪些像素被跳過是不公平的,因為這些像素仍然可能會影響輸出。當使用較大的圖像和更復雜的內核時,strides參數會突出顯示如何與內核一起使用卷積操作。由于卷積是將內核滑過輸入,可以使用 strides來設置如何在input上行走(walk). strides參數可以配置卷積以跳過某些元素,而不是遍歷輸入的每個元素。

PS: 作者對這個卷積核的操作描述為walk 實在是很形象,

例如,采取較大圖像和較大內核的卷積。 在這種情況下,它是6像素高,6像素寬和1通道深圖像(6x6x1)和(3x3x1)內核之間的卷積。

input_batch = tf.constant([

[ # First Input (6x6x1)

[[0.0], [1.0], [2.0], [3.0], [4.0], [5.0]],

[[0.1], [1.1], [2.1], [3.1], [4.1], [5.1]],

[[0.2], [1.2], [2.2], [3.2], [4.2], [5.2]],

[[0.3], [1.3], [2.3], [3.3], [4.3], [5.3]],

[[0.4], [1.4], [2.4], [3.4], [4.4], [5.4]],

[[0.5], [1.5], [2.5], [3.5], [4.5], [5.5]],

],

])

kernel = tf.constant([ # Kernel (3x3x1)

[[[0.0]], [[0.5]], [[0.0]]],

[[[0.0]], [[1.0]], [[0.0]]],

[[[0.0]], [[0.5]], [[0.0]]]

])

# NOTE: the change in the size of the strides parameter.

conv2d = tf.nn.conv2d(input_batch, kernel, strides=[1, 3, 3, 1], padding='SAME')

sess.run(conv2d)

代碼執行后的輸出如下:

array([[[[ 2.20000005],

[ 8.19999981]],

[[ 2.79999995],

[ 8.80000019]]]], dtype=float32)

通過在input_batch上按照步長移動kernel 使得inpout_batch 變量與kernel變量結合. 每次kernel移動后,他會在input_batch中得到確定的元素. 然后將重疊值相乘并將結果加在一起。 這是一個卷積如何使用所謂的逐點乘法去組合(combines)的兩個輸入。 使用下圖可能更直觀。


在該圖中,遵循代碼中的相同的邏輯。 將兩個張量進行卷積,同時使用跨越(stries)輸入。當內核大小允許卷積使用所有的輸入值的時候, 跨越(strides)會大幅度降低了輸出的維度.沒有一個輸入數據完全從striding中移除,除非輸入的張量較小。

Strides是調節輸入爭來那個維度的一種方式. 降低維度需要更少的處理能力,并且不會產生完全重疊的接受場(overlap)。strides參數遵循與輸入張量相同的格式

[image_batch_size_stride,image_height_stride,image_width_stride,image_channels_stride]。

通常情況下,很少更改stride參數的第一個或最后一個元素,因為這倆元素會使得tf.nn.conv2d操作跳過數據,并且不再考慮輸入數據了. image_height_stride和image_width_stride在減少輸入維數方面有用.

// ps? 作者在最后拋出一個問題,并預示著下一節的內容

跨越輸入的挑戰經常是如何處理不均勻地結束在輸入邊緣的步幅。這通常是由于圖像大小和內核大小不匹配,不均勻的步幅的時候會出現的問題。 如果圖像大小,內核大小和步幅都不能改變,則填充(padding)可以添加到圖像中以處理不均勻區域。

Padding

當內核重疊在圖像上時,應將其設置為適合圖像的邊界。 有時,尺寸可能不適合,一個很好的選擇是填補圖像中的缺失區域。 填充圖像的缺失區域稱為填充圖像。

TensorFlow會將用零填充圖像,或者當尺寸不允許內核跨越圖像而不超過其邊界時會引發錯誤。 tf.nn.conv2d的零的數量或錯誤狀態具是由兩個參數來控制padding. ('VALID','SAME')。

?SAME:? 意味著卷積的輸出和輸入的大小一樣, 當計算如何跨越圖像時,這不考慮過濾器尺寸; 當將所有缺少的值填充為零時,這可能會跨越存在的圖像的邊界。

VALID: 在計算如何跨越圖像時要考慮濾鏡尺寸。 這將盡可能將大量的保持內核在圖像的范圍內。在某些情況下可能有填充,但會避免。

// 給出了經驗貼

最好考慮輸入的大小,但是如果填充是必要的,那么TensorFlow有內置的選項。在大多數簡單的情況下,SAME是一個很好的選擇。 當輸入和內核與步幅良好時,優先使用VALID。 有關更多信息,TensorFlow在卷積文檔中很好地介紹了該話題().

Data Format

Tf.nn.conv2d的另一個參數是Data Format, 在以上的例子中并沒有使用到, tf.nn.conv2d的官方文檔中解釋其是 更改數據格式,以便input,kernel和strides遵循迄今為止使用的格式以外的格式。如果輸入input tensor 不是遵守[bantch_size, height, width, channel] 標準的話, 修改數據格式還是很有用的. 這種情況出現的話, 可以不將輸入更改為所匹配的形式,更改data_format參數以使用不同的布局就行了.

data_format: An optional string from: “NHWC”, “NCHW”. Defaults to “NHWC”. Specify the data format of the input and output data. With the default format “NHWC”, the data is stored in the order of: [batch, in_height, in_width, in_channels]. Alternatively, the format could be “NCHW”, the data storage order of: [batch, in_channels, in_height, in_width]


Data Format

------by 8月8號


Kernels in Depth(卷積核和深度)


在TensorFlow中,filter參數用于指定與輸入進行卷積的內核。過濾器通常是攝影中以調整圖像的屬性,例如允許到達相機鏡頭的陽光的量。在攝影中,過濾器允許攝影師徹底改變他們拍攝的照片。攝影師能夠使用過濾器改變照片的原因是因為過濾器可以識別進入鏡頭的光的某些屬性。例如,紅色透鏡濾光片將吸收(阻擋)不是紅色的每個頻率的頻率,只允許紅色通過濾光片。



在計算機視覺中,內核(過濾器)用于識別數字圖像的重要屬性。他們通過使用某些模式來突出顯示圖像中存在的特征。將復制紅色濾鏡示例圖像的內核通過對除紅色以外的所有顏色使用減小值來實現。在這種情況下,紅色將保持不變,但所有其他匹配的顏色都會減少。


本章開始的例子使用了一個設計用于執行邊緣檢測的內核。邊緣檢測內核在計算機視覺應用中是常見的,并且可以使用基本的TensorFlow操作和單個tf.nn.conv2d操作來實現。













最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容