Skip to main content
 首页 » 编程设计

python之Tensorflow Keras LSTM 未训练之受 number_of_epochs、优化器 adam 影响

2024年12月31日29lyhabc

我有 2 个代码片段。其中一个训练模型,而另一个不训练。我不想在没有深入了解的情况下在 Github 上提出问题,这浪费了我一天的时间来等待错误的模型进行训练。

这是模型,是正确的。运行 tensorflow 1.10.1。

model = Sequential() 
# I truncate the string at 20 characters, alphabet listset is a sorted list of the set of [A-Za-z0-9-_] which has len = 64 
model.add(LSTM(512, return_sequences=True, input_shape=(20, len(alphabet_listset)), dropout=0.2, stateful=False)) 
model.add(LSTM(512, return_sequences=False, dropout=0.2, stateful=False)) 
model.add(Dense(2, activation="softmax")) 
model.compile(optimizer=adam, loss='categorical_crossentropy',  
              metrics=['accuracy'])  # adam here is at learning rate 1e-3 
model.summary() 

要创建 X_train 和 Y_train,我使用 test_train_split。 我将字符串转换为一个热向量的方式(即使现在 lstm 有一个热向量的功能,如果你添加它真的有帮助)是

def string_vectorizer(strng, alphabet, max_str_len=20): 
    vector = [[0 if char != letter else 1 for char in alphabet] for letter in strng[0:max_str_len]] 
    while len(vector) != max_str_len: 
        vector = [*vector, [0 for char in alphabet]] 
    return np.array(vector) 

我提到的正确部分确实是正确的,因为这不是我第一次训练这个模型并验证它。我需要每个月更新我的模型,当我通过运行多个模型来测试我的架构时,我遇到了这个异常。

这是错误的代码

    model.fit(X_train, to_categorical(Y_train, 2), epochs=1000, 
              validation_data=(X_test, to_categorical(Y_test, 2)), 
              verbose=2, shuffle=True) 
    loss, accuracy = model.evaluate(X_test, to_categorical(Y_test, 2)) 

此错误片段的输出与正确片段日志相同,只是准确度在 12 个时期内保持在 0.5454,并且损失没有减少。我的示例数据分为 50k 正确标签和 60k 错误标签。因此,如果模型仅针对所有 60k 个错误标签预测 1,则准确度将为 60k/(60k + 50k) => 0.54。

这是正确的代码,唯一的区别是epochs的值。

expected_acc_eth, expected_loss_eth = 0.83, 0.40 
 
while(True): 
    model.fit(X_train, to_categorical(Y_train, 2), epochs=1, 
              validation_data=(X_test, to_categorical(Y_test, 2)),\ 
              verbose=2, shuffle=True) 
    loss, accuracy = model.evaluate(X_test, to_categorical(Y_test, 2)) 
 
    if((accuracy > expected_acc_eth) & (loss < expected_loss_eth)): 
        break 

此正确代码的输出

Train on 99000 samples, validate on 11000 samples 
Epoch 1/1 
 - 1414s - loss: 0.6847 - acc: 0.5578 - val_loss: 0.6698 - val_acc: 0.5961 
11000/11000 [==============================] - 36s 3ms/step 
Train on 99000 samples, validate on 11000 samples 
Epoch 1/1 
 - 1450s - loss: 0.6777 - acc: 0.5764 - val_loss: 0.6707 - val_acc: 0.5886 
11000/11000 [==============================] - 36s 3ms/step 
Train on 99000 samples, validate on 11000 samples 
Epoch 1/1 
 - 1425s - loss: 0.6729 - acc: 0.5862 - val_loss: 0.6643 - val_acc: 0.6030 
11000/11000 [==============================] - 37s 3ms/step 
Train on 99000 samples, validate on 11000 samples 
Epoch 1/1 
 - 1403s - loss: 0.6681 - acc: 0.5948 - val_loss: 0.6633 - val_acc: 0.6092 
11000/11000 [==============================] - 35s 3ms/step 
Train on 99000 samples, validate on 11000 samples 
Epoch 1/1 

我看过this stackoverflow post其中指出,提前停止会影响模型的学习方式,但它们与每个时期理论的步数偏离了主题。我尝试设置 batch_size 但这无济于事,或者我无法正确设置,因为它与 adam 的学习率成反比,而且我的规模一定已经关闭。我在某种程度上了解深度网络和机器学习,但这在输出之间差异太大了。

我希望它能帮助其他面临类似错误的人避免像我一样浪费太多时间!

有人可以详细说明一下吗?非常感谢任何帮助!

请您参考如下方法:

从我们在评论中的讨论来看,当使用 epochs > 1< 调用 model.fit() 时,Adam 优化器的实现似乎无法更新任何内容.

我很想知道为什么这是,但目前(较慢的)工作解决方案是使用 optimizer=rmsprop 而不是 optimizer=adam 在您对 model.compile() 的调用中。