使用预先训练的嵌入层的Keras自动编码器返回的维数不正确

2024-04-19 13:30:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直试图复制一个基于an example from the Deep Learning with Keras book的句子自动编码器。在

我重新编写了这个示例,使用嵌入层而不是句子生成器,并使用fitvs.fit_generator。在

我的代码如下:

df_train_text = df['string']

max_length = 80
embedding_dim = 300
latent_dim = 512
batch_size = 64
num_epochs = 10

# prepare tokenizer
t = Tokenizer(filters='')
t.fit_on_texts(df_train_text)
word_index = t.word_index
vocab_size = len(t.word_index) + 1

# integer encode the documents
encoded_train_text = t.texts_to_matrix(df_train_text)

padded_train_text = pad_sequences(encoded_train_text, maxlen=max_length, padding='post')

padding_train_text = np.asarray(padded_train_text, dtype='int32')

embeddings_index = {}
f = open('/Users/embedding_file.txt')
for line in f:
    values = line.split()
    word = values[0]
    coefs = np.asarray(values[1:], dtype='float32')
    embeddings_index[word] = coefs
f.close()

print('Found %s word vectors.' % len(embeddings_index))
#Found 51328 word vectors.

embedding_matrix = np.zeros((vocab_size, embedding_dim))
for word, i in word_index.items():
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
        # words not found in embedding index will be all-zeros.
        embedding_matrix[i] = embedding_vector


embedding_layer = Embedding(vocab_size,
                            embedding_dim,
                            weights=[embedding_matrix],
                            input_length=max_length,
                            trainable=False)
inputs = Input(shape=(max_length,), name="input")
embedding_layer = embedding_layer(inputs)
encoder = Bidirectional(LSTM(latent_dim), name="encoder_lstm", merge_mode="sum")(embedding_layer)
decoder = RepeatVector(max_length)(encoder)
decoder = Bidirectional(LSTM(embedding_dim, name='decoder_lstm', return_sequences=True), merge_mode="sum")(decoder)
autoencoder = Model(inputs, decoder)
autoencoder.compile(optimizer="adam", loss="mse")


autoencoder.fit(padded_train_text, padded_train_text,
                epochs=num_epochs, 
                batch_size=batch_size,
                callbacks=[checkpoint])

我验证了我的图层形状与示例中的相同,但是当我尝试匹配我的自动编码器时,我得到了以下错误:

^{pr2}$

我尝试过的其他一些事情包括将texts_to_matrix切换为texts_to_sequence以及包装/不包装填充字符串

我还遇到了this post,这似乎表明我走错了方向。有没有可能像我编码的那样,把自动编码器和嵌入层配合起来?如果没有,有人能帮我解释一下这个例子和我的版本之间的根本区别吗?在

编辑:我删除了最后一层中的return_sequences=True参数,得到了以下错误:ValueError: Error when checking target: expected bidirectional_1 to have shape (300,) but got array with shape (80,)

更新图层后,形状为:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input (InputLayer)           (None, 80)                0         
_________________________________________________________________
embedding_8 (Embedding)      (None, 80, 300)           2440200   
_________________________________________________________________
encoder_lstm (Bidirectional) (None, 512)               3330048   
_________________________________________________________________
repeat_vector_8 (RepeatVecto (None, 80, 512)           0         
_________________________________________________________________
bidirectional_8 (Bidirection (None, 300)               1951200   
=================================================================
Total params: 7,721,448
Trainable params: 5,281,248
Non-trainable params: 2,440,200
_________________________________________________________________

我是否遗漏了RepeatVector层和模型最后一层之间的一个步骤,这样我就可以返回(None,80300)的形状,而不是它当前生成的(None,300)形状?在


Tags: totextnonedfsizeindextrainembedding
1条回答
网友
1楼 · 发布于 2024-04-19 13:30:03

Embedding层以形状为(num_words,)的整数序列(即单词索引)作为输入,并以(num_words, embd_dim)的形状给出相应的嵌入作为输出。因此,在将Tokenizer实例拟合到给定文本之后,需要使用其texts_to_sequences()方法将每个文本转换为一系列整数:

encoded_train_text = t.texts_to_sequences(df_train_text)

此外,由于填充encoded_train_text之后,它将具有(num_samples, max_length)的形状,网络的输出形状也必须具有相同的形状(即,因为我们正在创建一个自动编码器),因此您需要删除最后一层的return_sequences=True参数。否则,它会给我们一个三维张量作为输出,这是没有意义的。在

作为补充说明,以下行是多余的,因为padded_train_text已经是一个numpy数组(顺便说一下,您根本没有使用padding_train_text):

^{pr2}$

相关问题 更多 >