7

在我的理解中,一个时期是对整个数据集的任意重复运行,而这些数据又被分部分处理,即所谓的批次。每train_on_batch计算一个损失后,更新权重,下一批会得到更好的结果。这些损失是 my to NN 的质量和学习状态的指标。

在几个来源中,每个时期都会计算(并打印)损失。因此,我不确定我是否做对了。

目前我的 GAN 看起来像这样:

for epoch:
  for batch:

    fakes = generator.predict_on_batch(batch)

    dlc = discriminator.train_on_batch(batch, ..)
    dlf = discriminator.train_on_batch(fakes, ..)
    dis_loss_total = 0.5 *  np.add(dlc, dlf)

    g_loss = gan.train_on_batch(batch,..)

    # save losses to array to work with later

这些损失是针对每批的。我如何获得它们一个时代?顺便说一句:我需要一个时期的损失,为什么?

4

2 回答 2

7

没有直接的方法来计算一个时期的损失。实际上,一个时期的损失通常定义为该时期中批次损失的平均值。因此,您可以在一个时期内累积损失值,最后将其除以该时期中的批次数:

epoch_loss = []
for epoch in range(n_epochs):
    acc_loss = 0.
    for batch in range(n_batches):
        # do the training 
        loss = model.train_on_batch(...)
        acc_loss += loss
    epoch_loss.append(acc_loss / n_batches)

至于另一个问题,时期损失的一种用法可能是将其用作停止训练的指标(但是,通常使用验证损失,而不是训练损失)。

于 2019-01-05T16:45:18.437 回答
1

我将扩展@today 的答案。在如何报告一个时期的损失以及如何使用它来确定何时停止训练方面存在一定的平衡。

  • 如果您只查看最近批次的损失,这将是对您的数据集损失的一个非常嘈杂的估计,因为可能该批次恰好存储了您的模型遇到问题的所有样本,或者所有难以成功的样本.
  • 如果您查看 epoch 中所有批次的平均损失,您可能会得到一个倾斜的响应,因为正如您所指出的,该模型已经(希望)在 epoch 中有所改进,因此初始批次的性能没有那么有意义与后期批次的性能相比。

准确报告 epoch loss 的唯一方法是将模型退出训练模式,即修复所有模型参数,然后在整个数据集上运行模型。这将是对您的时代损失的无偏计算。然而,总的来说这是一个糟糕的主意,因为如果你有一个复杂的模型或大量的训练数据,你会浪费很多时间来做这件事。

因此,我认为通过报告N个小批次的平均损失来平衡这些因素是最常见的,其中N大到足以消除单个批次的噪声,但又不会大到模型性能在第一个和第一个批次之间无法比较最后一批。

我知道你在 Keras,但这里有一个 PyTorch 示例清楚地说明了这个概念,在这里复制:

for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

您可以看到他们累积了N = 2000 个批次的损失,报告了这 2000 个批次的平均损失,然后将运行损失归零并继续前进。

于 2020-06-04T16:56:38.663 回答