宝宝计划

让建站和SEO变得简单

让不懂建站的用户快速建站,让会建站的提高建站效率!

PyTorch | 优化神经收罗老成的十七种关节

发布日期:2022-03-13 19:54    点击次数:59

 本文先容在使用 PyTorch 老成深度模子时最省力、最灵验的 17 种关节。该文所提关节,都是假定你在 GPU 环境下老成模子。具体现实如下。

01. 讨论换一种学习率 schedule

学习率 schedule 的接管对模子的敛迹速率和泛化才智有很大的影响。Leslie N. Smith 等人在论文《Cyclical Learning Rates for Training Neural Networks》、《Super-Convergence: Very Fast Training of Neural Networks Using Large Learning Rates 》中提倡了周期性(Cyclical)学习率以及 1Cycle 学习率 schedule。之后,fast.ai 的 Jeremy Howard 和 Sylvain Gugger 对其进行了延迟。下图是 1Cycle 学习率 schedule 的图示:

Sylvain 写到:1Cycle 包括两个等长的步幅,一个步幅是从较低的学习率到较高的学习率,另一个是回到最低水平。最大值来自学习率查找器登科的值,较小的值不错低十倍。然后,这个周期的长度应该略小于总的 epochs 数,况且,在老成的临了阶段,咱们应该允许学习率比最小值小几个数目级。

与传统的学习率 schedule 比较,在最佳的情况下,该 schedule 杀青了高大的加速(Smith 称之为超等敛迹)。举例,使用 1Cycle 战术在 ImageNet 数据集上老成 ResNet-56,老成迭代次数减少为底本的 1/10,但模子性能仍能并排原论文中的水平。在常见的体系架构和优化器中,这种 schedule 似乎领路得很好。

Pytorch 一经杀青了这两种关节:「torch.optim.lr_scheduler.CyclicLR」和「torch.optim.lr_scheduler.OneCycleLR」。

参考文档:https://pytorch.org/docs/stable/optim.html

02. 在 DataLoader 中使用多个 worker 和页锁定内存

当使用 torch.utils.data.DataLoader 时,建造 num_workers > 0,而不是默许值 0,同期建造 pin_memory=True,而不是默许值 False。

参考文档:https://pytorch.org/docs/stable/data.html

来自 NVIDIA 的高档 CUDA 深度学习算法软件工程师 Szymon Micacz 就曾使用四个 worker 和页锁定内存(pinned memory)在单个 epoch 中杀青了 2 倍的加速。人们接管 worker 数目的教会章程是将其建造为可用 GPU 数目的四倍,大于或小于这个数都会缩小老成速率。请恰当,加多 num_workers 将加多 CPU 内存糟践。

03. 把 batch 调到最大

把 batch 调到最大是一个颇有争议的视力。一般来说,如果在 GPU 内存允许的领域内将 batch 调到最大,你的老成速率会更快。但是,你也必须诊治其他超参数,比如学习率。一个比较好用的教会是,batch 大小加倍时,学习率也要加倍。

OpenAI 的论文《An Empirical Model of Large-Batch Training》很好地论证了不同的 batch 大小需要若干步才能敛迹。在《How to get 4x speedup and better generalization using the right batch size》一文中,作家 Daniel Huynh 使用不同的 batch 大小进行了一些实验(也使用上头究诘的 1Cycle 战术)。最终,他将 batch 大小由 64 加多到 512,杀青了 4 倍的加速。

关联词,使用大 batch 的不及是,这可能导致惩办决策的泛化才智比使用小 batch 的差。

04. 使用自动夹杂精度(AMP)

PyTorch 1.6 版块包括对 PyTorch 的自动夹杂精度老成的腹地杀青。这里想说的是,与单精度 (FP32) 比较,某些运算在半精度 (FP16) 下运行更快,而不会耗费准确率。AMP 会自动决定应该以哪种精度延迟哪种运算。这么既不错加速老成速率,又不错减少内存占用。

在最佳的情况下,AMP 的使用情况如下: 

import torch  # Creates once at the beginning of training  scaler = torch.cuda.amp.GradScaler()  for data, label in data_iter:     optimizer.zero_grad()     # Casts operations to mixed precision     with torch.cuda.amp.autocast():        loss = model(data)     # Scales the loss, and calls backward()     # to create scaled gradients     scaler.scale(loss).backward()     # Unscales gradients and calls     # or skips optimizer.step()     scaler.step(optimizer)     # Updates the scale for next iteration     scaler.update() 
05. 讨论使用另一种优化器

AdamW 是由 fast.ai 延迟的一种具有权重衰减(而不是 L2 正则化)的 Adam,在 PyTorch 中以 torch.optim.AdamW 杀青。AdamW 似乎在舛错和老成技巧上都一直优于 Adam。

Adam 和 AdamW 都能与上头提到的 1Cycle 战术很好地搭配。

现在,还有一些非腹地优化器也引起了很大的关怀,最凸起的是 LARS 和 LAMB。NVIDA 的 APEX 杀青了一些常见优化器的交融版块,比如 Adam。与 PyTorch 中的 Adam 杀青比较,这种杀青幸免了与 GPU 内存之间的屡次传递,速率擢升了 5%。

06. cudNN 基准

如果你的模子架构保持不变、输入大小保持不变,建造 torch.backends.cudnn.benchmark = True。

