Tensorflow - 如何使用tf.gather()将第一层输入的一部分传递给下一层的过滤器之一

时间:2017-11-06 03:05:27

标签: python tensorflow

我们说我有这个设置:

conv1 = tf.layers.conv2d(
    inputs=input_layer,
    filters=4,
    kernel_size=[14, 14],
    padding="valid",
    activation=tf.nn.relu
    )

conv2 = tf.layers.conv2d(
    inputs=conv1,
    filters=16,
    kernel_size=[5, 5],
    padding="valid",
    activation=tf.nn.relu
    )

this paper中的部分连接方案类似,我希望在conv1中将conv2的单独数量的图层提供给一个过滤器。我是否使用tf.gather()以及如何使用?

1 个答案:

答案 0 :(得分:0)

tf.gather()仅沿一个轴创建切片,因此对于您的情况,tf.gather_nd()会更好地工作。所以应该如下:

# make a placeholder for indices of the outputs you will pick, 
# or make it constant if they won't change
indices = tf.placeholder(tf.int32,[None,4]) 

conv1 = tf.layers.conv2d(
    inputs=input_layer,
    filters=4,
    kernel_size=[14, 14],
    padding="valid",
    activation=tf.nn.relu
)

# select required outputs
new_input = tf.gather_nd(conv,indices)
# or you can hard-wire them, if they're constant
new_input = tf.gather_nd(conv, [[0,0,0,0],[1,0,0,0]])

# then you need to reshape it back a proper size 
# as previous operation will return flattened list 
# (unless you slice raws, but not single outputs). 
# Depending what size you got and what you need, but possibly something like that:
required_shape = [-1,10,10,4]
new_input = tf.reshape(new_input,required_shape) 
# or instead of the constant array feed a tensor with new shape as well

conv2 = tf.layers.conv2d(
    inputs=new_input,
    filters=16,
    kernel_size=[5, 5],
    padding="valid",
    activation=tf.nn.relu
)

如果是gather_nd,您可以沿每个轴指定数组的显式元素。官方文档中有一个很好的例子:

indices = [[1]]
params = [[['a0', 'b0'], ['c0', 'd0']],
          [['a1', 'b1'], ['c1', 'd1']]]
output = [[['a1', 'b1'], ['c1', 'd1']]]

indices = [[0, 1], [1, 0]]
params = [[['a0', 'b0'], ['c0', 'd0']],
          [['a1', 'b1'], ['c1', 'd1']]]
output = [['c0', 'd0'], ['a1', 'b1']]

indices = [[0, 0, 1], [1, 0, 1]]
params = [[['a0', 'b0'], ['c0', 'd0']],
          [['a1', 'b1'], ['c1', 'd1']]]
output = ['b0', 'b1']