【问题标题】:interpreting get_weight in LSTM model in keras在 keras 中解释 LSTM 模型中的 get_weight
【发布时间】:2019-07-12 18:48:03
【问题描述】:

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

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 是连接编码器层和解码器的权重吗?我的意思是编码器和解码器之间的连接。

我看过这个问题here。因为它只是简单的密集层,我无法将这个概念与 seq2seq 模型联系起来。

更新1

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

感谢任何帮助:)

【问题讨论】:

    标签: python tensorflow keras lstm seq2seq


    【解决方案1】:

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

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

    【讨论】:

    • 非常感谢您的详细解释。对此我还有一个问题,希望您能帮我澄清一下。所以你提到我们有3个权重。我需要查看与latent size 中的20 neurons 相关的权重。根据您的解释,我认为我做的不对,我应该看看encoder.get_weights()[1]。我说的对吗?
    • @sariii 我不确定您所说的“与这 20 个神经元相关的重量”是什么意思?!所有这些权重都与神经元相关。实际上,内核由四个形状为(input_dim, lstm_units) 的子内核组成,每个子内核都有一个用途。同样的细化适用于循环内核:四个形状为(lstm_units, lstm_units) 的子内核,使其具有(lstm_units, 4* lstm_units) 的形状。所以我不确定你对其中哪一个感兴趣。每个都有不同的目的,但都与 LSTM 层中的神经元有关。
    • 非常感谢,非常感谢,现在我更清楚了。我已经用另一个与您在评论中的解释完全相关的问题更新了这个问题。你能看看并更新你的答案吗?另外,如果您能提供我可以阅读的链接以了解它们之间的差异,我将不胜感激。现在唯一模糊的部分是他们真正的区别。
    • @sariii 重新阅读您的评论,我认为您对内核权重(即.get_weights()[0] 返回的权重)感兴趣,因为实际上这些权重与 LSTM 神经元直接相关.循环内核处理隐藏状态。 This image 可能对您有所帮助:Ws 是内核,Us 是循环内核。另请参阅 Keras 源代码中的relevant part
    • @sariii 啊,所以你只是想找到子内核?!我已经与您分享了 cmets 中 Keras 源代码的链接,我认为您已经查看了它以找到哪个切片对应于哪个子内核!不管怎样,我很高兴你终于可以找到你问题的答案:)
    猜你喜欢
    • 2020-05-25
    • 2019-05-09
    • 2017-08-09
    • 2018-10-02
    • 1970-01-01
    • 2019-04-15
    • 2021-09-30
    • 1970-01-01
    • 2018-11-27
    相关资源
    最近更新 更多