这是我简单的可复制代码:
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)
?
任何帮助,我们感激不尽:)
答案 0 :(得分:1)
您所定义的encoder
是一个模型,它由两层组成:输入层和'encoder_lstm'
层,它是自动编码器中的双向LSTM层。因此,其输出形状将是'encoder_lstm'
的{{1}}层的输出形状(因为您已经设置了(None, 20)
和LATENT_SIZE = 20
)。因此输出形状正确且清晰。
但是,由于merge_mode="sum"
是模型,因此当您运行encoder
时,它将以列表形式返回模型中所有图层的权重。双向LSTM由两个单独的LSTM层组成。这些LSTM层中的每一层都有3个权重:核,递归核和偏差。因此encoder.get_weights()
将返回6个数组的列表,每个LSTM层3个。正如您存储在encoder.get_weights()
中一样,此列表的第一个元素是LSTM层之一的内核。 LSTM层的内核的形状为weights
。 (input_dim, 4 * lstm_units)
层的输入维为'encoder_lstm'
,其单位数为VOCAB_SIZE
。因此,我们将LATENT_SIZE
作为内核的形状。