web-dev-qa-db-fra.com

Comment implémenter Conv1DTranspose dans keras?

Je sais qu'il existe le Conv2DTranspose dans keras qui peut être utilisé dans Image. Nous devons l’utiliser dans la PNL, la déconvolution 1D est donc nécessaire. 

Comment implémentons-nous Conv1DTranspose dans keras?

21
Huo

Utilisez keras backend pour adapter le tenseur d’entrée à la convolution de transposition 2D. N'utilisez pas toujours l'opération de transposition car cela prendrait beaucoup de temps.

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
5
Dingkun Liu

Dans ma réponse, je suppose que vous utilisez précédemment Conv1D pour la convolution.

Conv2DTranspose est une nouveauté de Keras2. Auparavant, il utilisait une combinaison de UpSampling2D et d’une couche de convolution. Dans StackExchange [Data Science], il existe une discussion très intéressante sur quelles sont les couches déconvolutionnelles (une réponse inclut des gifs animés très utiles). 

Vérifiez cette discussion à propos de "Pourquoi toutes les convolutions (pas de déconvolutions) dans" Construire des auto-encodeurs à Keras " intéressant. Voici un extrait:" Comme François l'a déjà expliqué à plusieurs reprises, une couche de déconvolution n'est qu'une couche de convolution avec un échantillonnage croissant . Je ne pense pas qu'il existe une couche officielle de déconvolution. Le résultat est le même. "(La discussion se poursuit, il se peut qu’ils soient approximativement, pas exactement les mêmes - également, depuis lors, Keras 2 a introduit Conv2DTranspose)

Si je comprends bien, une combinaison de UpSampling1D et ensuite Convolution1D est ce que vous recherchez, je ne vois aucune raison de passer en 2D.

Si vous souhaitez toutefois utiliser Conv2DTranspose, vous devez d’abord remodeler l’entrée de 1D à 2D, par exemple.

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"
    )
)

La partie gênante pour utiliser Conv2DTranspose est que vous devez spécifier seq_length et que vous ne pouvez pas l’indiquer sous la forme Aucune (série de longueur arbitraire). dommage que ça ne soit pas là)

2
ntg

Vous pouvez le remodeler pour qu'il occupe une dimension supplémentaire, exécuter la déconvolution, puis le remodeler. En pratique, cela fonctionne. Mais je n’ai pas vraiment réfléchi très sérieusement si cela n’avait aucune implication théorique (mais cela semble théoriquement tout aussi bien, car vous n’allez pas "convolver" sur cette dimension.

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