DAY22:优化器(中)

开始比较各种优化器

  • 这边都先固定学习率0.01。
  1. SGD+momentum(学习率设置0.001时,训练出来每回合准确度都为0,於是改设置0.6)
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)
  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))
      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)
    
  • 学习曲线


  1. Adadelta

    学习率设置0.01时,训练很慢,连续10个epoch都为0,故将学习率调为0.8。

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

    这边我认为他的loss下降较慢,准确度还是有在缓缓上升,多练几个epoches可能会更好,但看似有点过拟和。


  1. Adagrad

    学习率设置为0.01。

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


  1. Adamax

    学习率设置0.02(预设)。

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



  1. ASGD

    学习率设置0.01(预设)。

    optimizer = torch.optim.ASGD(cnn.parameters(), lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0)
    
  • 学习曲线


    ASGD收敛较缓慢,设置了40个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)
    
  • 学习曲线


    可以发现这个优化器,准确度很震荡。


  1. Rprop

    全都照预设去设置。

    optimizer = torch.optim.Rprop(cnn.parameters(), lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06, 50))
    

    或许是这个优化器参数我不会调整,练出来准确度都是0,希望有大神可以教我。很抱歉这个优化器没能给大家带来示范。


  • SGD+momentum

  • Adam

  • Adadelta

  • Adagrad

  • Adamax

  • ASGD

  • RMSprop


表格比较

  • 可以看到test_score来看 Adam 和 Adagrad 的表现较佳。


今日小结

  • 每个优化器都各有好坏,碰上各种样本,都没有一定的优劣,建议多尝试,找出最好的优化器,建出最好的模型。

  • 今天比较的都是固定学习率,明天来搭配CosineAnnealing来训练看看,是否准确度会有所变化呢?


<<:  Day22 - [丰收款] 以Django Web框架实作永丰API线上支付模拟情境(3) - 两种付款方式实作

>>:  Day22 - 在 XState, 状态机器里无穷尽的状态、 资料:Extended State and context and assign API - 2

Day 17. slate × Immutable

接着我们要进入到 slate 的下一个重点章节: Immutability 。 虽然这已经算是一个...

初学者跪着学JavaScript Day6 :template literals和 tagged template literals傻傻分不清楚

一日客家话:黑黑的 念法:五无 之前只学过 template literals,tagged tem...

MLOps在金融产业:关於ML系统监控的why, what, how

我们常常听到,在一个ML专案当中,会需要做各种的资料监控。这些资料监控包含哪些呢? 开发流程 在开发...

计算资源及资料的设定02

建立了计算资源後,接下来要建立及处理有关资料的部分。 在Microsoft Azure Machin...

[想试试看JavaScript ] 运算子与自动转型

运算子 所谓的运算子就是就是一些符号,运算广义来说就是对资料做的任何动作。 平常生活中的加减乘除是一...