我关注Keras Seq2Seq tutorial,机智正常。但是,这是一个字符级模型,我想将它用于单词级模型。作者甚至包括一个需要更改的段落,但我当前的所有尝试都会导致有关拧紧尺寸的错误。
如果您遵循字符级模型,则输入数据为3个dims:#sequences
,#max_seq_len
,#num_char
,因为每个字符都是单热编码的。当我绘制教程中使用的模型摘要时,我得到:
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) (None, None, 71) 0
_____________________________________________________________________________ __________________
input_2 (InputLayer) (None, None, 94) 0
__________________________________________________________________________________________________
lstm_1 (LSTM) [(None, 256), (None, 335872 input_1[0][0]
__________________________________________________________________________________________________
lstm_2 (LSTM) [(None, None, 256), 359424 input_2[0][0]
lstm_1[0][1]
lstm_1[0][2]
__________________________________________________________________________________________________
dense_1 (Dense) (None, None, 94) 24158 lstm_2[0][0]
==================================================================================================
编译和训练就好了。
现在本教程的“如果我想使用带有整数序列的单词级模型怎么办?”我试图跟随这些变化。首先,我使用单词索引编码所有序列。因此,输入和目标数据现在是2个dims:#sequences
,#max_seq_len
,因为我不再是单热编码,而是现在使用嵌入层。
encoder_input_data_train.shape => (90000, 9)
decoder_input_data_train.shape => (90000, 16)
decoder_target_data_train.shape => (90000, 16)
例如,序列可能如下所示:
[ 826. 288. 2961. 3127. 1260. 2108. 0. 0. 0.]
当我使用列出的代码时:
# encoder
encoder_inputs = Input(shape=(None, ))
x = Embedding(num_encoder_tokens, latent_dim)(encoder_inputs)
x, state_h, state_c = LSTM(latent_dim, return_state=True)(x)
encoder_states = [state_h, state_c]
# decoder
decoder_inputs = Input(shape=(None,))
x = Embedding(num_decoder_tokens, latent_dim)(decoder_inputs)
x = LSTM(latent_dim, return_sequences=True)(x, initial_state=encoder_states)
decoder_outputs = Dense(num_decoder_tokens, activation='softmax')(x)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
模型编译并看起来像这样:
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_35 (InputLayer) (None, None) 0
__________________________________________________________________________________________________
input_36 (InputLayer) (None, None) 0
__________________________________________________________________________________________________
embedding_32 (Embedding) (None, None, 256) 914432 input_35[0][0]
__________________________________________________________________________________________________
embedding_33 (Embedding) (None, None, 256) 914432 input_36[0][0]
__________________________________________________________________________________________________
lstm_32 (LSTM) [(None, 256), (None, 525312 embedding_32[0][0]
__________________________________________________________________________________________________
lstm_33 (LSTM) (None, None, 256) 525312 embedding_33[0][0]
lstm_32[0][1]
lstm_32[0][2]
__________________________________________________________________________________________________
dense_21 (Dense) (None, None, 3572) 918004 lstm_33[0][0]
编译工作时,培训
model.fit([encoder_input_data, decoder_input_data], decoder_target_data, batch_size=32, epochs=1, validation_split=0.2)
失败并出现以下错误:ValueError: Error when checking target: expected dense_21 to have 3 dimensions, but got array with shape (90000, 16)
,后者是解码器输入/目标的形状。为什么Dense
图层是解码器输入数据形状的数组?
我尝试过的事情:
return_sequences=True
有点奇怪,因为我以为我不能给Dense
层一个序列(并且原始字符级模型的解码器没有说明这个)。但是,只需删除或设置return_sequences=False
就无济于事。当然,Dense
图层现在的输出形状为(None, 3572)
。Input
层。我已将它们分别设置为shape=(max_input_seq_len, )
和shape=(max_target_seq_len, )
,以便摘要不会显示(None, None)
,而是显示相应的值,例如(None, 16)
。没有变化。input_length
一起使用,否则上游的Dense
层无法计算其输出。但是,当我相应地设置input_length
时,仍然会出错。我有点陷入僵局吗?我是在正确的轨道上还是从根本上错过了一些东西。我的数据形状错了吗?为什么最后一个Dense
图层的形状为(90000, 16)
?这似乎很不合适。
更新:我发现问题似乎是decoder_target_data
目前的形状为(#sample, max_seq_len)
,例如(90000, 16)
。但我认为我需要对词汇表进行单热编码目标输出:(#sample, max_seq_len, vocab_size)
,例如(90000, 16, 3572)
。
不幸的是,这会引发Memory
错误。但是,当我进行调试时,即假设词汇量大小为10:
decoder_target_data = np.zeros((len(input_sequences), max_target_seq_len, 10), dtype='float32')
以及后来的解码器模型:
x = Dense(10, activation='softmax')(x)
然后模型训练没有错误。如果这确实是我的问题,我必须通过手动生成批次来训练模型,这样我可以保持词汇量大小但是减少#samples
,例如,每个形状(1000, 16, 3572)
减少到90个批次。我在这里走在正确的轨道上吗?
答案 0 :(得分:0)
最近我也遇到了这个问题。没有其他解决方案,然后在batch_size=64
中创建小批量的generator
,然后代替model.fit
进行model.fit_generator
。我在下面附加了generate_batch
代码:
def generate_batch(X, y, batch_size=64):
''' Generate a batch of data '''
while True:
for j in range(0, len(X), batch_size):
encoder_input_data = np.zeros((batch_size, max_encoder_seq_length),dtype='float32')
decoder_input_data = np.zeros((batch_size, max_decoder_seq_length+2),dtype='float32')
decoder_target_data = np.zeros((batch_size, max_decoder_seq_length+2, num_decoder_tokens),dtype='float32')
for i, (input_text_seq, target_text_seq) in enumerate(zip(X[j:j+batch_size], y[j:j+batch_size])):
for t, word_index in enumerate(input_text_seq):
encoder_input_data[i, t] = word_index # encoder input seq
for t, word_index in enumerate(target_text_seq):
decoder_input_data[i, t] = word_index
if (t>0)&(word_index<=num_decoder_tokens):
decoder_target_data[i, t-1, word_index-1] = 1.
yield([encoder_input_data, decoder_input_data], decoder_target_data)
然后像这样进行训练:
batch_size = 64
epochs = 2
# Run training
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit_generator(
generator=generate_batch(X=X_train_sequences, y=y_train_sequences, batch_size=batch_size),
steps_per_epoch=math.ceil(len(X_train_sequences)/batch_size),
epochs=epochs,
verbose=1,
validation_data=generate_batch(X=X_val_sequences, y=y_val_sequences, batch_size=batch_size),
validation_steps=math.ceil(len(X_val_sequences)/batch_size),
workers=1,
)
X_train_sequences
是[[23,34,56], [2, 33544, 6, 10]]
之类的列表的列表。
其他人也一样。
还从此博客中获得了帮助-word-level-english-to-marathi-nmt