如何在张量流中制作棋盘矩阵?

时间:2018-04-05 15:15:17

标签: tensorflow neural-network deep-learning

我需要初始化一个棋盘矩阵以合并我的张量流图中的两个特征图,我能够使用像这样的TF旁边的numpy来做一个已知的形状

def checkerboard_concat(x1, x2):

    mask1 = np.ones((10,10,3))
    mask1[1::2,::2] = 0
    mask1[::2,1::2] = 0

    mask2 = np.zeros((10,10,3))
    mask2[1::2,::2] = 1
    mask2[::2,1::2] = 1

    return x1 * mask1 + x2 * mask2

但我无法使用动态形状执行此操作,我使用tf.shape()返回形状(N,)的输出,但我不知道如何动态评估它。

另外,我尝试使用tf.ones_like(x1),但无法使用下标将其更改为numpy数组

1 个答案:

答案 0 :(得分:2)

以下是基于模运算和异或运算的解决方案:

import tensorflow as tf

def make_checkerboard(N):
    """
    Return a NxN checkerboard matrix M, i.e. with M(i,j) == True if (i+j) mod 2 == 1
    :param N:   Length of the checkerboard (can be dynamic)
    :return:    Boolean tensor of shape NxN
    """
    range_n = tf.range(N)
    odd_ind = tf.cast(tf.mod(range_n, 2), dtype=tf.bool)

    odd_rows = tf.tile(tf.expand_dims(odd_ind , -1), [1, N])
    odd_cols = tf.tile(tf.expand_dims(odd_ind ,  0), [N, 1])

    checker = tf.logical_xor(odd_rows, odd_cols)
    return checker

def checkerboard_concat(x1, x2, is_batch=True):

    dynamic_n = tf.shape(x1)[1 if is_batch else 0]
    mask2 = make_checkerboard(dynamic_n)
    mask2 = tf.expand_dims(mask2, -1)   # Expand masks to cover channels
    mask1 = tf.logical_not(mask2)

    return x1 * tf.cast(mask1, dtype=x1.dtype) + x2 * tf.cast(mask2, dtype=x2.dtype)


# Example:
tf.reset_default_graph()
sess = tf.InteractiveSession()

x1 = tf.ones((4,4,3), dtype=tf.int32)
x2 = tf.ones((4,4,3), dtype=tf.int32) * 2

x = checkerboard_concat(x1, x2, is_batch=False)
res = sess.run(x)
print(res[...,0])
# [[1 2 1 2]
#  [2 1 2 1]
#  [1 2 1 2]
#  [2 1 2 1]]