07. 贯注 CPU 和 GPU 之间频频的数据传输

当频频地使用 tensor.cpu() 将张量从 GPU 转到 CPU(或使用 tensor.cuda() 将张量从 CPU 转到 GPU)时,代价长短常腾贵的。item() 和 .numpy() 亦然相同不错使用. detach() 代替。

如果你创建了一个新的张量,不错使用裂缝字参数 device=torch.device( cuda:0 ) 将其分派给 GPU。

如果你需要传输数据,不错使用. to(non_blocking=True),唯有在传输之后莫得同步点。

08. 使用梯度 / 激活 checkpointing

Checkpointing 的责任旨趣是用狡计换内存,并不存储通盘狡计图的系数中间激活用于 backward pass,而是重新狡计这些激活。咱们不错将其应用于模子的任何部分。

具体来说,在 forward pass 中,function 会以 torch.no_grad() 形势运行,不存储中间激活。相背的是, forward pass 中会保存输入元组以及 function 参数。在 backward pass 中,输入和 function 会被检索,并再次在 function 上狡计 forward pass。然后追踪中间激活,使用这些激活值狡计梯度。

因此,固然这可能会稍微加多给定 batch 大小的运行技巧,但会显耀减少内存占用。这反过来又将允许进一步加多所使用的 batch 大小,从而擢升 GPU 的欺骗率。

尽管 checkpointing 以 torch.utils.checkpoint 形势杀青,但仍需要一些思考和致力于来正确地杀青。Priya Goyal 写了一个很好的教程来先容 checkpointing 裂缝方面。

Priya Goyal 教程地址:

https://github.com/prigoyal/pytorch_memonger/blob/master/tutorial/Checkpointing_for_PyTorch_models.ipynb

09. 使用梯度积聚

加多 batch 大小的另一种关节是在调用 optimizer.step() 之前在多个. backward() 传递中累积梯度。

Hugging Face 的 Thomas Wolf 的著述《Training Neural Nets on Larger Batches: Practical Tips for 1-GPU, Multi-GPU & Distributed setups》先容了怎样使用梯度累积。梯度累积不错通过如下形势杀青: 

model.zero_grad()                                   # Reset gradients tensors  for i, (inputs, labels) in enumerate(training_set):     predictions = model(inputs)                     # Forward pass      loss = loss_function(predictions, labels)       # Compute loss function      lossloss = loss / accumulation_steps                # Normalize our loss (if averaged)      loss.backward()                                 # Backward pass      if (i+1) % accumulation_steps == 0:             # Wait for several backward steps          optimizer.step()                            # Now we can do an optimizer step          model.zero_grad()                           # Reset gradients tensors          if (i+1) % evaluation_steps == 0:           # Evaluate the model when we...              evaluate_model()                        # ...have no gradients accumulate 

这个关节主如果为了遁入 GPU 内存的截止而设备的。

10. 使用散布式数据并行进行多 GPU 老成

加速散布式老成可能有许多关节,但是浅陋的关节是使用 torch.nn.DistributedDataParallel 而不是 torch.nn.DataParallel。这么一来,每个 GPU 将由一个专用的 CPU 中枢驱动,幸免了 DataParallel 的 GIL 问题。

散布式老成文档地址:https://pytorch.org/tutorials/beginner/dist_overview.html

11. 建造梯度为 None 而不是 0

梯度建造为. zero_grad(set_to_none=True) 而不是 .zero_grad()。这么做不错让内存分派器处理梯度,而不是将它们建造为 0。正如文档中所说,将梯度建造为 None 会产生限度的加速,但不要期待遗迹出现。恰当,这么做也有弱点,详敬佩息请检讨文档。

文档地址:https://pytorch.org/docs/stable/optim.html

12. 使用. as_tensor() 而不是. tensor()

torch.tensor() 老是会复制数据。如果你要调理一个 numpy 数组,使用 torch.as_tensor() 或 torch.from_numpy() 来幸免复制数据。

13. 必要时掀开调试器用

PyTorch 提供了许多调试器用,举例 autograd.profiler、autograd.grad_check、autograd.anomaly_detection。请确保当你需要调试时再掀开调试器,不需要时要实时关掉,因为调试器会缩小你的老成速率。

14. 使用梯度剪辑

对于幸免 RNN 中的梯度爆炸的问题,一经有一些实验和表面阐发,梯度剪辑(gradient = min(gradient, threshold))不错加速敛迹。HuggingFace 的 Transformer 杀青便是一个相配明晰的例子,讲明了怎样使用梯度剪辑。本文中提到的其他一些关节,如 AMP 也不错用。

在 PyTorch 中不错使用 torch.nn.utils.clip_grad_norm_来杀青。

15. 在 BatchNorm 之前关闭 bias

在驱动 BatchNormalization 层之前关闭 bias 层。对于一个 2-D 卷积层,不错将 bias 裂缝字建造为 False:torch.nn.Conv2d(..., bias=False, ...)。

16. 在考证技巧关闭梯度狡计

在考证技巧关闭梯度狡计,建造:torch.no_grad() 。

17. 使用输入和 batch 归一化

要再三查验一下输入是否归一化?是否使用了 batch 归一化? 

 



 




Powered by 宝宝计划 @2013-2022 RSS地图 HTML地图

Copyright 365建站 © 2013-2021 365建站器 版权所有