使用 Pytorch API 和 Fast-ai 进行分类的训练结果不同
Training results are different for Classification using Pytorch APIs and Fast-ai
我有两个训练 python 脚本。一个使用 Pytorch 的 API 进行分类训练,另一个使用 Fast-ai。
使用 Fast-ai 有更好的结果。
培训成果如下
Fastai
epoch train_loss valid_loss accuracy time
0 0.205338 2.318084 0.466482 23:02
1 0.182328 0.041315 0.993334 22:51
2 0.112462 0.064061 0.988932 22:47
3 0.052034 0.044727 0.986920 22:45
4 0.178388 0.081247 0.980883 22:45
5 0.009298 0.011817 0.996730 22:44
6 0.004008 0.003211 0.999748 22:43
Using Pytorch
Epoch [1/10], train_loss : 31.0000 , val_loss : 1.6594, accuracy: 0.3568
Epoch [2/10], train_loss : 7.0000 , val_loss : 1.7065, accuracy: 0.3723
Epoch [3/10], train_loss : 4.0000 , val_loss : 1.6878, accuracy: 0.3889
Epoch [4/10], train_loss : 3.0000 , val_loss : 1.7054, accuracy: 0.4066
Epoch [5/10], train_loss : 2.0000 , val_loss : 1.7154, accuracy: 0.4106
Epoch [6/10], train_loss : 2.0000 , val_loss : 1.7232, accuracy: 0.4144
Epoch [7/10], train_loss : 2.0000 , val_loss : 1.7125, accuracy: 0.4295
Epoch [8/10], train_loss : 1.0000 , val_loss : 1.7372, accuracy: 0.4343
Epoch [9/10], train_loss : 1.0000 , val_loss : 1.6871, accuracy: 0.4441
Epoch [10/10], train_loss : 1.0000 , val_loss : 1.7384, accuracy: 0.4552
使用Pytorch 不收敛。
我使用了相同的网络 (Wideresnet22),两者都是在没有预训练模型的情况下从头开始训练的。
网络为here。
使用 Pytorch 的训练是 here。
Fastai使用方法如下
from fastai.basic_data import DataBunch
from fastai.train import Learner
from fastai.metrics import accuracy
#DataBunch takes data and internall create data loader
data = DataBunch.create(train_ds, valid_ds, bs=batch_size, path='./data')
#Learner uses Adam as default for learning
learner = Learner(data, model, loss_func=F.cross_entropy, metrics=[accuracy])
#Gradient is clipped
learner.clip = 0.1
#learner finds its learning rate
learner.lr_find()
learner.recorder.plot()
#Weight decay helps to lower down weight. Learn in https://towardsdatascience.com/
learner.fit_one_cycle(5, 5e-3, wd=1e-4)
我使用 Pytorch 的训练算法可能有什么问题?
fastai
在后台使用了很多技巧。快速了解他们在做什么而你没有。
这些是我认为最重要的顺序,尤其是前两个应该会提高你的分数。
TLDR
使用一些调度程序(最好是torch.optim.lr_scheduler.CyclicLR)和AdamW
而不是SGD
。
更长的版本
fit_one_cycle
Leslie Smith 的 1 周期政策被用于 fastai
。在 PyTorch 中,可以使用 torch.optim.lr_scheduler.CyclicLR 创建类似的例程,但这需要一些手动设置。
基本上它从较低的学习率开始,逐渐增加到 5e-3
,然后再次回到较低的学习率(形成一个循环)。您可以调整 lr
应该如何上升和下降(在 fastai
中它使用余弦退火 IIRC 这样做)。
一开始你的学习率太高了,应该有调度器帮忙,先测试一下。
优化器
在提供的代码片段中,您使用 torch.optim.SGD
(因为 optim_fn
是 None
并且设置了默认值)这更难正确设置(通常)。
另一方面,如果您设法正确手动设置它,您可能会更好地概括。
还有fastai
默认不使用Adam
!它使用AdamW
if true_wd
is set (I think, it will be default in your case anyway, see source code). AdamW
decouples weight decay from adaptive learning rate which should improve convergence (read here or original paper
纪元数
如果您想比较这两种方法,请设置相同的轮数,目前是苹果对橘子。
渐变剪裁
你没有剪裁渐变(它被注释掉了),这取决于任务是否有用。暂时不会关注那个。
其他技巧
阅读 Learner and fit_one_cycle 并尝试在 PyTorch 中设置类似的东西(上述粗略指南)
您也可以使用某种形式的数据增强来进一步提高分数,但我认为这超出了问题的范围。
我有两个训练 python 脚本。一个使用 Pytorch 的 API 进行分类训练,另一个使用 Fast-ai。 使用 Fast-ai 有更好的结果。
培训成果如下
Fastai
epoch train_loss valid_loss accuracy time
0 0.205338 2.318084 0.466482 23:02
1 0.182328 0.041315 0.993334 22:51
2 0.112462 0.064061 0.988932 22:47
3 0.052034 0.044727 0.986920 22:45
4 0.178388 0.081247 0.980883 22:45
5 0.009298 0.011817 0.996730 22:44
6 0.004008 0.003211 0.999748 22:43
Using Pytorch
Epoch [1/10], train_loss : 31.0000 , val_loss : 1.6594, accuracy: 0.3568
Epoch [2/10], train_loss : 7.0000 , val_loss : 1.7065, accuracy: 0.3723
Epoch [3/10], train_loss : 4.0000 , val_loss : 1.6878, accuracy: 0.3889
Epoch [4/10], train_loss : 3.0000 , val_loss : 1.7054, accuracy: 0.4066
Epoch [5/10], train_loss : 2.0000 , val_loss : 1.7154, accuracy: 0.4106
Epoch [6/10], train_loss : 2.0000 , val_loss : 1.7232, accuracy: 0.4144
Epoch [7/10], train_loss : 2.0000 , val_loss : 1.7125, accuracy: 0.4295
Epoch [8/10], train_loss : 1.0000 , val_loss : 1.7372, accuracy: 0.4343
Epoch [9/10], train_loss : 1.0000 , val_loss : 1.6871, accuracy: 0.4441
Epoch [10/10], train_loss : 1.0000 , val_loss : 1.7384, accuracy: 0.4552
使用Pytorch 不收敛。 我使用了相同的网络 (Wideresnet22),两者都是在没有预训练模型的情况下从头开始训练的。
网络为here。
使用 Pytorch 的训练是 here。
Fastai使用方法如下
from fastai.basic_data import DataBunch
from fastai.train import Learner
from fastai.metrics import accuracy
#DataBunch takes data and internall create data loader
data = DataBunch.create(train_ds, valid_ds, bs=batch_size, path='./data')
#Learner uses Adam as default for learning
learner = Learner(data, model, loss_func=F.cross_entropy, metrics=[accuracy])
#Gradient is clipped
learner.clip = 0.1
#learner finds its learning rate
learner.lr_find()
learner.recorder.plot()
#Weight decay helps to lower down weight. Learn in https://towardsdatascience.com/
learner.fit_one_cycle(5, 5e-3, wd=1e-4)
我使用 Pytorch 的训练算法可能有什么问题?
fastai
在后台使用了很多技巧。快速了解他们在做什么而你没有。
这些是我认为最重要的顺序,尤其是前两个应该会提高你的分数。
TLDR
使用一些调度程序(最好是torch.optim.lr_scheduler.CyclicLR)和AdamW
而不是SGD
。
更长的版本
fit_one_cycle
Leslie Smith 的 1 周期政策被用于 fastai
。在 PyTorch 中,可以使用 torch.optim.lr_scheduler.CyclicLR 创建类似的例程,但这需要一些手动设置。
基本上它从较低的学习率开始,逐渐增加到 5e-3
,然后再次回到较低的学习率(形成一个循环)。您可以调整 lr
应该如何上升和下降(在 fastai
中它使用余弦退火 IIRC 这样做)。
一开始你的学习率太高了,应该有调度器帮忙,先测试一下。
优化器
在提供的代码片段中,您使用 torch.optim.SGD
(因为 optim_fn
是 None
并且设置了默认值)这更难正确设置(通常)。
另一方面,如果您设法正确手动设置它,您可能会更好地概括。
还有fastai
默认不使用Adam
!它使用AdamW
if true_wd
is set (I think, it will be default in your case anyway, see source code). AdamW
decouples weight decay from adaptive learning rate which should improve convergence (read here or original paper
纪元数
如果您想比较这两种方法,请设置相同的轮数,目前是苹果对橘子。
渐变剪裁
你没有剪裁渐变(它被注释掉了),这取决于任务是否有用。暂时不会关注那个。
其他技巧
阅读 Learner and fit_one_cycle 并尝试在 PyTorch 中设置类似的东西(上述粗略指南)
您也可以使用某种形式的数据增强来进一步提高分数,但我认为这超出了问题的范围。