在 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 = 20
和 merge_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)
作为内核的形状。
这是我的简单可重现代码:
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
是连接编码层和解码层的权重吗?我的意思是编码器和解码器之间的连接。
我看过这个问题
更新1
有什么区别:
encoder.get_weights()[0]
和 encoder.get_weights()[1]
?
第一个是 (100,80)
第二个是 (20,80)
概念上的?
感谢任何帮助:)
您定义的encoder
是一个模型,它由两层组成:输入层和'encoder_lstm'
层,即自动编码器中的双向LSTM层。所以它的输出形状将是 'encoder_lstm'
层的输出形状,即 (None, 20)
(因为你已经设置了 LATENT_SIZE = 20
和 merge_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)
作为内核的形状。