Tensorflow–池化操作
pool(池化)操作與卷積運算類似,取輸入張量的每一個位置的矩形鄰域內值的最大值或平均值作為該位置的輸出值,如果取的是最大值,則稱為最大值池化;如果取的是平均值,則稱為平均值池化。pooling操作在圖像處理中的應用類似於均值平滑,形態學處理,下采樣等操作,與卷積類似,池化也分為same池化和valid池化
一.same池化
same池化的操作方式一般有兩種:same最大值池化和same平均值池化
1.same最大值池化
我們以4行4列的張量x和2行3列的鄰域掩碼為例,介紹same最大值池化的計算過程
same池化的鄰域掩碼同same卷積的卷積核類似,需要指定錨點,該錨點的位置和same卷積時卷積核的錨點位置類似。其規則一樣,不懂請看下面鏈接:
Tensorflow通過函數tf.nn.max_pool實現最大值池化操作
import tensorflow as tf
# 輸入形狀為[1,4,1,4]的張量
value2d=tf.constant(
[
# 第1個4行4列1深度的三維張量
[
[[2],[3],[8],[-2]],
[[6],[1],[5],[9]],
[[7],[2],[-1],[8]],
[[1],[4],[3],[5]]
]
]
,tf.float32
)
# 最大值池化操作
value2d_maxPool=tf.nn.max_pool(value2d,(1,2,3,1),[1,1,1,1],'SAME')
session=tf.Session()
print(session.run(value2d_maxPool))
[[[[6.]
[8.]
[9.]
[9.]]
[[7.]
[7.]
[9.]
[9.]]
[[7.]
[7.]
[8.]
[8.]]
[[4.]
[4.]
[5.]
[5.]]]]
上述代碼處理的是深度為1的三維張量的池化操作,且鄰域掩碼在沿行和列方向的移動步長均為1
2.多深度張量的same池化
本質上,多深度到的same最大值池化操作是在每一深度上分別進行池化操作,結果並未改變原張量的深度。我們以3行3列2深度的三維張量和2行2列2深度鄰域掩碼的same最大值池化操作
如果same池化操作過程中鄰域掩碼沿行和沿列的移動步長均為2
import tensorflow as tf
value3d=tf.constant(
[
# 第1個3行3列2深度的三維張量
[
[[2,5],[3,3],[8,2]],
[[6,1],[1,2],[5,4]],
[[7,9],[2,-3],[-1,3]]
]
]
,tf.float32
)
# 2行2列2深度的池化掩碼,在行方向上的移動步長為2,在列方向上的移動步長為2
value3d_maxPool=tf.nn.max_pool(value3d,(1,2,2,1),[1,2,2,1],'SAME')
session=tf.Session()
print(session.run(value3d_maxPool))
[[[[ 6. 5.]
[ 8. 4.]]
[[ 7. 9.]
[-1. 3.]]]]
3.多個三維張量的same最大值池化
以2個深度為2的三維張量分別與2行2列的鄰域掩碼的same最大值池化操作,其沿行和沿列方向的移動步長為2
import tensorflow as tf
value3d=tf.constant(
[
# 第1個3行3列2深度的三維張量
[
[[2,5],[3,3],[8,2]],
[[6,1],[1,2],[5,4]],
[[7,9],[2,-3],[-1,3]]
],
# 第1個3行3列2深度的三維張量
[
[[1,4],[9,3],[1,1]],
[[1,1],[1,2],[3,3]],
[[2,1],[3,6],[4,2]]
]
]
,tf.float32
)
# 2行2列2深度的池化掩碼,在行方向上的移動步長為2,在列方向上的移動步長為2
value3d_maxPool=tf.nn.max_pool(value3d,(1,2,2,1),[1,2,2,1],'SAME')
session=tf.Session()
print(session.run(value3d_maxPool))
[[[[ 6. 5.]
[ 8. 4.]]
[[ 7. 9.]
[-1. 3.]]]
[[[ 9. 4.]
[ 3. 3.]]
[[ 3. 6.]
[ 4. 2.]]]]
4.same平均值池化
Tensorflow通過函數tf.nn.avg_pool實現平均值池化,使用方法和函數tf.nn.max_pool類似,以上示例代碼如下:
value3d_avgPool=tf.nn.avg_pool(value3d,(1,2,2,1),[1,2,2,1],'SAME')
import tensorflow as tf
value3d=tf.constant(
[
# 第1個3行3列2深度的三維張量
[
[[2,5],[3,3],[8,2]],
[[6,1],[1,2],[5,4]],
[[7,9],[2,-3],[-1,3]]
]
]
,tf.float32
)
# 2行2列2深度的池化掩碼,在行方向上的移動步長為2,在列方向上的移動步長為2
value3d_avgPool=tf.nn.avg_pool(value3d,(1,2,2,1),[1,2,2,1],'SAME')
session=tf.Session()
print(session.run(value3d_avgPool))
[[[[ 3. 2.75]
[ 6.5 3. ]]
[[ 4.5 3. ]
[-1. 3. ]]]]
二.valid池化
valid池化與same池化的不同之處在於鄰域掩碼只在張量內移動
1.valid的最大值池化
value3d_maxPool=tf.nn.max_pool(value3d,(1,2,2,1),[1,1,1,1],'VALID')
2.多深度張量的valid池化
以3行3列2深度的三維張量和2行2列的鄰域掩碼的valid最大值池化為例
import tensorflow as tf
value3d=tf.constant(
[
# 第1個3行3列2深度的三維張量
[
[[2,5],[3,3],[8,2]],
[[6,1],[1,2],[5,4]],
[[7,9],[2,-3],[-1,3]]
]
]
,tf.float32
)
# 2行2列2深度的池化掩碼,在行方向上的移動步長為1,在列方向上的移動步長為1
value3d_maxPool=tf.nn.max_pool(value3d,(1,2,2,1),[1,1,1,1],'VALID')
session=tf.Session()
print(session.run(value3d_maxPool))
[[[[6. 5.]
[8. 4.]]
[[7. 9.]
[5. 4.]]]]
3.多個三維張量的valid池化
import tensorflow as tf
value3d=tf.constant(
[
# 第1個3行3列2深度的三維張量
[
[[2,5],[3,3],[8,2]],
[[6,1],[1,2],[5,4]],
[[7,9],[2,-3],[-1,3]]
],
# 第1個3行3列2深度的三維張量
[
[[1,4],[9,3],[1,1]],
[[1,1],[1,2],[3,3]],
[[2,1],[3,6],[4,2]]
]
]
,tf.float32
)
# 2行2列2深度的池化掩碼,在行方向上的移動步長為2,在列方向上的移動步長為2
value3d_maxPool=tf.nn.max_pool(value3d,(1,2,2,1),[1,1,1,1],'VALID')
session=tf.Session()
print(session.run(value3d_maxPool))
[[[[6. 5.]
[8. 4.]]
[[7. 9.]
[5. 4.]]]
[[[9. 4.]
[9. 3.]]
[[3. 6.]
[4. 6.]]]]