在 keras 的 LSTM 模型中解释 get_weight

interpreting get_weight in LSTM model in keras

这是我的简单可重现代码:

from keras.callbacks import ModelCheckpoint
from keras.models import Model
from keras.models import load_model
import keras
import numpy as np

SEQUENCE_LEN = 45
LATENT_SIZE = 20
VOCAB_SIZE = 100

inputs = keras.layers.Input(shape=(SEQUENCE_LEN, VOCAB_SIZE), name="input")
encoded = keras.layers.Bidirectional(keras.layers.LSTM(LATENT_SIZE), merge_mode="sum", name="encoder_lstm")(inputs)
decoded = keras.layers.RepeatVector(SEQUENCE_LEN, name="repeater")(encoded)
decoded = keras.layers.Bidirectional(keras.layers.LSTM(VOCAB_SIZE, return_sequences=True), merge_mode="sum", name="decoder_lstm")(decoded)
autoencoder = keras.models.Model(inputs, decoded)
autoencoder.compile(optimizer="sgd", loss='mse')
autoencoder.summary()

x = np.random.randint(0, 90, size=(10, SEQUENCE_LEN,VOCAB_SIZE))
y = np.random.normal(size=(10, SEQUENCE_LEN, VOCAB_SIZE))
NUM_EPOCHS = 1
checkpoint = ModelCheckpoint(filepath='checkpoint/{epoch}.hdf5')
history = autoencoder.fit(x, y, epochs=NUM_EPOCHS,callbacks=[checkpoint])

这是我的代码,用于查看编码器层中的权重:

for epoch in range(1, NUM_EPOCHS + 1):
    file_name = "checkpoint/" + str(epoch) + ".hdf5"
    lstm_autoencoder = load_model(file_name)
    encoder = Model(lstm_autoencoder.input, lstm_autoencoder.get_layer('encoder_lstm').output)
    print(encoder.output_shape[1])
    weights = encoder.get_weights()[0]
    print(weights.shape)
    for idx in range(encoder.output_shape[1]):
        token_idx = np.argsort(weights[:, idx])[::-1]

这里 print(encoder.output_shape)(None,20)print(weights.shape)(100, 80).

我明白get_weight会在层后打印重量过渡。

我没有根据这个架构得到的部分是80。这是什么?

还有,这里的weights是连接编码层和解码层的权重吗?我的意思是编码器和解码器之间的连接。

我看过这个问题。因为它只是简单的密集层,所以我无法将这个概念连接到 seq2seq 模型。

更新1

有什么区别: encoder.get_weights()[0]encoder.get_weights()[1]? 第一个是 (100,80) 第二个是 (20,80) 概念上的?

感谢任何帮助:)

您定义的encoder是一个模型,它由两层组成:输入层和'encoder_lstm'层,即自动编码器中的双向LSTM层。所以它的输出形状将是 'encoder_lstm' 层的输出形状,即 (None, 20) (因为你已经设置了 LATENT_SIZE = 20merge_mode="sum")。所以输出形状正确清晰。

但是,由于 encoder 是一个模型,当您 运行 encoder.get_weights() 时,它将 return 模型中所有层的权重作为一个列表。双向 LSTM 由两个独立的 LSTM 层组成。每个 LSTM 层都有 3 个权重:内核、循环内核和偏差。所以 encoder.get_weights() 会 return 一个包含 6 个数组的列表,每个 LSTM 层 3 个。此列表的第一个元素,正如您存储在 weights 中并且是您的问题的主题,是其中一个 LSTM 层的内核。 LSTM 层的内核具有 (input_dim, 4 * lstm_units) 的形状。 'encoder_lstm'层的输入维度为VOCAB_SIZE,其单元数为LATENT_SIZE。因此,我们有 (VOCAB_SIZE, 4 * LATENT_SIZE) = (100, 80) 作为内核的形状。