相当于keras后端的np.convolve

Equivalent of np.convolve in keras backend

我有以下功能

def pad_ones(arr):
    return np.convolve(arr, [1, 1, 1], "same") 

# for example:
# >>> pad_ones([0, 0, 0, 1, 0, 0])
# array([0, 0, 1, 1, 1, 0])

我想用它来处理 one_hot 编码数组。这目前在 tensorflow 中引发错误:

NotImplementedError: Cannot convert a symbolic Tensor to a numpy array. This error may indicate that you're trying to pass a Tensor to a NumPy call, which is not supported

所以我尝试使用 keras.backend 来实现它,但找不到合适的解决方案。 np.convolve 的 keras 后端等效项是什么?我发现有文章指出 keras 卷积与 np.correlate 相同,但我没有找到任何文章解释 np.convolve 在 keras.backend.

中的等价物

我试过像这样使用 K.conv1d:

K.conv1d(K.constant([0, 0, 1, 0, 0, 0]), K.constant([1, 1, 1]), "same")

但是我得到以下错误:

ValueError: "num_spatial_dims" must be 1, 2, or 3. Received: num_spatial_dims=-1.

最终解决方案(特别感谢@AloneTogether):

def keras_pad_ones(one_hot_2d_matrix):
    kernel = K.constant([1, 1, 1], shape=(3, 1, 1))
    x = K.expand_dims(one_hot_2d_matrix)
    x = K.conv1d(x, kernel, padding='same')
    x = K.squeeze(x, axis=-1)
    return x

# Example:
# >>> arr_1d = K.constant([0, 0, 0, 1, 0, 0])
# >>> keras_pad_ones(K.expand_dims(arr_1d, axis=0))
# output: [[0., 0., 1., 1., 1., 0.]]

# >>> arr_2d = K.constant([[0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0]])
# >>> keras_pad_ones(arr_2d)
# output: [[0., 0., 1., 1., 1., 0.], [1., 1., 0., 0., 0., 0.]]

使用 Tensorflow 复制 np.convolve 的简单方法是使用 tf.nn.conv1d:

import tensorflow as tf

original = tf.constant([0, 0, 0, 1, 0, 0], dtype=tf.float32)
x = tf.reshape(original, (1, tf.shape(original)[0],  1))
kernel = tf.constant([1, 1, 1], dtype=tf.float32)
kernel = tf.reshape(kernel, [tf.shape(kernel)[0], 1, 1])

x = tf.nn.conv1d(x, kernel, padding='SAME', stride=1)
x = tf.reshape(x, (tf.shape(x)[1]))

print(original)
print(x)
tf.Tensor([0. 0. 0. 1. 0. 0.], shape=(6,), dtype=float32)
tf.Tensor([0. 0. 1. 1. 1. 0.], shape=(6,), dtype=float32)

或像这样 tf.keras.backend.conv1d

x = tf.keras.backend.conv1d(x, kernel, padding='same', strides=1)

其余代码保持不变。