【问题标题】:Plot loss and accuracy over each epoch for both training and test datasets为训练和测试数据集绘制每个时期的损失和准确性
【发布时间】:2021-09-24 03:13:34
【问题描述】:

我正在训练该模型对 3 个类别 (0,1,2) 进行分类。我正在使用 2 倍交叉验证,我正在使用 pytorch,我想在同一个图上绘制训练和测试数据集的准确性和损失函数。我确实知道该怎么做。特别是我只是在完成训练后评估测试,有没有办法可以同时为训练数据和测试数据绘制该图

# Configuration options
k_folds = 2
loss_function = nn.CrossEntropyLoss()
# For fold results
results = {}
# Set fixed random number seed
torch.manual_seed(42)
# Prepare dataset by concatenating Train/Test part; we split later.
training_set = CustomDataset('one_hot_train_data.txt','train_3states_target.txt') #training_set = CustomDataset_3('one_hot_train_data.txt','train_5_target.txt')
training_generator = torch.utils.data.DataLoader(training_set, **params)
val_set = CustomDataset('one_hot_val_data.txt','val_3states_target.txt')
test_set = CustomDataset('one_hot_test_data.txt','test_3states_target.txt')
#testloader = torch.utils.data.DataLoader(test_set, **params)
#dataset1 = ConcatDataset([training_set, val_set])
dataset = ConcatDataset([training_set,test_set])
kfold = KFold(n_splits=k_folds, shuffle=True)

# Start print
print('--------------------------------')
# K-fold Cross Validation model evaluation
for fold, (train_ids, test_ids) in enumerate(kfold.split(dataset)):
    # Print
    print(f'FOLD {fold}')
    print('--------------------------------')
    # Sample elements randomly from a given list of ids, no replacement.
    train_subsampler = torch.utils.data.SubsetRandomSampler(train_ids)
    test_subsampler = torch.utils.data.SubsetRandomSampler(test_ids)

    # Define data loaders for training and testing data in this fold
    trainloader = torch.utils.data.DataLoader(
        dataset,**params, sampler=train_subsampler)
    testloader = torch.utils.data.DataLoader(
       dataset,
       **params, sampler=test_subsampler)
    # Init the neural network
    model = PPS()
    model.to(device)
    # Initialize optimizer
    optimizer = optim.SGD(model.parameters(), lr=LEARNING_RATE)
    # Run the training loop for defined number of epochs
    train_acc = []
    for epoch in range(0, N_EPOCHES):
        # Print epoch
        print(f'Starting epoch {epoch + 1}')
        # Set current loss value
        running_loss = 0.0
        epoch_loss = 0.0
        a = []
        # Iterate over the DataLoader for training data
        for i, data in enumerate(trainloader, 0):
            inputs, targets = data
            inputs = inputs.unsqueeze(-1)
            #inputs = inputs.to(device)
            targets = targets.to(device)
            inputs = inputs.to(device)
            # print(inputs.shape,targets.shape)
            # Zero the gradients
            optimizer.zero_grad()
            # Perform forward pass
            loss,outputs = model(inputs,targets)
            outputs = outputs.to(device)

            # Perform backward pass
            loss.backward()
            # Perform optimization
            optimizer.step()
            # print statistics
            running_loss += loss.item()
            epoch_loss += loss
            a.append(torch.sum(outputs == targets))
            # print(outputs.shape,outputs.shape[0])

            if i % 2000 == 1999:  # print every 2000 mini-batches
                print('[%d, %5d] loss: %.3f' %
                      (epoch + 1, i + 1, running_loss / 2000), "acc",
                      torch.sum(outputs == targets) / float(outputs.shape[0]))
                running_loss = 0.0
            # sum_acc += (outputs == stat_batch.argmax(1)).float().sum()
        print("epoch", epoch + 1, "acc", sum(a) / len(train_subsampler), "loss", epoch_loss / len(trainloader))
        train_acc.append(sum(a) / len(train_subsampler))
    state = {'epoch': epoch + 1, 'state_dict': model.state_dict(),
                     'optimizer': optimizer.state_dict() }
    torch.save(state, path + name_file + "model_epoch_i_" + str(epoch) + str(fold)+".cnn")
    #torch.save(model.state_dict(), path + name_file + "model_epoch_i_" + str(epoch) + ".cnn")
    # Print about testing
    print('Starting testing')

