【问题标题】:TensorFlow 2.0: Eager execution of training either returns bad results or doesn't learn at allTensorFlow 2.0:急切执行训练要么返回糟糕的结果,要么根本不学习
【发布时间】:2019-03-21 08:58:34
【问题描述】:

我正在试验 TensorFlow 2.0 (alpha)。我想实现一个简单的前馈网络,它有两个用于二进制分类的输出节点(它是a 2.0 version of this model)。

这是脚本的简化版本。在我定义了一个简单的Sequential() 模型后,我设置:

# import layers + dropout & activation
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.activations import elu, softmax

# Neural Network Architecture
n_input = X_train.shape[1]
n_hidden1 = 15
n_hidden2 = 10
n_output = y_train.shape[1]


model = tf.keras.models.Sequential([
    Dense(n_input, input_shape = (n_input,), activation = elu),   # Input layer
    Dropout(0.2), 
    Dense(n_hidden1, activation = elu), # hidden layer 1
    Dropout(0.2),     
    Dense(n_hidden2, activation = elu), # hidden layer 2
    Dropout(0.2), 
    Dense(n_output, activation = softmax)  # Output layer
])


# define loss and accuracy
bce_loss = tf.keras.losses.BinaryCrossentropy()
accuracy = tf.keras.metrics.BinaryAccuracy()

# define optimizer
optimizer = tf.optimizers.Adam(learning_rate = 0.001)

# save training progress in lists
loss_history = []
accuracy_history = []


# loop over 1000 epochs
for epoch in range(1000):

    with tf.GradientTape() as tape:

        # take binary cross-entropy (bce_loss)
        current_loss = bce_loss(model(X_train), y_train)

    # Update weights based on the gradient of the loss function
    gradients = tape.gradient(current_loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    # save in history vectors
    current_loss = current_loss.numpy()
    loss_history.append(current_loss)

    accuracy.update_state(model(X_train), y_train)
    current_accuracy = accuracy.result().numpy()
    accuracy_history.append(current_accuracy)

    # print loss and accuracy scores each 100 epochs
    if (epoch+1) % 100 == 0:
        print(str(epoch+1) + '.\tTrain Loss: ' + str(current_loss) + ',\tAccuracy: ' + str(current_accuracy))

    accuracy.reset_states()

print('\nTraining complete.')

训练没有错误,但奇怪的事情发生了:

  • 有时,网络不会学到任何东西。在所有 epoch 中,所有损失和准确率分数都是恒定的。
  • 其他时候,网络正在学习,但非常非常糟糕。准确度从未超过 0.4(而在 TensorFlow 1.x 中,我毫不费力地获得了 0.95+)。如此低的表现表明我在训练中出了点问题。
  • 其他时候,准确度的提高非常缓慢,而损失始终保持不变。

什么会导致这些问题?请帮助我理解我的错误。


更新: 经过一些更正,我可以让网络学习。但是,它的性能极差。在 1000 个 epoch 之后,它达到了大约 %40 的准确率,这显然意味着仍然有问题。任何帮助表示赞赏。

【问题讨论】:

    标签: python tensorflow keras eager-execution tensorflow2.0


    【解决方案1】:

    tf.GradientTape 正在记录在其范围内发生的每个操作。

    你不想在磁带中记录梯度计算,你只想向前计算损失。

    with tf.GradientTape() as tape:
        # take binary cross-entropy (bce_loss)
        current_loss = bce_loss(model(df), classification)
    # End of tape scope
    
    # Update weights based on the gradient of the loss function
    gradients = tape.gradient(current_loss, model.trainable_variables)
    # The tape is now consumed
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    

    更重要的是,我没有看到训练集上的循环,因此我认为完整的代码如下所示:

    for epoch in range(n_epochs):
        for df, classification in dataset:
            # your code that computes loss and trains
    

    而且,指标的使用是错误的。

    您希望在每个训练步骤累积,从而更新准确度操作的内部状态,并在每个 epoch 结束时测量整体准确度。

    因此你必须:

    # Measure the accuracy inside the training loop
    accuracy.update_state(model(df), classification)
    

    并且仅在 epoch 结束时调用 accuracy.result(),此时所有准确度值都已保存到指标中。 记得调用 .reset_states() 方法来清除变量状态,在每个 epoch 结束时将其重置为零。

    【讨论】:

    • 1) 抱歉,我仍然没有收到for df, classification in dataset 行:什么是对象dataset? (在我的脚本中,df 是我的数据集,classification 是 one-hot 编码的因变量)。 2) 我应该写current_accuracy = accuracy.update_state(model(df), classification) 然后将其附加到accuracy_history 吗?顺便说一句,谢谢你提供的所有信息。
    • 1) 所以你不是循环平均批次,而是一次使用所有训练集。纯梯度下降而不是小批量梯度下降——那没关系!您可以删除我添加的循环部分,因为您不需要遍历数据集。 2) accuracy.update_state(model(df), classification) 然后 accuracy_history.append(accuracy.result()) 并以 accuracy_history.clear_states() 结尾
    • 您的意思是:accuracy.reset_states() 作为结尾吗?我应该为loss 做同样的事情吗?
    • 您好,我遵循了您的所有建议,但问题仍然存在。损失和准确率输出始终是恒定的,除非有时它学习但非常糟糕以至于它不可能是正确的。我还能尝试什么?
    • 我想我找到了原因! ` accuracy.update_state(model(X_train), y_train)` 应该是 ` accuracy.update_state(y_train, model(X_train))` 因为tensorflow.org/api_docs/python/tf/keras/metrics/Accuracy 是 accuracy(y_true, y_pred)
    猜你喜欢
    • 1970-01-01
    • 2019-11-04
    • 2017-12-10
    • 2018-11-20
    • 2019-06-15
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多