如何在 TensorFlow 中用一维内核卷积信号?

我正在尝试过滤形状为 TensorFlow 张量(N_batch, N_data),其中N_batch是批量大小(例如 32),N_data是(嘈杂的)时间序列数组的大小。我有一个高斯核(取自这里),它是一维的。然后我想tensorflow.nn.conv1d用我的信号来卷积这个内核。


我早上大部分时间都在努力使输入信号和内核的维度正确,但显然没有成功。从我从互联网上收集的信息来看,输入信号和内核的维度都需要以某种挑剔的方式对齐,而我就是不知道是哪种方式。TensorFlow 错误消息也不是特别有意义 ( Shape must be rank 4 but is rank 3 for 'conv1d/Conv2D' (op: 'Conv2D') with input shapes: [?,1,1000], [1,81])。下面我包含了一小段代码来重现这种情况:


import tensorflow as tf

import numpy as np

import matplotlib.pyplot as plt


# Based on: https://stackoverflow.com/a/52012658/1510542

# Credits to @zephyrus



def gaussian_kernel(size, mean, std):

    d = tf.distributions.Normal(tf.cast(mean, tf.float32), tf.cast(std, tf.float32))

    vals = d.prob(tf.range(start=-size, limit=size+1, dtype=tf.float32))


    kernel = vals   # Some reshaping is required here


    return kernel / tf.reduce_sum(kernel)



def gaussian_filter(input, sigma):

    size = int(4*sigma + 0.5)


    x = input   # Some reshaping is required here


    kernel = gaussian_kernel(size=size, mean=0.0, std=sigma)

    conv = tf.nn.conv1d(x, kernel, stride=1, padding="SAME")

    return conv



def run_filter():


    tf.reset_default_graph()


    # Define size of data, batch sizes

    N_batch = 32

    N_data = 1000


    noise = 0.2 * (np.random.rand(N_batch, N_data) - 0.5)

    x = np.linspace(0, 2*np.pi, N_data)

    y = np.tile(np.sin(x), N_batch).reshape(N_batch, N_data)

    y_noisy = y + noise


    input = tf.placeholder(tf.float32, shape=[None, N_data])

    smooth_input = gaussian_filter(input, sigma=10)


    with tf.Session() as sess:

        sess.run(tf.global_variables_initializer())

        y_smooth = smooth_input.eval(feed_dict={input: y_noisy})


        plt.plot(y_noisy[0])

        plt.plot(y_smooth[0])

        plt.show()



if __name__ == "__main__":

    run_filter()

有任何想法吗?


郎朗坤
浏览 227回答 1
1回答

繁星coding

您需要为输入/内核添加通道维度,因为 TF 卷积通常用于多通道输入/输出。当您使用简单的 1 通道输入/输出时,这相当于添加一些大小为 1 的“虚拟”轴。由于默认情况下卷积期望通道最后出现,因此您的占位符应具有形状,[None,  N_data, 1]并且您的输入应修改为y_noisy = y + noisey_noisy = y_noisy[:, :, np.newaxis] 同样,您需要向过滤器添加输入和输出通道维度:kernel = gaussian_kernel(size=size, mean=0.0, std=sigma)kernel = kernel[:, tf.newaxis, tf.newaxis]也就是说,过滤器应具有 shape [width, in_channels, out_cannels]。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python