tensorflow conv2-same 理解

数字理解

输出结果的shape计算:
‘SAME’ 类型的padding,其输出的height和width计算如下:
out_height = ceil(float(in_height) / float(strides[1])) ceil:向上取整
out_width = ceil(float(in_width) / float(strides[2]))

‘VALID’类型的padding, 其输出的height和width计算如下:
out_height = ceil(float(in_height – filter_height + 1) / float(strides[1]))
out_width = ceil(float(in_width – filter_width + 1) / float(strides[2]))

图片理解

具体计算理解

1
2
3
4
5
6
7
8
9
10
x =
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6

w =
0 1 2
1 2 3
2 3 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def testConv2DSameEven(self):
n, n2 = 4, 2

# Input image.
x = create_test_input(1, n, n, 1)

# Convolution kernel.
w = create_test_input(1, 3, 3, 1)
w = array_ops.reshape(w, [3, 3, 1, 1])

variable_scope.get_variable('Conv/weights', initializer=w)
variable_scope.get_variable('Conv/biases', initializer=array_ops.zeros([1]))
variable_scope.get_variable_scope().reuse_variables()

y1 = layers.conv2d(x, 1, [3, 3], stride=1, scope='Conv')
y1_expected = math_ops.to_float([[14, 28, 43, 26], [28, 48, 66, 37],
[43, 66, 84, 46], [26, 37, 46, 22]])
y1_expected = array_ops.reshape(y1_expected, [1, n, n, 1])

y2 = resnet_utils.subsample(y1, 2)
y2_expected = math_ops.to_float([[14, 43], [43, 84]])
y2_expected = array_ops.reshape(y2_expected, [1, n2, n2, 1])

y3 = resnet_utils.conv2d_same(x, 1, 3, stride=2, scope='Conv')
y3_expected = y2_expected

y4 = layers.conv2d(x, 1, [3, 3], stride=2, scope='Conv')
y4_expected = math_ops.to_float([[48, 37], [37, 22]])
y4_expected = array_ops.reshape(y4_expected, [1, n2, n2, 1])

with self.test_session() as sess:
sess.run(variables.global_variables_initializer())
self.assertAllClose(y1.eval(), y1_expected.eval())
self.assertAllClose(y2.eval(), y2_expected.eval())
self.assertAllClose(y3.eval(), y3_expected.eval())
self.assertAllClose(y4.eval(), y4_expected.eval())

总结

1
2
3
4
5
1. net = conv2d_same(inputs, num_outputs, 3, stride=stride)
2. net = slim.conv2d(inputs, num_outputs, 3, stride=1, padding='SAME')
net = subsample(net, factor=stride)
3. net = slim.conv2d(inputs, num_outputs, 3, stride=stride, padding='SAME')
1和2是等价的,当inputs的高或宽是偶数时3与1,2不一样。
请作者喝一杯咖啡☕️