# Evaluation for this fold  
    correct, total = 0, 0
    with torch.no_grad():
    # Iterate over the test data and generate predictions
     for i, data in enumerate(testloader, 0):
        # Get inputs
        inputs, targets = data
        #targets = targets.to(device)
        inputs = inputs.unsqueeze(-1)
        inputs = inputs.to(device)
        # Generate outputs
        loss,outputs = model(inputs,targets)
        outputs.to(device)
        print("out",outputs.shape)
        print("target",targets.shape)
        print("targetsize",targets.size(0))
        print("sum",(outputs == targets).sum().item())
        #print("sum",torch.sum(outputs == targets))

        # Set total and correct
       # _, predicted = torch.max(outputs.data, 1)
        total += targets.size(0)
        correct += (outputs == targets).sum().item()
        #correct += torch.sum(outputs == targets)

    
    # Print accuracy
    print('Accuracy for fold %d: %d %%' % (fold,float( 100.0 * float(correct / total))))
    print('--------------------------------')
    results[fold] = 100.0 * float(correct / total)

# Print fold results
print(f'K-FOLD CROSS VALIDATION RESULTS FOR {k_folds} FOLDS')
print('--------------------------------')
sum = 0.0
for key, value in results.items():
    print(f'Fold {key}: {value} %')
    sum += value
print(f'Average: {float(sum / len(results.items()))} %')

【问题讨论】:

    标签: python keras pytorch cross-validation loss


    【解决方案1】:

    您可以使用专门为此构建的 Tensorboard,这里是 pytorch 的文档:https://pytorch.org/docs/stable/tensorboard.html

    所以在你打印结果的情况下,你可以做一个

    writer.add_scalar('accuracy/train',  torch.sum(outputs == targets) / float(outputs.shape[0]), n_iter)
    

    编辑:添加你可以关注的小例子

    假设您正在训练一个模型:

    model_name = 'network'
    log_name = '{}_{}'.format(model_name, strftime('%Y%m%d_%H%M%S'))
    writer = SummaryWriter('logs/{}'.format(log_name))
    
    net = Model()
    criterion = torch.nn.MSELoss()
    optimizer = torch.optim.SGD(net.parameters(), lr=0.1)
    
    for epoch in range(num_epochs):
        losses = []
        for i, (inputs,labels) in enumerate (trainloader):
            inputs = Variable(inputs.float())
            labels = Variable(labels.float())
            outputs = net(inputs)
            optimizer.zero_grad()
            loss = criterion(outputs, labels)
            losses.append(loss)
            loss.backward()
            optimizer.step()
            correct_values += (outputs == labels).float().sum()
        accuracy = 100 * correct_values / len(training_set)
        avg_loss = sum(losses) / len(training_set)
        writer.add_scalar('loss/train', avg_loss.item(), epoch)
        writer.add_scalar('acc/train', accuracy, epoch)
    
                    
    
    

    【讨论】:

    • 非常感谢你的回复,你能告诉我我把它放在哪里,因为我每 2000 批打印一次,但我想在每个时期上绘制,也为了测试那里没有时期,我了解文档,但我无法在我的示例中应用它。
    • 我编辑了我的答案,你应该看看你可以把它放在哪里,对于测试你只做一个时代,所以你可以做同样的事情,但只用writer.add_scalar('acc/test', accuracy, 1)显示最终值,或者,您可以使用仅不时使用的验证集,并根据这些数据绘制网络如何反应。
    • 在我的代码中,我结合训练和测试数据集进行 k 折交叉验证。在我的代码中还有我没有使用的验证数据集。您能否告诉我如何在测试期间使用它来绘制另一个情节
    • 在我的代码中,我结合训练和测试数据集进行 k 折交叉验证。在我的代码中还有我没有使用的验证数据集。您能否告诉我如何在验证期间使用它来绘制另一个图?
    • pytorch 和 tensorboard 的好处是你可以做任何你想做的事,你可以检查 epoch 是否是模验证频率 (if epoch % val_frequency == 0) 然后迭代你的数据并做和训练一样的事情但放置一个 net.train(False) 并以 writer.add_scalar('loss/val', avg_loss.item(), epoch) writer.add_scalar('acc/val', accuracy, epoch) 结尾
    猜你喜欢
    • 2022-10-05
    • 2017-06-13
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    相关资源
    最近更新 更多