Я знаю, что в keras есть Conv2DTranspose, который можно использовать в Image. Нам нужно использовать его в НЛП, поэтому необходима одномерная деконволюция.
Как реализовать Conv1DTranspose в keras?
Я знаю, что в keras есть Conv2DTranspose, который можно использовать в Image. Нам нужно использовать его в НЛП, поэтому необходима одномерная деконволюция.
Как реализовать Conv1DTranspose в keras?
Используйте серверную часть 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
В моем ответе я предполагаю, что вы ранее использовали Conv1D для свертки.
Conv2DTranspose является новым в Keras2, раньше то, что он делает, выполнялось комбинацией UpSampling2D и слоя свертки. В StackExchange[Data Science] есть очень интересное обсуждение что такое слои деконволюции ( один ответ включает в себя очень полезные анимированные GIF-файлы).
Проверьте это обсуждение о "Почему все свертки (без деконволюций) в "Создание автоэнкодеров в 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"
)
)
Неудобная часть использования Conv2DTranspose заключается в том, что вам нужно указать seq_length и не может иметь значение None (серия произвольной длины). рядом не будет)
В TensorFlow v2.2.0 слой Conv1DTranspose реализован в API tf.keras.layers. Проверьте!
Вы можете изменить его форму, чтобы занять дополнительное измерение, запустить деконволюцию, а затем изменить форму обратно. На практике это работает. Но я на самом деле не особо задумывался, имеет ли это какие-либо теоретические последствия (но, кажется, теоретически это также хорошо, поскольку вы не собираетесь «сворачиваться» над этим измерением
x = Reshape( ( -1, 1 ) )( x )
x = Permute( ( 3, 1, 2 ) )( x )
x = Conv2DTranspose( filters, kernel )( x )
x = Lambda( K.squeeze, arguments={"axis":1} )( x )