【问题标题】:How do I get non-aggregated batch statistics with tf.keras.callbacks?如何使用 tf.keras.callbacks 获取非聚合批处理统计信息?
【发布时间】:2021-04-14 10:02:09
【问题描述】:

我正在尝试使用 keras model.fit() 方法训练模型。此方法返回一个历史对象,其中包含每个时期的损失值 - 但是我希望每个批次都有损失值。

在网上我发现了使用带有on_batch_end(self, logs={}) 方法的自定义回调类的建议。问题是这个方法只能通过 聚合 统计信息,这些统计信息在每个 epoch 都会被重置。我想为每个批次提供个人统计信息。

https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/Callback#on_train_batch_end

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    您可以通过自定义训练循环轻松做到这一点,您可以在其中添加一个包含每批损失值的列表。

    train_loss_per_train_batch.append(loss_value.numpy())
    

    以下是所有操作的方法:

    import tensorflow as tf
    import tensorflow_datasets as tfds
    
    ds = tfds.load('iris', split='train', as_supervised=True)
    
    train = ds.take(125).shuffle(16).batch(4)
    test = ds.skip(125).take(25).shuffle(16).batch(4)
    
    model = tf.keras.Sequential([
        tf.keras.layers.Dense(16, activation='relu'),
        tf.keras.layers.Dense(32, activation='relu'),
        tf.keras.layers.Dense(3, activation='softmax')
    ])
    
    
    loss_object = tf.losses.SparseCategoricalCrossentropy(from_logits=False)
    
    
    def compute_loss(model, x, y, training):
      out = model(x, training=training)
      loss = loss_object(y_true=y, y_pred=out)
      return loss
    
    
    def get_grad(model, x, y):
        with tf.GradientTape() as tape:
            loss = compute_loss(model, x, y, training=True)
        return loss, tape.gradient(loss, model.trainable_variables)
    
    
    optimizer = tf.optimizers.Adam()
    
    verbose = "Epoch {:2d} Loss: {:.3f} TLoss: {:.3f} Acc: {:.2%} TAcc: {:.2%}"
    
    train_loss_per_train_batch = list()
    
    for epoch in range(1, 25 + 1):
        train_loss = tf.metrics.Mean()
        train_acc = tf.metrics.SparseCategoricalAccuracy()
        test_loss = tf.metrics.Mean()
        test_acc = tf.metrics.SparseCategoricalAccuracy()
    
        for x, y in train:
            loss_value, grads = get_grad(model, x, y)
            optimizer.apply_gradients(zip(grads, model.trainable_variables))
            train_loss.update_state(loss_value)
            train_acc.update_state(y, model(x, training=True))
            train_loss_per_train_batch.append(loss_value.numpy())
    
        for x, y in test:
            loss_value, _ = get_grad(model, x, y)
            test_loss.update_state(loss_value)
            test_acc.update_state(y, model(x, training=False))
    
        print(verbose.format(epoch,
                             train_loss.result(),
                             test_loss.result(),
                             train_acc.result(),
                             test_acc.result()))
    

    【讨论】:

    • 如问题所述,on_train_batch_end 没有获得单个批次的统计信息,只有当前批次之前所有批次的聚合
    • 我可以找到另一种方法,但可以支持该声明吗?我在文档中找不到它tensorflow.org/guide/keras/custom_callback
    • tensorflow.org/api_docs/python/tf/keras/callbacks/… 函数参数说明表中是这样写的
    • 我猜你应该去自定义训练循环(见更新的答案)
    • 我希望能够避免这种情况——哦,好吧。仍然感谢您的意见!
    猜你喜欢
    • 2023-01-12
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    • 2012-05-07
    • 2021-03-03
    相关资源
    最近更新 更多