Tensorflow中slice与cancat的使用

两个函数都是卷积神经网络中的常见操作,
再修改tf.conrib.slim 程序时,slim 没有自带的slice操作,但是可以直接使用tf的slice操作代替。

1
2
3
4
5
6
7
8
t = tf.constant([[[1, 1, 1], [2, 2, 2]],
[[3, 3, 3], [4, 4, 4]],
[[5, 5, 5], [6, 6, 6]]])
tf.slice(t, [1, 0, 0], [1, 1, 3]) # [[[3, 3, 3]]]
tf.slice(t, [1, 0, 0], [1, 2, 3]) # [[[3, 3, 3],
# [4, 4, 4]]]
tf.slice(t, [1, 0, 0], [2, 1, 3]) # [[[3, 3, 3]],
# [[5, 5, 5]]]

其中后两个参数为 begin和 size。
begin 代表开始位置(每一个维度上从第几个元素开始截取)
size 代表每一个维度从begin位置上开始截取多少个元素

简单的说:
例子:
tf.slice(t, [1, 0, 0], [1, 1, 3]) # [[[3, 3, 3]]]
中的[1, 0, 0] :
第一个1 代表从行 [[3, 3, 3], [4, 4, 4]] 开始截取。
第二个0 代表从[3, 3, 3] 开始截取
第三个0 代表从元素3 开始截取
中的[1, 1, 3] :
第一个1 代表截取一个元素即[[3, 3, 3], [4, 4, 4]]
第二个1 代表截取一个元素即[3, 3, 3]
第三个3 代表截取三个元素即3,3,3
最终结果还原原始维度为:[[[3, 3, 3]]]

例子:
tf.slice(t, [1, 0, 0], [2, 1, 3]) # [[[3, 3, 3]], [[5, 5, 5]]]
中的 [1, 0, 0]:
第一个1 代表从行 [[3, 3, 3], [4, 4, 4]] 开始截取。
第二个0 代表从[3, 3, 3] 开始截取
第三个0 代表从元素3 开始截取
中的 [2, 1, 3]:
第一个2 代表截取两个元素即
[[3, 3, 3], [4, 4, 4]],
[[5, 5, 5], [6, 6, 6]]
可以视为:
x = [3, 3, 3], [4, 4, 4]
y = [5, 5, 5], [6, 6, 6]
截取了[x,y]
第二个1代表上面的每一行(每一个元素x or y)截取一个子元素即
[[3, 3, 3]],
[[5, 5, 5]]
这里的每个单元素整体是:
x = [3, 3, 3]
y = [5, 5, 5]
第三个3 代表上面的每一个元素截取三个子元素即
3, 3, 3
5, 5, 5
最终结果还原原始维度为:
[[[3, 3, 3]],[[5, 5, 5]]]

在程序中如果没有确定的维度大小,可以用-1代表终止位置:

1
2
3
4
conv1 = slim.conv2d(input, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_1')
conv1 = slim.conv2d(conv1, 32, [3, 3], rate=1, activation_fn=lrelu, scope='g_conv1_2')
slice_1 = tf.slice(conv1, [0, 0, 0, 0], [-1, -1, -1, 16])
slice_2 = tf.slice(conv1, [0, 0, 0, 16], [-1, -1, -1, 16])

image

concat 的用法就比较简单了,但是要注意坐标的设置:

1
2
3
4
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 0) # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 1) # [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]

其中第二个参数0 代表以第1维合并,1代表第二维合并…

concat1 = tf.concat([slice_1, slice_2], axis=3)
例如上面的slice_1 与slice_2 的合并需要设置axis=3.
image

引用:
https://www.tensorflow.org/api_docs/python/tf/slice
https://www.tensorflow.org/api_docs/python/tf/concat