【问题标题】:autocorrelation of the input in tensorflow/kerastensorflow/keras 中输入的自相关
【发布时间】:2018-02-05 18:31:29
【问题描述】:

我有一个一维输入信号。我想计算自相关作为神经网络的一部分,以便在网络内部进一步使用。 我需要将输入与输入本身进行卷积。 在 keras 自定义层/张量流中执行卷积。我们需要以下参数 data shape is "[batch, in_height, in_width, in_channels]", filter shape is "[filter_height, filter_width, in_channels, out_channels]

过滤器形状中没有批次,在我的情况下需要输入

【问题讨论】:

  • 你有多少个in_channels?
  • 有2个频道。
  • 而且这些通道不应该在卷积中混合,对吧?
  • 是的,每个通道都需要独立。我还可以修改我的代码以使通道数为 1。这很容易完成
  • 我在想办法,但这不是小事。

标签: tensorflow keras batch-processing convolution


【解决方案1】:

TensorFlow 现在有一个auto_correlation 函数。它应该在版本1.6 中。如果您从源代码构建,您可以立即使用它(参见例如the github code)。

【讨论】:

    【解决方案2】:

    这是一个可能的解决方案。

    通过自卷积,我理解了一个常规卷积,其中过滤器与输入完全相同(如果不是这样,请原谅我的误解)。

    为此我们需要一个自定义函数,以及一个Lambda 层。

    起初我使用padding = 'same',它使输出的长度与输入的长度相同。我不确定你到底想要什么输出长度,但如果你想要更多,你应该在进行卷积之前自己添加填充。 (在长度为 7 的示例中,对于从一端到另一端的完整卷积,此手动填充将包括输入长度之前的 6 个零和之后的 6 个零,并使用padding = 'valid'。找到backend functions here

    工作示例 - 输入 (5,7,2)

    from keras.models import Model
    from keras.layers import *
    import keras.backend as K
    
    batch_size = 5
    length = 7
    channels = 2
    channels_batch = batch_size*channels
    
    def selfConv1D(x):
        #this function unfortunately needs to know previously the shapes
        #mainly because of the for loop, for other lines, there are workarounds
        #but these workarounds are not necessary since we'll have this limitation anyway
    
        #original x: (batch_size, length, channels)
    
        #bring channels to the batch position:
        x = K.permute_dimensions(x,[2,0,1]) #(channels, batch_size, length)
    
        #suppose channels are just individual samples (since we don't mix channels)
        x = K.reshape(x,(channels_batch,length,1))
    
        #here, we get a copy of x reshaped to match filter shapes:
        filters = K.permute_dimensions(x,[1,2,0])  #(length, 1, channels_batch)
    
        #now, in the lack of a suitable available conv function, we make a loop
        allChannels = []
        for i in range (channels_batch):
    
            f = filters[:,:,i:i+1]
            allChannels.append(
                K.conv1d(
                    x[i:i+1], 
                    f, 
                    padding='same', 
                    data_format='channels_last'))
                        #although channels_last is my default config, I found this bug: 
                        #https://github.com/fchollet/keras/issues/8183
    
            #convolution output: (1, length, 1)
    
        #concatenate all results as samples
        x = K.concatenate(allChannels, axis=0) #(channels_batch,length,1)
    
        #restore the original form (passing channels to the end)
        x = K.reshape(x,(channels,batch_size,length))
        return K.permute_dimensions(x,[1,2,0]) #(batch_size, length, channels)
    
    
    #input data for the test:
    x = np.array(range(70)).reshape((5,7,2))
    
    #little model that just performs the convolution
    inp= Input((7,2))
    out = Lambda(selfConv1D)(inp)
    
    model = Model(inp,out)
    
    #checking results
    p = model.predict(x)
    for i in range(5):
        print("x",x[i])
        print("p",p[i])
    

    【讨论】:

    • 完成了与您的实现类似的事情,但使用了 keras 自定义层。那么现在有办法逃避批量大小的预初始化吗?
    • 我不知道如何避免它。但这仅仅是因为“for”循环。我们不能迭代张量。但也许我们可以在循环中使用K.eval(K.shape(x))[0]。在这种情况下,我们可以在使用批量大小的其他行中应用一些解决方法......
    【解决方案3】:

    您可以通过将“批量大小”视为“深度”来使用 tf.nn.conv3d:

    # treat the batch size as depth.
    data = tf.reshape(input_data, [1, batch, in_height, in_width, in_channels])
    kernel = [filter_depth, filter_height, filter_width, in_channels, out_channels]
    out = tf.nn.conv3d(data, kernel, [1,1,1,1,1], padding='SAME')
    

    【讨论】:

    • 我认为使用它会使沿深度轴的值混合对吗?
    • 对。这不是你想要的吗?你能举一些例子来说明你需要什么吗?
    • 让我们处理一批 16 个双变量时间序列,每个时间步长为 100 个。我需要每个变量的自相关。 (16,100,2) 将输入大小。我只需要将时间序列与自身沿轴 = 1 进行卷积,即上例中的 100。输出类似于 (16,?,2)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2021-12-26
    • 2018-08-23
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多