如何在keras中实现Conv1DTranspose?

Huo*_*Huo 24 keras keras-layer

我知道在keras中有Conv2DTranspose可用于Image.我们需要在NLP中使用它,因此需要一维反卷积.

我们如何在keras中实现Conv1DTranspose?

Din*_*Liu 10

使用keras后端使输入张量适合2D转置卷积.不要总是使用转置操作,因为它会耗费大量时间.

import keras.backend as K
from keras.layers import Conv2DTranspose


def Conv1DTranspose(input_tensor, filters, kernel_size, strides=2, padding='same'):
    x = Lambda(lambda x: K.expand_dims(x, axis=2))(input_tensor)
    x = Conv2DTranspose(filters=filters, kernel_size=(kernel_size, 1), strides=(strides, 1), padding=padding)(x)
    x = Lambda(lambda x: K.squeeze(x, axis=2))(x)
    return x
Run Code Online (Sandbox Code Playgroud)

  • **来自评论**:虽然总是很感激答案,但提供有关您的代码如何解决手头问题的一些信息确实很有帮助.并非每个人都熟悉您的确切编码逻辑,但可能了解您的一般*方法*或*概念*.为了帮助改进您的答案,请提供一些[**上下文**](https://meta.stackexchange.com/questions/114762),并查看有关[**写好答案**]的帮助文章( http://stackoverflow.com/help/how-to-answer)有关如何使您的答案计数的一些提示:) (6认同)

ntg*_*ntg 5

在我的回答中,我想您以前正在使用Conv1D进行卷积。

Conv2DTranspose是Keras2中的新功能,它过去是通过UpSampling2D和卷积层的组合来完成的。在StackExchange [Data Science]中,关于反卷积层有一个非常有趣的讨论(一个答案包括非常有用的动画gif)。

请查看有关“为什么在Keras中构建自动编码器中的所有卷积(不进行反卷积)”的讨论。以下摘录:“正如Francois多次解释的那样,反卷积层只是一个上采样的卷积层。我认为没有官方的反卷积层。结果是相同的。”(继续讨论,可能是它们近似而不是完全相同-而且,从那时起,Keras 2引入了Conv2DTranspose)

以我的理解,您正在寻找UpSampling1D然后是Convolution1D的组合,我认为没有理由选择2D。

但是,如果要使用Conv2DTranspose,则需要首先将输入从1D整形为2D,例如

model = Sequential()
model.add(
    Conv1D(
        filters = 3, 
        kernel_size = kernel_size, 
        input_shape=(seq_length, M),#When using this layer as the first layer in a model, provide an input_shape argument 
    )
)
model.add(
    Reshape( ( -1, 1, M) )
)
model.add(
    keras.layers.Conv2DTranspose(
        filters=M,
        kernel_size=(10,1),
        data_format="channels_last"
    )
)
Run Code Online (Sandbox Code Playgroud)

使用Conv2DTranspose的不便之处在于您需要指定seq_length且不能将其设置为None(任意长度系列)不幸的是,对于TensorFlow后端,UpSampling1D也是如此(Theano似乎再一次更好-太糟糕了不会在附近)


小智 0

您可以将其重塑以占据额外的维度,运行反卷积,然后将其重塑回来。在实践中,这是有效的。但我并没有真正认真思考它是否有任何理论意义(但理论上似乎也很好,因为你不会在这个维度上“卷积”)

x = Reshape( ( -1, 1 ) )( x )
x = Permute( ( 3, 1, 2 ) )( x )
x = Conv2DTranspose( filters, kernel )( x )
x = Lambda( K.squeeze, arguments={"axis":1} )( x )
Run Code Online (Sandbox Code Playgroud)