我的代码(高斯和make_kernel函数来自:https://github.com/keras-team/keras/issues/3720用于测试) . reshape_out 是(?,21,3) . 21 * 3个元素是21个3D位置 . 我需要投影这21个位置来生成热图,应该是(?,32,32) . 投影后,32 * 32热图中约有21个 . 我不知道如何在张量流中做到这一点 . 然后我找到sparse_to_dense函数 . 但后来我发现它不可区分 . 我正在尝试使用其他解决方案进行投影,例如scatter_nd . 到现在为止,我仍然无法使其发挥作用 . 我还尝试将this fix复制到我安装的tensorflow文件中,但程序将挂起 variables.Variable line . 我的代码:

reshape_out = Reshape((21, 3), input_shape=(21*3,), name='reshape_to_21_3')(output3d)

def proj_output_shape(shp):
    return (None, 32, 32, 1)

def gaussian(x, mu, sigma):
    # from: https://github.com/keras-team/keras/issues/3720
    return np.exp(-(float(x) - float(mu)) ** 2 / (2 * sigma ** 2))

def make_kernel(sigma):
    # from: https://github.com/keras-team/keras/issues/3720
    # kernel radius = 2*sigma, but minimum 3x3 matrix
    kernel_size = max(3, int(2 * 2 * sigma + 1))
    mean = np.floor(0.5 * kernel_size)
    kernel_1d = np.array([gaussian(x, mean, sigma) for x in range(kernel_size)])
    # make 2D kernel
    np_kernel = np.outer(kernel_1d, kernel_1d).astype(dtype=K.floatx())
    # normalize kernel by sum of elements
    kernel = np_kernel / np.sum(np_kernel)

    print('kernel={0}'.format(kernel))
    return kernel

def f(x):
    import tensorflow as tf
    print('x.shape={0}'.format(x.shape))
    idx = K.cast(x[:, :, 0:2]*15.5+15.5, "int32")
    print('idx.shape={0}'.format(idx.shape))
    z = tf.sparse_to_dense(idx, [K.shape(x)[0], 32, 32], 1.0, 0.0, name='sparse_tensor')
    z = K.reshape(z, (K.shape(x)[0], 32, 32, 1))
    fil = make_kernel(1.0)
    fil = K.reshape(fil, (5, 5, 1, 1))

    print('z.shape={0}'.format(z.shape), z)
    print('fil.shape={0}'.format(fil.shape), fil)

    r = K.conv2d(z,kernel=fil, padding='same', data_format="channels_last")
    print('r.shape={0}'.format(r.shape), r)

    return r

proj_out = Lambda(lambda x: f(x), 
                  output_shape=proj_output_shape, name='projection')(reshape_out)

输出:

x.shape=(?, 21, 3)
idx.shape=(?, 21, 2)
kernel=[[0.00296902 0.01330621 0.02193823 0.01330621 0.00296902]
 [0.01330621 0.05963429 0.09832032 0.05963429 0.01330621]
 [0.02193823 0.09832032 0.1621028  0.09832032 0.02193823]
 [0.01330621 0.05963429 0.09832032 0.05963429 0.01330621]
 [0.00296902 0.01330621 0.02193823 0.01330621 0.00296902]]
('z.shape=(?, 32, 32, 1)', <tf.Tensor 'projection_35/Reshape:0' shape=(?, 32, 32, 1) dtype=float32>)
('fil.shape=(5, 5, 1, 1)', <tf.Tensor 'projection_35/Reshape_1:0' shape=(5, 5, 1, 1) dtype=float32>)
('r.shape=(?, 32, 32, 1)', <tf.Tensor 'projection_35/convolution:0' shape=(?, 32, 32, 1) dtype=float32>)

错误:

ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.

如何解决这个问题?谢谢

UPDATE

我认为 z = tf.sparse_to_dense(idx, [K.shape(x)[0], 32, 32], 1.0, 0.0, name='sparse_tensor') 是可以返回None的操作(参考:Why is no gradient available when using sparse tensors in TensorFlow?

我换了

st = tf.SparseTensor(indices=idx, values=1, dense_shape=[K.shape(x)[0], 32, 32])
z = tf.sparse.to_dense(st)

但得到了错误 ValueError: Shape (?, 21, 2) must have rank 2

我的张量流是1.12.0

仍然坚持这个问题 . 欢迎任何帮助 . 谢谢

UPDATE

如何借助 tf.scatter_nd 做到这一点?