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.]]]]