每批次和历元的验证和训练损失

问题描述 投票:0回答:2

我正在使用 Pytorch 运行一些深度学习模型。我目前正在跟踪每个时期的训练和验证损失,这是相当标准的。但是,跟踪每批/迭代的训练和验证损失的最佳方法是什么?

对于训练损失,我可以在每次训练循环后保留一个损失列表。但是,验证损失是在整个 epoch 之后计算的,所以我不确定如何计算每批的验证损失。我唯一能想到的就是在每个训练批次之后运行整个验证步骤并跟踪这些步骤,但这似乎有点矫枉过正并且需要大量计算。

比如训练是这样的:

for epoch in range(2): # 多次循环数据集

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()

对于验证损失:

with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
        # validation loss
        batch_loss = error(outputs.float(), labels.long()).item()
        loss_test += batch_loss
    loss_test /= len(testloader)

验证损失/测试部分是在每个时期完成的。我正在寻找一种方法来获取每批次的验证损失,这就是我上面的观点。

有什么建议吗?

machine-learning deep-learning pytorch
2个回答
3
投票

嗯,你是对的,这就是“在每个训练批次后运行整个验证步骤并跟踪这些步骤”的方法,而且你也认为这非常耗时并且太过分了。但是,如果这是您真正需要的东西,那么有一种方法可以做到。

您可以做的是,假设您的数据中有 1000 个批次。现在,要计算每批次验证损失,您可以选择不对每个批次运行验证步骤(那么您必须执行 1000 次!),但对于这些批次的一小部分,我们假设 50/100(选择如您所愿或认为可行)。

现在,您可以使用一些统计功效,以便您对 50/100 批次的计算变得非常非常接近 1000 批次的计算结果(这意味着,如果您计算过,少量批次的验证损失必须接近 1000 批次的验证损失) ),因此为了实现这一目标,您可以在批次选择中引入一些随机性。 这意味着您从 1000 个批次中随机选择 100 个批次来运行验证步骤。


2
投票

epoch是让模型经历整个训练集的过程——通常分为批次。而且,它往往会被洗牌。另一方面,验证集用于调整训练的超参数,并找出模型对新数据的行为。从这方面来说,对我来说,评价

epoch=1/2
没有多大意义。因为问题是 - 无论评估设置为
epoch=1/2
的表现如何 - 你能做什么?因为,您不知道它在纪元的前半部分经历了哪些数据,所以无法利用“前半部分更好”的优势......并且记住您的数据可能会被分成批次。

因此,我会坚持使用经典方法:然后对整个集合进行训练,然后才对另一组进行评估。在某些情况下,由于计算时间的原因,您甚至不允许自己每个时期评估一次。相反,您将评估每个 n 时期。但话又说回来,这将取决于您的数据集大小、从该数据集进行的采样、批量大小和计算成本。

对于训练损失,您可以跟踪其值 per-update-step vs. per-epoch。这将使您能够更好地控制模型是否独立于验证阶段进行学习。


编辑 - 作为不必在每个训练批次运行整个评估集的替代方案,您可以执行以下操作:洗牌验证并设置与训练集相同的批次大小。

  • len(trainset)//batch_size
    是每个 epoch 的更新数量
  • len(validset)//batch_size
    是每个 epoch 允许的评估次数
  • 您可以在
    len(trainset)//len(validset)
    上评估每个
    1
    火车更新 批次

这可以让您在每个时期获得

len(trainset)//len(validset)
次反馈。

如果将训练/有效比率设置为

0.1
,则
len(validset)=0.1*len(trainset)
,即每个 epoch 10 部分评估。

© www.soinside.com 2019 - 2024. All rights reserved.