我正在构建一个序列来对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个随机单热阵列上训练网络。我通过限制它们只有10个可能的输入/输出(字符)来大大降低了复杂性。损失迅速上升至100左右并留在那里。我期待10种可能的结果,随机猜测会让我失去大约-ln(1/10)~2.3
,当然100太高了。我也期望即使我给网络随机数组输入它最终会记住那些数组并且过度拟合并且损失会减少,但事实并非如此。损失大约为100.我无法弄清楚出了什么问题......
编辑2:更多调试。我通过强制输入和输出具有相同的长度,将模型打成更简单的模型。对于拼写纠正器来说这不是太糟糕,只要拼写错误没有删除或插入太多字符(我不管怎样填充序列以使它们具有相同的长度,这使我能够批量训练)。但是,该模型仍然表现出相同的行为。我也尝试在随机数上运行该模型并获得相同的100损失:
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)
。这意味着问题可能出在我的tokenizer生成器中。但我无法弄清问题是什么,因为我打印出输出并发现它们确实是一个热门的载体。
答案 0 :(得分:1)
对于将来发生在这个问题上的人。我已经找到了问题,不幸的是问题不在我发布的代码块中,所以没有办法从这里调试代码。对于那个很抱歉。
问题是我在生成器函数内的错误位置初始化了一个热向量。因此,他们在每批次之后都没有被重新归零,他们只是填满了1,导致更糟糕和更糟糕的损失。很难发现这个问题,因为发生器实际上对第一个循环工作得很好,所以每当我打印出它的输出时,我看到了正确的输出。