在 tensorflow 中计算 conv2d 的输出
Computing outputs from conv2d in tensorflow
想直观的了解一下tensorflow中的tf.nn.conv2d()
函数。原因 i post 这是因为当输入是一维数组时,卷积很难解释。这是一个例子。
假设我有一个 [1x5] 输入特征向量。
d = [x for x in range(1,6)]
print('Inputs:', d)
现在重塑并展平为张量。
d = tf.reshape(d, shape=[-1,1,5,1])
print ("New shape : ",d.get_shape().as_list())
新形状:[1, 1, 5, 1]
# convert inputs to float32
d = tf.cast(d,tf.float32)
应用大小为 [2x2] 的过滤器,然后以步长为 1 进行卷积。
w1 = np.random.randint(5, size=(2,2))
w1 = tf.reshape(w1, shape=[2,2,1,1])
w1 = tf.cast(w1, tf.float32)
# Apply conv layer
d_conv = tf.nn.conv2d(d, w1, strides=[1,1,1,1], padding='SAME')
# run session
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print('\nFilter: ', w1.eval())
print('\nShape after convolution:',d_conv.eval().shape)
print('\nConv output:',d_conv.eval())
输出。
Inputs: [1, 2, 3, 4, 5]
Filter: [[[[ 3.]]
[[ 1.]]]
[[[ 2.]]
[[ 3.]]]]
Shape after convolution: (1, 1, 5, 1)
Conv output: [[[[ 5.]
[ 9.]
[ 13.]
[ 17.]
[ 15.]]]]
分析
输出是卷积过滤器 [[[ 3.]] [[ 1.]]]] 与输入 d
的结果,步长为 1,5 之后的最后一个元素是 zero padded
.
看起来过滤器元素 [[[ 2.]] [[ 3.]]]] 从未应用过。
如果有人能解释发生了什么,那就太好了。最好是增加过滤器大小 w1
并计算出,即 w1 = np.random.randint(10, size=(3,3)), w1 = tf.reshape(w1, shape=[3,3,1,1])
但我仍然得到奇怪的输出。
非常感谢。
根据 documentation 填充 SAME
涉及以下内容:
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
if (in_height % strides[1] == 0):
pad_along_height = max(filter_height - strides[1], 0)
else:
pad_along_height = max(filter_height - (in_height % strides[1]), 0)
if (in_width % strides[2] == 0):
pad_along_width = max(filter_width - strides[2], 0)
else:
pad_along_width = max(filter_width - (in_width % strides[2]), 0)
pad_top = pad_along_height // 2
pad_bottom = pad_along_height - pad_top
pad_left = pad_along_width // 2
pad_right = pad_along_width - pad_left
在你的例子中
filter_height = 2
filter_width = 2
in_height = 1
in_width = 5
strides = [1 1 1 1]
这导致以下填充:
pad_top = 0
pad_bottom = 1
pad_left = 0
pad_right = 1
零填充输入(省略通道和批量维度):
1 2 3 4 5 0
0 0 0 0 0 0
与核卷积(省略通道维度)
3 1
2 3
给出以下内容:
[ 1 ( 2 ][ 3 )( 4 ][ 5 ) 0 ]
[ 0 ( 0 ][ 0 )( 0 ][ 0 ) 0 ]
[ 3 1 ][ 3 1 ][ 3 1 ]
[ 2 3 ][ 2 3 ][ 2 3 ]
( 3 1 )( 3 1 )
( 2 3 )( 2 3 )
[5] (9) [13] (17) [15]
此处相同类型的大括号显示与内核卷积的输入数据中的位置。例如:
[ 1 2 ] [ 3 1 ]
* = [5]
[ 0 0 ] [ 2 3 ]
( 2 3 ) ( 3 1 )
* = (9)
( 0 0 ) ( 2 3 )
以此类推
想直观的了解一下tensorflow中的tf.nn.conv2d()
函数。原因 i post 这是因为当输入是一维数组时,卷积很难解释。这是一个例子。
假设我有一个 [1x5] 输入特征向量。
d = [x for x in range(1,6)]
print('Inputs:', d)
现在重塑并展平为张量。
d = tf.reshape(d, shape=[-1,1,5,1])
print ("New shape : ",d.get_shape().as_list())
新形状:[1, 1, 5, 1]
# convert inputs to float32
d = tf.cast(d,tf.float32)
应用大小为 [2x2] 的过滤器,然后以步长为 1 进行卷积。
w1 = np.random.randint(5, size=(2,2))
w1 = tf.reshape(w1, shape=[2,2,1,1])
w1 = tf.cast(w1, tf.float32)
# Apply conv layer
d_conv = tf.nn.conv2d(d, w1, strides=[1,1,1,1], padding='SAME')
# run session
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print('\nFilter: ', w1.eval())
print('\nShape after convolution:',d_conv.eval().shape)
print('\nConv output:',d_conv.eval())
输出。
Inputs: [1, 2, 3, 4, 5]
Filter: [[[[ 3.]]
[[ 1.]]]
[[[ 2.]]
[[ 3.]]]]
Shape after convolution: (1, 1, 5, 1)
Conv output: [[[[ 5.]
[ 9.]
[ 13.]
[ 17.]
[ 15.]]]]
分析
输出是卷积过滤器 [[[ 3.]] [[ 1.]]]] 与输入 d
的结果,步长为 1,5 之后的最后一个元素是 zero padded
.
看起来过滤器元素 [[[ 2.]] [[ 3.]]]] 从未应用过。
如果有人能解释发生了什么,那就太好了。最好是增加过滤器大小 w1
并计算出,即 w1 = np.random.randint(10, size=(3,3)), w1 = tf.reshape(w1, shape=[3,3,1,1])
但我仍然得到奇怪的输出。
非常感谢。
根据 documentation 填充 SAME
涉及以下内容:
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
if (in_height % strides[1] == 0):
pad_along_height = max(filter_height - strides[1], 0)
else:
pad_along_height = max(filter_height - (in_height % strides[1]), 0)
if (in_width % strides[2] == 0):
pad_along_width = max(filter_width - strides[2], 0)
else:
pad_along_width = max(filter_width - (in_width % strides[2]), 0)
pad_top = pad_along_height // 2
pad_bottom = pad_along_height - pad_top
pad_left = pad_along_width // 2
pad_right = pad_along_width - pad_left
在你的例子中
filter_height = 2
filter_width = 2
in_height = 1
in_width = 5
strides = [1 1 1 1]
这导致以下填充:
pad_top = 0
pad_bottom = 1
pad_left = 0
pad_right = 1
零填充输入(省略通道和批量维度):
1 2 3 4 5 0
0 0 0 0 0 0
与核卷积(省略通道维度)
3 1
2 3
给出以下内容:
[ 1 ( 2 ][ 3 )( 4 ][ 5 ) 0 ]
[ 0 ( 0 ][ 0 )( 0 ][ 0 ) 0 ]
[ 3 1 ][ 3 1 ][ 3 1 ]
[ 2 3 ][ 2 3 ][ 2 3 ]
( 3 1 )( 3 1 )
( 2 3 )( 2 3 )
[5] (9) [13] (17) [15]
此处相同类型的大括号显示与内核卷积的输入数据中的位置。例如:
[ 1 2 ] [ 3 1 ]
* = [5]
[ 0 0 ] [ 2 3 ]
( 2 3 ) ( 3 1 )
* = (9)
( 0 0 ) ( 2 3 )
以此类推