DAY23:优化器(下)

开始比较各种优化器

  • 这边都采用变动学习率CosineAnnealing。示范我这边T_max只用6。

    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=6, eta_min=0, last_epoch=-1)
    
  1. SGD+momentum
batch_size = 50
base_lr = 0.6
max_epoch = 20
model_path = './tttdensenet.pth'
# 将图片转为tensor
  transforms = Compose([ToTensor()])
  train_dataset = CaptchaData('./pic_train2',        './answer/answer_train_v2.csv',transform=transforms)
                              
# dataloader读取batchsize资料
  train_data_loader = DataLoader(train_dataset, batch_size=batch_size, num_workers=0,shuffle=True, drop_last=True)
  test_data = CaptchaData('./pic_test2','./answer/answer_test_v2.csv',transform=transforms)
  test_data_loader = DataLoader(test_data, batch_size=batch_size,num_workers=0, shuffle=True, drop_last=True)
                                
  # 读取预训练模型densenet201
  cnn = models.densenet201(num_classes=180)
  if torch.cuda.is_available():
      cnn.cuda()
  if restor:
      cnn.load_state_dict(torch.load(model_path))
  # 采用SGD + momentum当优化器
  optimizer = torch.optim.SGD(cnn.parameters(), lr=base_lr, momentum=0.9)
  scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=6, eta_min=0, last_epoch=-1)
  criterion = nn.MultiLabelSoftMarginLoss()
  acc_history_train = []
  loss_history_train = []
  loss_history_test = []
  acc_history_test = []
  for epoch in range(max_epoch):
      start_ = time.time()
      loss_history = []
      acc_history = []

      cnn.train()

      for img, target in train_data_loader:
          img = Variable(img)
          target = Variable(target)
          if torch.cuda.is_available():
              img = img.cuda()
              target = target.cuda()
          output = cnn(img)
          loss = criterion(output, target)
          optimizer.zero_grad()
          loss.backward()
          optimizer.step()

          acc = calculat_acc(output, target)
          acc_history.append(float(acc))
          loss_history.append(float(loss))
      
      # 要加上这段scheduler.step()
      scheduler.step()
      print('train_loss: {:.4}|train_acc: {:.4}'.format(
          torch.mean(torch.Tensor(loss_history)),
          torch.mean(torch.Tensor(acc_history)),
      ))
      acc_history_train.append((torch.mean(torch.Tensor(acc_history))).float())
      loss_history_train.append((torch.mean(torch.Tensor(loss_history))).float())

      loss_history = []
      acc_history = []
      cnn.eval()
      for img, target in test_data_loader:
          img = Variable(img)
          target = Variable(target)
          if torch.cuda.is_available():
              img = img.cuda()
              target = target.cuda()
          output = cnn(img)

          acc = calculat_acc(output, target)
          acc_history.append(float(acc))
          loss_history.append(float(loss))
      print('test_loss: {:.4}|test_acc: {:.4}'.format(
          torch.mean(torch.Tensor(loss_history)),
          torch.mean(torch.Tensor(acc_history)),
      ))
      acc_history_test.append((torch.mean(torch.Tensor(acc_history))).float())
      loss_history_test.append((torch.mean(torch.Tensor(loss_history))).float())

      print('epoch: {}|time: {:.4f}'.format(epoch, time.time() - start_))
      print("========================================")
      torch.save(cnn.state_dict(), model_path)


  # 画出acc学习曲线
  acc = acc_history_train
  epoches = range(1, len(acc) + 1)
  val_acc = acc_history_test
  plt.plot(epoches, acc, 'b', label='Training acc')
  plt.plot(epoches, val_acc, 'r', label='Validation acc')
  plt.title('Training and validation accuracy')
  plt.legend(loc='lower right')
  plt.grid()
  # 储存acc学习曲线
  plt.savefig('./acc.png')
  plt.show()

  # 画出loss学习曲线
  loss = loss_history_train
  val_loss = loss_history_test
  plt.plot(epoches, loss, 'b', label='Training loss')
  plt.plot(epoches, val_loss, 'r', label='Validation loss')
  plt.title('Training and validation loss')
  plt.legend(loc='upper right')
  plt.grid()
  # 储存loss学习曲线
  plt.savefig('loss.png')
  plt.show()
  
  • 学习曲线


  1. Adam

    只有将优化器改为Adam,其余都一样。

    # 需要修改的只有这个code,将optimizer改成Adam就好。
    optimizer = torch.optim.Adam(cnn.parameters(), lr=base_lr)
    
  • 学习曲线

  • 搭配CosineAnnealing之後,准确度稍微提升。


  1. Adadelta

    optimizer = torch.optim.Adadelta( cnn.parameters(),lr=base_lr, rho=0.9, eps=1e-06, weight_decay=0)
    
  • 学习曲线

     

  • 原本用固定学习率时收敛就较慢,搭配cosineAnnealing显得收敛更慢,建议可以用学习率衰减的方式,另外就是因为节省时间,这边都只有练20或40个epoches,当练多一点时,可以将T_max调整大一点,相信准确度和收敛状况会提升较多。


  1. Adagrad

    optimizer = torch.optim.Adagrad(cnn.parameters(), lr=0.01, lr_decay=0, weight_decay=0)
    
  • 学习曲线

  • 准确率有较固定学习率还低一点。但因这是示范而已,正常应该多跑几个epoches且多尝试初始学习率和参数,都会有所帮助。


  1. Adamax

    optimizer = torch.optim.Adamax(cnn.parameters(), lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)
    
  • 学习曲线


  1. ASGD
  • 学习率设置0.01(预设)时,加入CosineAnnealing训练不出来,效果很差。於是将学习率设置0.8。
