[翻譯 chapter 5 ]
PS:? 有一部分在另外一臺(tái)電腦上, 明天稍后給出
Input and Kernel
我們?cè)谏厦娴睦又袆?chuàng)建了兩個(gè)張量(tensor).? 張量 Input_batch 的形狀和上一節(jié)中見(jiàn)到的image_batch 的形狀很像雁刷。 這第一個(gè)張量將會(huì)是是被卷積的沛励,第二個(gè)tensor 將會(huì)是卷積核目派。 Kernel 是一個(gè)很重要的術(shù)語(yǔ)企蹭,有的時(shí)候會(huì)被稱為權(quán)重(weights), 過(guò)濾器(filter)遍蟋,卷積矩陣(convolution matrix )或者是膜(mask)虚青。由于這個(gè)任務(wù)(task)與計(jì)算機(jī)視覺(jué)相關(guān)棒厘,常常被看做image kernel 奢人,所以使用kernel這個(gè)術(shù)語(yǔ)有一定意義何乎。在Tensorflow中描述這個(gè)函數(shù)的時(shí)候,沒(méi)有本質(zhì)上的區(qū)別各墨。在Tensorflow中的參數(shù)被稱為 filter,? 它是一個(gè)從訓(xùn)練中學(xué)習(xí)到的一組權(quán)重(weights)的集合贬堵。(PS: 嘿嘿黎做, 這個(gè)時(shí)候看看 filter., weights )引几。
kernel ( filter parameter) 中包含的大量不同的權(quán)重將會(huì)在學(xué)習(xí)過(guò)程中被修改敞掘。
在示例代碼中玖雁,有一個(gè)內(nèi)核是kernel變量的第一個(gè)維度赫冬。 kernel被構(gòu)建后返回一個(gè)張量劲厌,其將包括第一個(gè)通道與原始輸入和原始輸入第二個(gè)通道加倍(2)。 在本文中风范,通道(channel)用于描述秩(rank)為1的張量(也就是向量)中的元素硼婿。 通道是計(jì)算機(jī)視覺(jué)中描述輸出向量的術(shù)語(yǔ)寇漫,例如RGB圖像具有三個(gè)通道,表示為rank為1的張量? [紅,綠彻采,藍(lán)]肛响。 現(xiàn)在,想不講stride和padding參數(shù)猎物,這兩個(gè)參數(shù)將在以后的section中介紹蔫磨,隨后也會(huì)集中關(guān)注卷積(tf.nn.conv2d)輸出堤如。
conv2d = tf.nn.conv2d(input_batch, kernel, strides=[1, 1, 1, 1], padding='SAME')
sess.run(conv2d)
示例執(zhí)行后輸出的結(jié)果是:
array([[[[ 0., 0.],
[ 1., 2.]],
[[ 2., 4.],
[ 3., 6.]]],
[[[ 2., 4.],
[ 4., 8.]],
[[ 6., 12.],
[ 8., 16.]]]], dtype=float32)
輸出的也是一個(gè)tensor, 它的rank 和input_batch 一樣, 而且維度的數(shù)量也可以在kernel 里面發(fā)現(xiàn). 想象一下,如果 input_batch 代表一個(gè)只有一個(gè)通道的圖像, 也就是灰度級(jí)圖像. Tensor中的每個(gè)元素代表圖像上的每個(gè)像素點(diǎn). 那么, 圖像右下角的像素值將為3.0蝗岖。
將卷積操作tf.nn.conv2d 看作為 圖像( 用input_batch 表示) 和 張量kernel 的結(jié)合操作. 這兩個(gè)tensor的卷積會(huì)產(chǎn)生一個(gè)特征圖(a feature map). 特征圖是一個(gè)廣泛的術(shù)語(yǔ),不僅僅只在計(jì)算機(jī)視覺(jué)中出現(xiàn)瓣俯,它涉及與圖像內(nèi)核一起使用的操作的輸出彩匕。當(dāng)向output添加新圖層的時(shí)候, 特征圖代表了這些張量的卷積.
輸入圖像和特征圖輸出之間的關(guān)系可以從代碼中深入探索. 我們可以使用相同的索引,在輸入批次和特征圖中訪問(wèn)元素绪爸。當(dāng)訪問(wèn)同一個(gè)像素下的輸入和特征的時(shí)候, 可以顯示出當(dāng)輸入和kernel 卷積后的變化. 在下面的示例中, 可以發(fā)現(xiàn)圖像中右下角的像素被改變, 并可以通過(guò)乘法的方式找到改變后的值: 3.0*1.0 和 3.0*2.0 .? 相應(yīng)的像素值以及對(duì)應(yīng)的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
上述代碼執(zhí)行后,會(huì)輸出:
(array([ 3.], dtype=float32), array([ 3., 6.], dtype=float32))
在這個(gè)簡(jiǎn)單的示例中, 圖像中的每個(gè)像素和卷積核中的對(duì)象值相乘, 并添加到相應(yīng)的特征圖層(layer)中. 在上下文中, Layer(層)指的是輸出的新維度. 在這個(gè)例子中很難看到卷積運(yùn)算過(guò)程中的值。
Strides(步長(zhǎng))
卷積在計(jì)算機(jī)視覺(jué)中的價(jià)值在于它能夠降低輸入維度递惋,在本案中輸入指的是圖像萍虽。一個(gè)圖像(2D圖像)的維度是它的 寬,高和通道數(shù)邓馒。 對(duì)于神經(jīng)網(wǎng)絡(luò)來(lái)說(shuō)绒净,掃描一個(gè)龐大的圖像維度并判斷哪些像素重要挂疆,這需要消耗大量的時(shí)間宝当。使用卷積降低圖像的維數(shù)是通過(guò)改變內(nèi)核的strides(步長(zhǎng))來(lái)完成的庆揩。
參數(shù)strides可以使得卷積核跳過(guò)圖像中的像素并在輸出的中不包含這些像素订晌。說(shuō)哪些像素被跳過(guò)是不公平的,因?yàn)檫@些像素仍然可能會(huì)影響輸出奕枢。當(dāng)使用較大的圖像和更復(fù)雜的內(nèi)核時(shí)缝彬,strides參數(shù)會(huì)突出顯示如何與內(nèi)核一起使用卷積操作。由于卷積是將內(nèi)核滑過(guò)輸入一疯,可以使用 strides來(lái)設(shè)置如何在input上行走(walk). strides參數(shù)可以配置卷積以跳過(guò)某些元素违施,而不是遍歷輸入的每個(gè)元素。
PS: 作者對(duì)這個(gè)卷積核的操作描述為walk 實(shí)在是很形象辣往,
例如站削,采取較大圖像和較大內(nèi)核的卷積。 在這種情況下园细,它是6像素高猛频,6像素寬和1通道深圖像(6x6x1)和(3x3x1)內(nèi)核之間的卷積。
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)
代碼執(zhí)行后的輸出如下:
array([[[[ 2.20000005],
[ 8.19999981]],
[[ 2.79999995],
[ 8.80000019]]]], dtype=float32)
通過(guò)在input_batch上按照步長(zhǎng)移動(dòng)kernel 使得inpout_batch 變量與kernel變量結(jié)合. 每次kernel移動(dòng)后,他會(huì)在input_batch中得到確定的元素. 然后將重疊值相乘并將結(jié)果加在一起。 這是一個(gè)卷積如何使用所謂的逐點(diǎn)乘法去組合(combines)的兩個(gè)輸入招刹。 使用下圖可能更直觀。
在該圖中,遵循代碼中的相同的邏輯越锈。 將兩個(gè)張量進(jìn)行卷積甘凭,同時(shí)使用跨越(stries)輸入德撬。當(dāng)內(nèi)核大小允許卷積使用所有的輸入值的時(shí)候, 跨越(strides)會(huì)大幅度降低了輸出的維度.沒(méi)有一個(gè)輸入數(shù)據(jù)完全從striding中移除蜓洪,除非輸入的張量較小隆檀。
Strides是調(diào)節(jié)輸入爭(zhēng)來(lái)那個(gè)維度的一種方式. 降低維度需要更少的處理能力,并且不會(huì)產(chǎn)生完全重疊的接受場(chǎng)(overlap)菊霜。strides參數(shù)遵循與輸入張量相同的格式
[image_batch_size_stride,image_height_stride构捡,image_width_stride勾徽,image_channels_stride]。
通常情況下,很少更改stride參數(shù)的第一個(gè)或最后一個(gè)元素吹由,因?yàn)檫@倆元素會(huì)使得tf.nn.conv2d操作跳過(guò)數(shù)據(jù),并且不再考慮輸入數(shù)據(jù)了. image_height_stride和image_width_stride在減少輸入維數(shù)方面有用.
// ps? 作者在最后拋出一個(gè)問(wèn)題,并預(yù)示著下一節(jié)的內(nèi)容
跨越輸入的挑戰(zhàn)經(jīng)常是如何處理不均勻地結(jié)束在輸入邊緣的步幅。這通常是由于圖像大小和內(nèi)核大小不匹配乌昔,不均勻的步幅的時(shí)候會(huì)出現(xiàn)的問(wèn)題磕道。 如果圖像大小贯卦,內(nèi)核大小和步幅都不能改變,則填充(padding)可以添加到圖像中以處理不均勻區(qū)域责循。
Padding
當(dāng)內(nèi)核重疊在圖像上時(shí)萨螺,應(yīng)將其設(shè)置為適合圖像的邊界。 有時(shí)徘层,尺寸可能不適合,一個(gè)很好的選擇是填補(bǔ)圖像中的缺失區(qū)域跷敬。 填充圖像的缺失區(qū)域稱為填充圖像。
TensorFlow會(huì)將用零填充圖像拥褂,或者當(dāng)尺寸不允許內(nèi)核跨越圖像而不超過(guò)其邊界時(shí)會(huì)引發(fā)錯(cuò)誤。 tf.nn.conv2d的零的數(shù)量或錯(cuò)誤狀態(tài)具是由兩個(gè)參數(shù)來(lái)控制padding. ('VALID'尤慰,'SAME')。
?SAME:? 意味著卷積的輸出和輸入的大小一樣, 當(dāng)計(jì)算如何跨越圖像時(shí)责蝠,這不考慮過(guò)濾器尺寸; 當(dāng)將所有缺少的值填充為零時(shí)齿拂,這可能會(huì)跨越存在的圖像的邊界。
VALID: 在計(jì)算如何跨越圖像時(shí)要考慮濾鏡尺寸砸狞。 這將盡可能將大量的保持內(nèi)核在圖像的范圍內(nèi)。在某些情況下可能有填充研底,但會(huì)避免。
// 給出了經(jīng)驗(yàn)貼
最好考慮輸入的大小芽隆,但是如果填充是必要的,那么TensorFlow有內(nèi)置的選項(xiàng)腕扶。在大多數(shù)簡(jiǎn)單的情況下半抱,SAME是一個(gè)很好的選擇。 當(dāng)輸入和內(nèi)核與步幅良好時(shí)史简,優(yōu)先使用VALID跺讯。 有關(guān)更多信息,TensorFlow在卷積文檔中很好地介紹了該話題().
Data Format
Tf.nn.conv2d的另一個(gè)參數(shù)是Data Format, 在以上的例子中并沒(méi)有使用到, tf.nn.conv2d的官方文檔中解釋其是 更改數(shù)據(jù)格式愈污,以便input聪建,kernel和strides遵循迄今為止使用的格式以外的格式。如果輸入input tensor 不是遵守[bantch_size, height, width, channel] 標(biāo)準(zhǔn)的話, 修改數(shù)據(jù)格式還是很有用的. 這種情況出現(xiàn)的話, 可以不將輸入更改為所匹配的形式茫陆,更改data_format參數(shù)以使用不同的布局就行了.
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]
------by 8月8號(hào)
Kernels in Depth(卷積核和深度)
在TensorFlow中,filter參數(shù)用于指定與輸入進(jìn)行卷積的內(nèi)核簿盅。過(guò)濾器通常是攝影中以調(diào)整圖像的屬性,例如允許到達(dá)相機(jī)鏡頭的陽(yáng)光的量棚瘟。在攝影中喜最,過(guò)濾器允許攝影師徹底改變他們拍攝的照片偎蘸。攝影師能夠使用過(guò)濾器改變照片的原因是因?yàn)檫^(guò)濾器可以識(shí)別進(jìn)入鏡頭的光的某些屬性。例如瞬内,紅色透鏡濾光片將吸收(阻擋)不是紅色的每個(gè)頻率的頻率,只允許紅色通過(guò)濾光片虫蝶。
在計(jì)算機(jī)視覺(jué)中,內(nèi)核(過(guò)濾器)用于識(shí)別數(shù)字圖像的重要屬性能真。他們通過(guò)使用某些模式來(lái)突出顯示圖像中存在的特征赁严。將復(fù)制紅色濾鏡示例圖像的內(nèi)核通過(guò)對(duì)除紅色以外的所有顏色使用減小值來(lái)實(shí)現(xiàn)。在這種情況下粉铐,紅色將保持不變疼约,但所有其他匹配的顏色都會(huì)減少蝙泼。
本章開(kāi)始的例子使用了一個(gè)設(shè)計(jì)用于執(zhí)行邊緣檢測(cè)的內(nèi)核忆谓。邊緣檢測(cè)內(nèi)核在計(jì)算機(jī)視覺(jué)應(yīng)用中是常見(jiàn)的踱承,并且可以使用基本的TensorFlow操作和單個(gè)tf.nn.conv2d操作來(lái)實(shí)現(xiàn)倡缠。