【问题标题】:Keras sequence to sequence model loss increases without boundKeras 序列到序列模型的损失无限制地增加
【发布时间】: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


【解决方案1】:

致那些将来遇到这个问题的人。我已经找到了问题所在,不幸的是,问题不在我发布的代码块中,因此无法从这里调试代码。对于那个很抱歉。

问题是我在生成器函数内的错误位置初始化了一个热向量。所以他们没有在每批之后重新归零,他们只是被填满了 1,导致越来越严重的损失。很难发现这个问题,因为生成器实际上在第一个循环中工作得很好,所以每当我打印出它的输出时,我都会看到正确的输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-03
    • 2019-09-18
    • 2021-06-12
    • 2021-09-08
    • 2021-09-08
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    相关资源
    最近更新 更多