【发布时间】:2018-04-19 00:14:05
【问题描述】:
我正在 Keras 中构建一个序列到序列模型,以纠正可能发生的简单拼写错误。我主要关注this tutorial。
我有一段相当复杂的代码来生成单词中的随机拼写错误,然后我将其输出:([misspelled sentence,offset_sentence],original_sentence) 发送到模型中。我构建的模型看起来与教程中的模型几乎完全相同:
print('Training tokenizer...')
tokenizer = CharToken()
tokenizer.train_on_corpus(brown)
num_chars = len(tokenizer.char_dict)
alpha = 0.001
encoder_inputs = Input(shape=(None,num_chars))
encoder = LSTM(128,return_state=True)
encoder_outputs,state_h,state_c = encoder(encoder_inputs)
encoder_states = [state_h,state_c]
decoder_inputs = Input(shape=(None,num_chars))
decoder = LSTM(128,return_sequences=True,return_state=True)
decoder_outputs,_,_ =
decoder(decoder_inputs,initial_state=encoder_states)
decoder_dense = Dense(num_chars,activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)
model = keras.models.Model(inputs=
[encoder_inputs,decoder_inputs],outputs=decoder_outputs)
optim = keras.optimizers.rmsprop(lr=alpha,decay=1e-6)
model.compile(optimizer=optim,loss='categorical_crossentropy')
model.summary()
model.fit_generator(tokenizer.batch_generator(),
steps_per_epoch=1000,epochs=1)
我确定问题不在于标记器,因为我已经检查过它并多次检查了所有输出。该类中的 batch_generator 方法输出一个表示([misspelled sentence,offset_sentence],original_sentence) 的热向量的元组。我尝试过更改超参数,包括将学习率设为微乎其微的 0.00001,但无论我做什么,训练损失总是从 11 左右开始,然后不断增加......
谁能弄清楚我做错了什么?
编辑:我又进行了一步调试,从等式中删除了标记器,并尝试在 3 个随机的 one-hot 数组上训练网络。通过将它们限制为只有 10 个可能的输入/输出(字符),我大大降低了复杂性。损失迅速上升到约 100 并保持在那里。我预计随机猜测的 10 种可能结果会让我损失大约-ln(1/10)~2.3,当然 100 太高了。我也期望即使我给网络提供随机数组,它最终会记住这些数组并过度拟合并且损失会减少,但事实并非如此。损失保持在 100 左右。我不知道出了什么问题...
编辑 2:更多调试。通过强制输入和输出具有相同的长度,我将模型打造成更简单的模型。只要拼写错误没有删除或插入太多字符,这对于拼写校正器来说并不算太糟糕(我无论如何都会填充序列以使它们具有相同的长度,这使我能够进行批量训练)。但是,该模型仍然表现出相同的行为。我还尝试在随机数上运行模型并获得相同的 100ish 损失:
num_chars=10
alpha = 0.001
X = np.random.randint(10,size=(10000,30,10))
Y = np.random.randint(10,size=(10000,30,10))
inputs = Input(shape=(None,num_chars))
x = LSTM(128,return_sequences=True)(inputs)
x = LSTM(128,return_sequences=True)(x)
output = Dense(num_chars,activation='softmax')(x)
model = keras.models.Model(inputs=inputs,outputs=output)
optim = keras.optimizers.rmsprop(lr=alpha,decay=1e-6)
model.compile(optimizer=optim,loss='categorical_crossentropy')
model.summary()
model.fit(X,Y)
我开始怀疑我安装的 keras 或类似的东西是否有问题。我以前在我的另一台机器上多次运行过这样的序列模型,但我从未观察到这种奇怪的行为。
编辑 3:我刚刚意识到我的调试存在缺陷。我没有将随机 Y 数组变成一个单热向量。当我将其更改为单热向量时,损失与预期一致,约为-ln(1/num_chars)。这意味着问题可能出在我的标记器生成器中。但是我无法弄清楚问题出在哪里,因为我已经打印了输出并看到它们确实是 one-hot 向量。
【问题讨论】:
-
尝试在 LSTM 中使用激活函数,例如tanh。
-
keras中的lstms自动有默认的激活函数。
标签: python-3.x keras