optimizer = torch.optim.ASGD(cnn.parameters(), lr=0.8, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0)
  • 学习曲线

  • 可以发现ASGD收敛原本就较缓慢,这次设置了60个epoches,loss值下降更缓慢,并没有比固定学习率效果来的好。可以试试看学习率衰减来更新,而不是用循环的学习率更新方式。


  1. RMSprop

    全都照预设去设置。

    optimizer = torch.optim.RMSprop(cnn.parameters(), lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
    
  • 学习曲线

  

可以发现这个优化器,准确度很震荡,但搭配後训练出一个不错的准确度。

  • SGD+momentum

  • Adam

  • Adadelta

  • Adagrad

  • Adamax

  • ASGD

  • RMSprop


表格比较

  • 可以看到test_score来看 Adam 和 Adamax 及 RMSprop 的表现有比固定学习率再更好一些,尤其是RMSprop,建议都可以多尝试,说不定有更好的参数和epoch可以让整个模型准确度提高。


今日小结

  • 搭配CosineAnnealing(余弦退火)的更新学习率後,有些反而提升准确度,有些反而下降,建议可以多尝试,小弟我本身在做玉山比赛的话是用SGD+momentum搭配CosineAnnealing,效果还不错。

  • 优化器和学习率更新,搭配不同的资料集时,可能会有不同的效果,多尝试,会练出属於自己最好的模型。


<<:  30天打造品牌特色电商网站 Day.23 关於position定位

>>:  DAY23 - 将作品发布出去吧 - 後端篇 (heroku)

彻底卸载 Mac 应用程序

并不是所有的都是常用的应用程序,而且多数情况下都是下载了 App 之後却没怎麽使用。渐渐地,这些应用...

15【雷坑】千万别肖想用 APCS 升大学

事实上一现在的情况来看,若是要用 APCS 成绩当作升大学的跳板是完全不建议的,理由如下: 高手独占...

威胁建模(threat modeling)的步骤

-威胁建模(来源:CSSLP CBK) 根据CSSLP CBK,可以通过以下方式进行威胁建模: 1...

.Net Core Web Api_笔记01

.net core web api 可以和任何前端Client端技术或框架(javascript ,...

重要性分析和业务影响分析(criticality analysis and Business impact analysis (BIA))

-重要性分析和业务影响分析 业务影响分析(BIA)是业务连续性管理的关键过程。它分析了中断对关键活...