web-dev-qa-db-ja.com

ケラスにConv1DTransposeを実装する方法?

画像で使用できるケラスのConv2DTransposeがあることを知っています。 NLPで使用する必要があるため、1Dデコンボリューションが必要です。

どのようにしてケラスにConv1DTransposeを実装しますか?

25
Huo

Kerasバックエンドを使用して、入力テンソルを2D転置たたみ込みに適合させます。多くの時間を消費するため、転置操作は常に使用しないでください。

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


def Conv1DTranspose(input_tensor, filters, kernel_size, strides=2, padding='same'):
    """
        input_tensor: tensor, with the shape (batch_size, time_steps, dims)
        filters: int, output dimension, i.e. the output tensor will have the shape of (batch_size, time_steps, filters)
        kernel_size: int, size of the convolution kernel
        strides: int, convolution step size
        padding: 'same' | 'valid'
    """
    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
13
Dingkun Liu

私の回答では、畳み込みに以前Conv1Dを使用していたと思います。

Conv2DTransposeはKeras2の新機能で、以前はUpSampling2Dとコンボリューションレイヤーの組み合わせによって行われていました。 StackExchange [Data Science]では、 デコンボリューションレイヤーとは何かについて非常に興味深い議論があります (1つの答えには、非常に便利なアニメーションGIFが含まれています)。

についてのこのディスカッションを確認してください "KerasでのAutoencodersの構築 のすべてのたたみ込み(デコンボリューションなし)が興味深い理由。ここに抜粋があります:" Francois is multipleすでに、デコンボリューションレイヤーは、アップサンプリングを備えたコンボリューションレイヤーにすぎません。公式のデコンボリューションレイヤーはないと思います。結果は同じです。」(議論は続いていますが、それらはほぼ同じであり、完全に同じではないかもしれません-それ以来、Keras 2はConv2DTransposeを導入しました)

私が理解しているように、 UpSampling1DConvolution1D の組み合わせはあなたが探しているもの、私は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"
    )
)

Conv2DTransposeを使用するための不便な部分は、seq_lengthを指定する必要があり、None(任意の長さシリーズ)として指定できないことです。残念ながら、TensorFlowバックエンドのUpSampling1Dでも同じです(Theanoはここでもまた優れているようです-あまりにも悪い周りにいるつもりはない)

6
ntg

追加の次元を占めるように形状を変更し、デコンボリューションを実行してから、形状を元に戻すことができます。実際には、これは機能します。しかし、それが理論的な意味を持っている場合、私はそれほど強く考えていませんでした(しかし、あなたがその次元で「畳み込む」つもりはないので、理論的には問題がないようです。

x = Reshape( ( -1, 1 ) )( x )
x = Permute( ( 3, 1, 2 ) )( x )
x = Conv2DTranspose( filters, kernel )( x )
x = Lambda( K.squeeze, arguments={"axis":1} )( x )
0
arch3r