使用 CNN 和 pytorch 计算每个类的准确率

Posted

技术标签:

【中文标题】使用 CNN 和 pytorch 计算每个类的准确率【英文标题】:calculate accuracy for each class using CNN and pytorch 【发布时间】:2020-11-07 12:17:53 【问题描述】:

我可以使用此代码在每个 epoch 后计算准确度。但是,我想在最后计算每个类的准确性。我怎样才能做到这一点? 我有两个文件夹 train 和 val 。每个文件夹有 7 个不同类别的 7 个文件夹。 train 文件夹用于训练。否则 val 文件夹用于测试

  def train_model(model, criterion, optimizer, lr_scheduler, num_epochs=25):
    since = time.time()

    best_model = model
    best_acc = 0.0

    for epoch in range(num_epochs):
        print('Epoch /'.format(epoch, num_epochs - 1))
        print('-' * 10)

        # Each epoch has a training and validation phase
        for phase in ['train', 'val']:
            if phase == 'train':
                mode='train'
                optimizer = lr_scheduler(optimizer, epoch)
                model.train()  # Set model to training mode
            else:
                model.eval()
                mode='val'

            running_loss = 0.0
            running_corrects = 0

            counter=0
            # Iterate over data.
            for data in dset_loaders[phase]:
                inputs, labels = data
                print(inputs.size())
                # wrap them in Variable
                if use_gpu:
                    try:
                        inputs, labels = Variable(inputs.float().cuda()),                             
                        Variable(labels.long().cuda())
                    except:
                        print(inputs,labels)
                else:
                    inputs, labels = Variable(inputs), Variable(labels)

                # Set gradient to zero to delete history of computations in previous epoch. Track operations so that differentiation can be done automatically.
                optimizer.zero_grad()
                outputs = model(inputs)
                _, preds = torch.max(outputs.data, 1)
                
                loss = criterion(outputs, labels)
                # print('loss done')                
                # Just so that you can keep track that something's happening and don't feel like the program isn't running.
                # if counter%10==0:
                #     print("Reached iteration ",counter)
                counter+=1

                # backward + optimize only if in training phase
                if phase == 'train':
                    # print('loss backward')
                    loss.backward()
                    # print('done loss backward')
                    optimizer.step()
                    # print('done optim')
                # print evaluation statistics
                try:
                    # running_loss += loss.data[0]
                    running_loss += loss.item()
                    # print(labels.data)
                    # print(preds)
                    running_corrects += torch.sum(preds == labels.data)
                    # print('running correct =',running_corrects)
                except:
                    print('unexpected error, could not calculate loss or do a sum.')
            print('trying epoch loss')
            epoch_loss = running_loss / dset_sizes[phase]
            epoch_acc = running_corrects.item() / float(dset_sizes[phase])
            print(' Loss: :.4f Acc: :.4f'.format(
                phase, epoch_loss, epoch_acc))


            # deep copy the model
            if phase == 'val':
                if USE_TENSORBOARD:
                    foo.add_scalar_value('epoch_loss',epoch_loss,step=epoch)
                    foo.add_scalar_value('epoch_acc',epoch_acc,step=epoch)
                if epoch_acc > best_acc:
                    best_acc = epoch_acc
                    best_model = copy.deepcopy(model)
                    print('new best accuracy = ',best_acc)
    time_elapsed = time.time() - since
    print('Training complete in :.0fm :.0fs'.format(
        time_elapsed // 60, time_elapsed % 60))
    print('Best val Acc: :4f'.format(best_acc))
    print('returning and looping back')
    return best_model


def exp_lr_scheduler(optimizer, epoch, init_lr=BASE_LR, lr_decay_epoch=EPOCH_DECAY):
    """Decay learning rate by a factor of DECAY_WEIGHT every lr_decay_epoch epochs."""
    lr = init_lr * (DECAY_WEIGHT**(epoch // lr_decay_epoch))

    if epoch % lr_decay_epoch == 0:
        print('LR is set to '.format(lr))

    for param_group in optimizer.param_groups:
        param_group['lr'] = lr

    return optimizer

 

【问题讨论】:

【参考方案1】:

计算整体准确率相当简单:

outputs = model(inputs)
_, preds = torch.max(outputs.data, 1)

acc_all = (preds == labels).float().mean()

要按类计算它需要多几行代码:

acc = [0 for c in list_of_classes]
for c in list_of_classes:
    acc[c] = ((preds == labels) * (labels == c)).float() / (max(labels == c).sum(), 1))

【讨论】:

短甜又有效。

以上是关于使用 CNN 和 pytorch 计算每个类的准确率的主要内容,如果未能解决你的问题,请参考以下文章

在 PyTorch 中计算每个 epoch 的准确率

为啥损失减少而准确率却没有增加? PyTorch

PyTorch实现TPU版本CNN模型

CNN模型学不好

如何计算或绘制 CNN 中每个类的误差?

pytorch学习笔记:卷积神经网络CNN(基础篇)