• 【猫狗数据集】使用top1和top5准确率衡量模型


    数据集下载地址:

    链接:https://pan.baidu.com/s/1l1AnBgkAAEhh0vI5_loWKw
    提取码:2xq4

    创建数据集:https://www.cnblogs.com/xiximayou/p/12398285.html

    读取数据集:https://www.cnblogs.com/xiximayou/p/12422827.html

    进行训练:https://www.cnblogs.com/xiximayou/p/12448300.html

    保存模型并继续进行训练:https://www.cnblogs.com/xiximayou/p/12452624.html

    加载保存的模型并测试:https://www.cnblogs.com/xiximayou/p/12459499.html

    划分验证集并边训练边验证:https://www.cnblogs.com/xiximayou/p/12464738.html

    使用学习率衰减策略并边训练边测试:https://www.cnblogs.com/xiximayou/p/12468010.html

    利用tensorboard可视化训练和测试过程:https://www.cnblogs.com/xiximayou/p/12482573.html

    从命令行接收参数:https://www.cnblogs.com/xiximayou/p/12488662.html

    epoch、batchsize、step之间的关系:https://www.cnblogs.com/xiximayou/p/12405485.html

    之前使用的仅仅是top1准确率。在图像分类中,一般使用top1和top5来衡量分类模型的好坏。下面来看看。

    首先在util下新建一个acc.py文件,向里面加入计算top1和top5准确率的代码:

    import torch
    def accu(output, target, topk=(1,)):
        """Computes the accuracy over the k top predictions for the specified values of k"""
        with torch.no_grad():
            maxk = max(topk)
            batch_size = target.size(0)
            _, pred = output.topk(maxk, 1, True, True)
            pred = pred.t()
            correct = pred.eq(target.view(1, -1).expand_as(pred))
    
            res = []
            for k in topk:
                correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
                res.append(correct_k.mul_(100.0 / batch_size))
            return res

    重点就是topk()函数:

    torch.topk(input, k, dim=None, largest=True, sorted=True, out=None) -> (Tensor, LongTensor)
    input:输入张量
    k:指定返回的前几位的值
    dim:排序的维度
    largest:返回最大值
    sorted:返回值是否排序
    out:可选输出张量

    需要注意的是我们这里只有两类,因此不存在top5。因此如果设置参数topk=(1,5),则会报错:RuntimeError:invalid argument 5:k not in range for dimension at /pytorch/ate ... 

    因此我们只能设置topk=(1,2),而且top2的值肯定是100%。最终res中第一位存储的是top1准确率,第二位存储的是top2准确率。

    然后修改对应的train.py:

    import torch
    from tqdm import tqdm
    from tensorflow import summary
    import datetime
    from utils import acc
    
    """
    current_time = str(datetime.datetime.now().timestamp())
    train_log_dir = '/content/drive/My Drive/colab notebooks/output/tsboardx/train/' + current_time
    test_log_dir = '/content/drive/My Drive/colab notebooks/output/tsboardx/test/' + current_time
    val_log_dir = '/content/drive/My Drive/colab notebooks/output/tsboardx/val/' + current_time
    train_summary_writer = summary.create_file_writer(train_log_dir)
    val_summary_writer = summary.create_file_writer(val_log_dir)
    test_summary_writer = summary.create_file_writer(test_log_dir)
    """
    class Trainer:
      def __init__(self,criterion,optimizer,model):
        self.criterion=criterion
        self.optimizer=optimizer
        self.model=model
      def get_lr(self):
        for param_group in self.optimizer.param_groups:
            return param_group['lr']
      def loop(self,num_epochs,train_loader,val_loader,test_loader,scheduler=None,acc1=0.0):
        self.acc1=acc1
        for epoch in range(1,num_epochs+1):
          lr=self.get_lr()
          print("epoch:{},lr:{:.6f}".format(epoch,lr))
          self.train(train_loader,epoch,num_epochs)
          self.val(val_loader,epoch,num_epochs)
          self.test(test_loader,epoch,num_epochs)
          if scheduler is not None:
            scheduler.step()
    
      def train(self,dataloader,epoch,num_epochs):
        self.model.train()
        with torch.enable_grad():
          self._iteration_train(dataloader,epoch,num_epochs)
    
      def val(self,dataloader,epoch,num_epochs):
        self.model.eval()
        with torch.no_grad():
          self._iteration_val(dataloader,epoch,num_epochs)
      def test(self,dataloader,epoch,num_epochs):
        self.model.eval()
        with torch.no_grad():
          self._iteration_test(dataloader,epoch,num_epochs)
    
      def _iteration_train(self,dataloader,epoch,num_epochs):
        #total_step=len(dataloader)
        #tot_loss = 0.0
        #correct = 0
        train_loss=AverageMeter()
        train_top1=AverageMeter()
        train_top2=AverageMeter()
        #for i ,(images, labels) in enumerate(dataloader):
        #res=[]
        for images, labels in tqdm(dataloader,ncols=80):
          images = images.cuda()
          labels = labels.cuda()
          # Forward pass
          outputs = self.model(images)
          #_, preds = torch.max(outputs.data,1)
          pred1_train,pred2_train=acc.accu(outputs,labels,topk=(1,2))
          loss = self.criterion(outputs, labels)
          train_loss.update(loss.item(),images.size(0))
          train_top1.update(pred1_train[0],images.size(0))
          train_top2.update(pred2_train[0],images.size(0))
          # Backward and optimizer
          self.optimizer.zero_grad()
          loss.backward()
          self.optimizer.step()
          #tot_loss += loss.data
          """
          if (i+1) % 2 == 0:
              print('Epoch: [{}/{}], Step: [{}/{}], Loss: {:.4f}'
                    .format(epoch, num_epochs, i+1, total_step, loss.item()))
          """
          #correct += torch.sum(preds == labels.data).to(torch.float32)
        ### Epoch info ####
        #epoch_loss = tot_loss/len(dataloader.dataset)
        #epoch_acc = correct/len(dataloader.dataset)
        #print('train loss: {:.4f},train acc: {:.4f}'.format(epoch_loss,epoch_acc))
        print(">>>[{}] train_loss:{:.4f} top1:{:.4f} top2:{:.4f}".format("train", train_loss.avg, train_top1.avg, train_top2.avg))
        """
        with train_summary_writer.as_default():
          summary.scalar('loss', train_loss.avg, epoch)
          summary.scalar('accuracy', train_top1.avg, epoch)
        """
        """
        if epoch==num_epochs:
          state = { 
            'model': self.model.state_dict(), 
            'optimizer':self.optimizer.state_dict(), 
            'epoch': epoch,
            'train_loss':train_loss.avg,
            'train_acc':train_top1.avg,
          }
          save_path="/content/drive/My Drive/colab notebooks/output/"   
          torch.save(state,save_path+"/resnet18_final_v2"+".t7")
        """
        t_loss = train_loss.avg,
        t_top1 = train_top1.avg
        t_top2 = train_top2.avg
        return t_loss,t_top1,t_top2
      def _iteration_val(self,dataloader,epoch,num_epochs):
        #total_step=len(dataloader)
        #tot_loss = 0.0
        #correct = 0
        #for i ,(images, labels) in enumerate(dataloader):
        val_loss=AverageMeter()
        val_top1=AverageMeter()
        val_top2=AverageMeter()
        for images, labels in tqdm(dataloader,ncols=80):
            images = images.cuda()
            labels = labels.cuda()
    
            # Forward pass
            outputs = self.model(images)
            #_, preds = torch.max(outputs.data,1)
            pred1_val,pred2_val=acc.accu(outputs,labels,topk=(1,2))
            loss = self.criterion(outputs, labels)
            val_loss.update(loss.item(),images.size(0))
            val_top1.update(pred1_val[0],images.size(0))
            val_top2.update(pred2_val[0],images.size(0))
            #tot_loss += loss.data
            #correct += torch.sum(preds == labels.data).to(torch.float32)
            """
            if (i+1) % 2 == 0:
                print('Epoch: [{}/{}], Step: [{}/{}], Loss: {:.4f}'
                      .format(1, 1, i+1, total_step, loss.item()))
            """
        ### Epoch info ####
        #epoch_loss = tot_loss/len(dataloader.dataset)
        #epoch_acc = correct/len(dataloader.dataset)
        #print('val loss: {:.4f},val acc: {:.4f}'.format(epoch_loss,epoch_acc))
        print(">>>[{}] val_loss:{:.4f} top1:{:.4f} top2:{:.4f}".format("val", val_loss.avg, val_top1.avg, val_top2.avg))
        """
        with val_summary_writer.as_default():
          summary.scalar('loss', val_loss.avg, epoch)
          summary.scalar('accuracy', val_top1.avg, epoch)
        """
        t_loss = val_loss.avg,
        t_top1 = val_top1.avg
        t_top2 = val_top2.avg
        return t_loss,t_top1,t_top2
      def _iteration_test(self,dataloader,epoch,num_epochs):
        #total_step=len(dataloader)
        #tot_loss = 0.0
        #correct = 0
        #for i ,(images, labels) in enumerate(dataloader):
        test_loss=AverageMeter()
        test_top1=AverageMeter()
        test_top2=AverageMeter()
        for images, labels in tqdm(dataloader,ncols=80):
            images = images.cuda()
            labels = labels.cuda()
    
            # Forward pass
            outputs = self.model(images)
            #_, preds = torch.max(outputs.data,1)
            pred1_test,pred2_test=acc.accu(outputs,labels,topk=(1,2))
            loss = self.criterion(outputs, labels)
            test_loss.update(loss.item(),images.size(0))
            test_top1.update(pred1_test[0],images.size(0))
            test_top2.update(pred2_test[0],images.size(0))
            #tot_loss += loss.data
            #correct += torch.sum(preds == labels.data).to(torch.float32)
            """
            if (i+1) % 2 == 0:
                print('Epoch: [{}/{}], Step: [{}/{}], Loss: {:.4f}'
                      .format(1, 1, i+1, total_step, loss.item()))
            """          
        ### Epoch info ####
        #epoch_loss = tot_loss/len(dataloader.dataset)
        #epoch_acc = correct/len(dataloader.dataset) * 100
        #print('test loss: {:.4f},test acc: {:.4f}'.format(epoch_loss,epoch_acc))
        print(">>>[{}] test_loss:{:.4f} top1:{:.4f} top2:{:.4f}".format("test", test_loss.avg, test_top1.avg, test_top2.avg))
        t_loss = test_loss.avg,
        t_top1 = test_top1.avg
        t_top2 = test_top2.avg
        """
        with test_summary_writer.as_default():
          summary.scalar('loss', test_loss.avg, epoch)
          summary.scalar('accuracy', test_top1.avg, epoch)
        """
        """
        if epoch_acc > self.acc1:
          state = {  
          "model": self.model.state_dict(),
          "optimizer": self.optimizer.state_dict(),
          "epoch": epoch,
          "epoch_loss": test_loss.avg,
          "epoch_acc": test_top1.avg,
          }
          save_path="/content/drive/My Drive/colab notebooks/output/"
          print("在第{}个epoch取得最好的测试准确率,准确率为:{:.4f}".format(epoch,test_top1.avg))   
          torch.save(state,save_path+"/resnet18_best_v2"+".t7")
          self.acc1=max(self.acc1,test_top1.avg)
        """
        return t_loss,t_top1,t_top2
    
    class AverageMeter(object):
        def __init__(self):
            self.reset()
    
        def reset(self):
            self.val = 0
            self.avg = 0
            self.sum = 0
            self.count = 0
    
        def update(self, val, n=1):
            self.val = val
            self.sum += float(val) * n
            self.count += n
            self.avg = self.sum / self.count

    我们新建了一个AverageMeter类来存储结果。

    最终结果:

    下一节:加载预训练的模型并进行微调。

  • 相关阅读:
    【EntityFramework系列教程十,翻译】ASP.NET MVC程序中的一些高级应用
    对不含数据源的DataGridView实现自定义排序
    poj 1584 A Round Peg in a Ground Hole(叉积判断凸多边形)
    大整数运算
    poj 1408 Fishnet(计算几何)
    poj 1201 Intervals(第一道差分约束题)
    poj 2983 Is the Information Reliable?(差分约束)
    poj 2187 Beauty Contest(凸包+旋转卡壳)
    poj 2031 Building a Space Station(prim)
    poj 3007 Organize Your Train part II
  • 原文地址:https://www.cnblogs.com/xiximayou/p/12489069.html
Copyright © 2020-2023  润新知