我的代码(高斯和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
做到这一点?