0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用NVIDIA DALI实现和使用GPU加速自动增强来训练

jf_pJlTbmA9 来源:NVIDIA 作者:NVIDIA 2023-07-05 16:30 次阅读

深度学习模型需要数百 GB 的数据才能在看不见的样本上很好地泛化。数据扩充有助于增加数据集中示例的可变性。

传统的数据扩充方法可以追溯到统计学习,当时扩充的选择依赖于建立模型训练的工程师的领域知识、技能和直觉。

自动增强出现了减少对手动数据预处理的依赖。它结合了应用自动调整和根据概率分布随机选择增强的思想。

事实证明,使用 AutoAugment 和 RandAugment 等自动数据增强方法可以通过使模型在训练中看到的样本多样化来提高模型的准确性。自动扩充使数据预处理更加复杂,因为一批中的每个样本都可以用不同的随机扩充进行处理。

在这篇文章中,我们介绍了如何使用 NVIDIA DALI 实现和使用 GPU 加速自动增强来训练,然后使用条件执行。

自动数据扩充方法

自动增强是基于标准的图像变换,如旋转、剪切、模糊或亮度调整。大多数操作都接受一个称为幅值的控制参数。幅度越大,操作对图像的影响就越大。

传统上,扩充策略是由工程师手工编写的固定操作序列。自动增强策略与传统策略的区别在于,增强和参数的选择不是固定的,而是概率的。

AutoAugment采用强化学习从数据中学习最佳概率增强策略,将目标模型的泛化视为奖励信号。使用 AutoAugment ,我们发现了图像数据集的新策略,例如ImageNet,CIFAR-10和SVHN,超过了最先进的精度。

AutoAugment 策略是一组增强对。每个增强都用应用或跳过操作的幅度和概率进行参数化。运行策略时,随机选择并应用其中一对,独立于每个样本。

学习策略意味着搜索最佳的增强对、它们的大小和概率。在策略搜索过程中,必须对目标模型进行多次再培训。这使得策略搜索的计算成本巨大。

为了避免计算成本高昂的搜索步骤,您可以重用在类似任务中找到的现有策略。或者,您可以使用其他自动数据扩充方法,这些方法旨在将搜索步骤保持在最低限度。

RandAugment将策略搜索步骤减少到只调整两个数字:N和M.N是要在序列中应用的随机选择的操作数,以及M是所有操作共享的大小。尽管 RandAugment 很简单,但我们发现,当与相同的增强集一起使用时,这种数据增强方法优于 AutoAugment 的策略。

TrivialAgument通过移除这两个超参数来构建 RandAugment 。我们建议对每个样本随机选择一个增量。 TrivialAugment 和 RandAugment 之间的区别在于,幅度不是固定的,而是随机均匀采样的。

结果表明,在训练过程中随机采样增强对于模型泛化可能比广泛搜索仔细调整的策略更重要。

从开始1.24 版本发布, DALI 提供了AutoAugment,RandAugment和TrivialAugment在这篇文章中,我们向您展示了如何使用所有这些最先进的实现,并讨论了 DALI 中新的条件执行功能,这是它们实现的支柱。

DALI 和有条件执行

现代 GPU 架构显著加快了深度学习模型训练。然而,为了实现最大的端到端性能,必须快速预处理模型消耗的数据批次,以避免 CPU 出现瓶颈。

NVIDIA DALI 通过异步执行、预取、专用加载程序、一组丰富的面向批处理的扩充以及与流行的 DL 框架(如PyTorch,TensorFlow,PaddlePaddle和MXNet.

为了创建一个数据处理管道,我们在 Python 函数中组合了所需的操作,并用@pipeline_def出于性能原因,该函数只定义 DALI 的执行计划,然后由 DALI 执行器异步运行。

下面的代码示例显示了一个管道定义,该定义加载、解码并将随机噪声增强应用于图像。

from nvidia.dali import pipeline_def, fn, types 
 
@pipeline_def(batch_size=8, num_threads=4, device_id=0) 
def pipeline(): 
    encoded, _ = fn.readers.file(file_root=data_path, random_shuffle=True) 
    image = fn.decoders.image(encoded, device="mixed") 
    prob = fn.random.uniform(range=[0, 0.15]) 
    distorted = fn.noise.salt_and_pepper(image, prob=prob) 
    return distorted 

管道的代码是面向样本的,而输出是一批图像。在指定运算符时不需要处理批处理,因为 DALI 在内部进行管理。

然而,到目前为止,还不可能表达对一批样本子集进行操作的操作。这阻止了使用 DALI 实现自动扩增,因为它为每个样本随机选择不同的操作。

DALI 中引入的条件执行使您能够使用正则 Python 语义为批处理中的每个样本选择单独的操作: if 语句。下面的代码示例随机应用两个增强中的一个。

@pipeline_def(batch_size=4, num_threads=4, device_id=0,
              enable_conditionals=True)
def pipeline():
    encoded, _ = fn.readers.file(file_root=data_path, random_shuffle=True)
    image = fn.decoders.image(encoded, device="mixed")
    change_stauration = fn.random.coin_flip(dtype=types.BOOL)
    if change_stauration:
        distorted = fn.saturation(image, saturation=2)
    else:
        edges = fn.laplacian(image, window_size=5)
        distorted = fn.cast_like(0.5 * image + 0.5 * edges, image)
    return distorted

我们增加了一些样本的饱和度,并在其他样本中使用拉普拉斯算子检测边缘,基于fn.random.coin_flip后果 DALI 翻译if-else语句转换为执行计划,该执行计划根据 if 条件将批处理拆分为两个批处理。通过这种方式,部分批次分别并行处理,而样本则属于同一批次if-else分支仍然受益于批处理的 CUDA 内核。

您可以很容易地扩展该示例,以使用从任意集合中随机选择的扩充。在下面的代码示例中,我们定义了三个扩充,并实现了一个选择运算符,该运算符根据随机选择的整数选择正确的一个。

def edges(image):
    edges = fn.laplacian(image, window_size=5)
    return fn.cast_like(0.5 * image + 0.5 * edges, image)

def rotation(image):
    angle = fn.random.uniform(range=[-45, 45])
    return fn.rotate(image, angle=angle, fill_value=0)

def salt_and_pepper(image):
    return fn.noise.salt_and_pepper(image, prob=0.15)


def select(image, operation_idx, operations, i=0):
    if i >= len(operations):
        return image
    if operation_idx == i:
        return operations[i](image)
    return select(image, operation_idx, operations, i + 1)

在下面的代码示例中,我们选择了一个随机整数,并在 DALI 管道内使用 select 运算符运行相应的操作。

@pipeline_def(batch_size=6, num_threads=4, device_id=0,
              enable_conditionals=True)
def pipeline():
    encoded, _ = fn.readers.file(file_root=data_path, random_shuffle=True)
    image = fn.decoders.image(encoded, device="mixed")
    operations = [edges, rotation, salt_and_pepper]
    operation_idx = fn.random.uniform(values=list(range(len(operations))))
    distorted = select(image, operation_idx, operations)
    return distorted

因此,我们得到了一批图像,其中每个图像都通过一个随机选择的操作进行变换:边缘检测、旋转和椒盐噪声失真。

DALI 自动增强

通过按样本选择运算符,您可以实现自动扩充。为了便于使用, NVIDIA 推出了auto_augDALI 中的模块,具有流行的自动增强的现成实现:auto_aug.auto_augment,auto_aug.rand_augment和auto_aug.trivial_augment它们可以开箱即用,也可以通过调整增强幅度或构建 DALI 基元的用户定义的增强来定制。

这个auto_aug.augmentationsDALI 中的模块提供由自动增强程序共享的默认操作集:

auto_contrast

brightness

color

contrast

equalize

invert

posterize

rotate

sharpness

shear_x

shear_y

solarize

solarize_add

translate_x

translate_y

下面的代码示例显示了如何运行 RandAugment 。

import nvidia.dali.auto_aug.rand_augment as ra

@pipeline_def(batch_size=6, num_threads=4, device_id=0,
              enable_conditionals=True)
def pipeline():
    encoded, _ = fn.readers.file(file_root=data_path, random_shuffle=True)
    shape = fn.peek_image_shape(encoded)
    image = fn.decoders.image(encoded, device="mixed")
    distorted = ra.rand_augment(image, n=3, m=15, shape=shape, fill_value=0)
    return distorted

这个rand_augment操作员接受解码后的图像、图像的形状、要在序列中应用的随机增强的数量 (n=3) 以及这些行动应该具有的规模 (m=15,在可定制的0, 30范围)。

在某些应用程序中,您可能必须限制已使用的扩充集。例如,如果数据集由数字图片组成,则将数字“ 9 ”旋转 180 度将使相关标签无效。运行以下代码示例rand_augment具有有限的增强集。

from nvidia.dali.auto_aug import augmentations as a

augmentations = [
    a.shear_x.augmentation((0, 0.3), randomly_negate=True),
    a.shear_y.augmentation((0, 0.3), randomly_negate=True),
    a.translate_x.augmentation((0, 0.45), randomly_negate=True),
    a.translate_y.augmentation((0, 0.45), randomly_negate=True),
    a.rotate.augmentation((0, 30), randomly_negate=True),
]

每个增强都可以通过幅度如何映射到变换强度来参数化。例如a.rotate.augmentation((0, 30))指定要将图像旋转不大于 30 度的角度。randomly_negate=True指定角度应随机取反,以便随机顺时针或逆时针旋转图像。

下面的代码示例以类似 RandAugment 的方式应用增强。

@pipeline_def(batch_size=8, num_threads=4, device_id=0,
              enable_conditionals=True)
def pipeline():
    encoded, _ = fn.readers.file(file_root=data_path, random_shuffle=True)
    shape = fn.peek_image_shape(encoded)
    image = fn.decoders.image(encoded, device="mixed")
    distorted = ra.apply_rand_augment(augmentations, image, n=3, m=15, shape=shape, fill_value=0)
    return distorted

前两个管道定义之间的唯一区别是使用了更通用的apply_rand_augment接受附加参数的运算符,即扩充列表。

接下来,将自定义扩充添加到集合中。使用cutout作为一个例子。它使用 DALI 用一个归零的矩形随机覆盖图像的一部分fn.erase作用包fn.erase与@augmentation描述如何将幅度映射到cutout矩形。cutout_size是从 0 . 01 到 0 . 4 范围的大小的元组,而不是普通大小。

from nvidia.dali.auto_aug.core import augmentation

def cutout_shape(size):
    # returns the shape of the rectangle
    return [size, size]

@augmentation(mag_range=(0.01, 0.4), mag_to_param=cutout_shape)
def cutout(image, cutout_size, fill_value=None):
    anchor = fn.random.uniform(range=[0, 1], shape=(2,))
    return fn.erase(image, anchor=anchor, shape=cutout_size, normalized=True, centered_anchor=True, fill_value=fill_value)

augmentations += [cutout]

对于更改,运行一组自定义的几何增强,如TrivialAugment,即具有随机幅度。对代码的更改是最小的;您导入并调用trivial_augment而不是rand_augment来自aut_aug单元

import nvidia.dali.auto_aug.trivial_augment as ta

@pipeline_def(batch_size=8, num_threads=4, device_id=0,
              enable_conditionals=True)
def pipeline():
    encoded, _ = fn.readers.file(file_root=data_path, random_shuffle=True)
    shape = fn.peek_image_shape(encoded)
    image = fn.decoders.image(encoded, device="mixed")
    distorted = ta.apply_trivial_augment(augmentations, image, shape=shape, fill_value=0)
    return distorted

DALI 的自动增强性能

现在,插上 DALI 和AutoAugment进入模型训练并比较吞吐量,使用EfficientNet-b0例如,改编自NIVDIA Deep Learning Examples.AutoAugment是 EfficientNet 系列模型预处理阶段的标准部分。

在链接的示例中AutoAugment策略使用 PyTorch 数据加载器实现,并在 CPU 上运行,而模型训练在 GPU 上进行。当 DALI 管道替换在 CPU 上运行的数据加载器时,吞吐量会增加。 EfficientNet 加 DALI 的源代码可在DALI examples.

该模型在自动混合精度模式( AMP )下运行,批量大小: DGX-1 V100 为 128 , DGX A100 为 256 。

我们用两种硬件设置进行了实验: DGX-1 V100 16 GB 和 DGX A100 。我们测量了每秒处理的图像数量(越多越好)。在这两种情况下,速度都有所提高: DGX-1 V100 的速度提高了 33% , DGX A100 的速度增加了 12% 。

图中虚线所示的理论吞吐量是通过单独改进数据预处理可以预期的训练速度的上限。为了测量理论极限,我们使用在每次迭代中重复的一批合成数据而不是真实数据进行训练。这让我们看到了在不需要预处理的情况下,模型处理批次的速度有多快。

合成情况和 CPU 数据加载器情况之间的显著性能差距表明存在预处理瓶颈。为了验证这一假设,请查看训练期间 GPU 的使用情况。

Figure-16-GPU-utilization-on-DGX-1-V100-16GB-increases-during-EfficientNet-b0-training-1.jpg 图 7 。在 EfficientNet-b0 培训期间, DGX-1V 16GB 的 GPU 利用率增加

(批量大小 128 ,具有 DALI 数据预处理的自动混合精度模式)

Figure-17-GPU-utilization-on-DGX-A100-increases-during-EfficientNet-b0-training-.jpg 图 8 。在 EfficientNet-b0 培训期间, DGX-A100 的 GPU 利用率增加

(批量大小 256 ,自动混合精度模式,带 DALI 数据预处理)

这些图显示了在给定的 GPU 利用率下我们花费了多少时间。您可以看到,当使用在 CPU 上运行的数据加载器对数据进行预处理时, GPU 的利用率会反复下降。值得注意的是,在大约 5% 的时间里,利用率下降到 10% 以下。这表明训练定期停滞,等待下一批数据从数据加载程序到达。

如果您将加载和自动增强步骤移动到带有 DALI 的 GPU0, 10条消失,并且整体 GPU 利用率增加。图 6 中显示的使用 DALI 的训练吞吐量的增加证实了我们成功地克服了之前的预处理瓶颈。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • NVIDIA
    +关注

    关注

    14

    文章

    4940

    浏览量

    102815
  • 人工智能
    +关注

    关注

    1791

    文章

    46859

    浏览量

    237567
  • 深度学习
    +关注

    关注

    73

    文章

    5492

    浏览量

    120977
收藏 人收藏

    评论

    相关推荐

    NVIDIA火热招聘GPU高性能计算架构师

    GPU架构设计者提供反馈,以改善和推进未来GPU的架构设计基本要求(其一即可): * 严谨的逻辑思维和分析能力* 有CUDA代码调优经验(或者SIMD等架构的调优经验)* 熟悉矩阵计算的优化和加速* 较强C++编程能力、算法分析
    发表于 09-01 17:22

    NVIDIA-SMI:监控GPU的绝佳起点

    nvidia-smi可执行文件位于虚拟机管理程序上。如果在同一部署中您选择在GPU上使用作为传递,那么GPU正在寻找访客上的NVIDIA驱动程序,因此
    发表于 09-04 15:18

    GPU加速XenApp/Windows 2016/Office/IE性能会提高吗

    Shark查看哪些程序/进程使用GPU(硬件加速)。它看起来不像Internet Explorer 11或Office 2016根本不使用GPU。我已经验证IE和Office都启用
    发表于 09-12 16:24

    购买哪款Nvidia GPU

    Nvidia的NV 24核,224 GB RAM,1.4 GB临时存储。这是相当昂贵的(每月费用超过3,400美元),除非我承诺1年或3年的承诺,略有减少。我认为如果我购买GPU服务器,从长远来看可能会更便
    发表于 09-26 15:30

    Nvidia GPU风扇和电源显示ERR怎么解决

    问题最近在Ubuntu上使用Nvidia GPU训练模型的时候,如果机器锁屏一段时间再打开的时候鼠标非常卡顿,或者说显示界面非常卡顿,使用nvidia-smi查看发现,
    发表于 12-30 06:44

    在Ubuntu上使用Nvidia GPU训练模型

    问题最近在Ubuntu上使用Nvidia GPU训练模型的时候,没有问题,过一会再训练出现非常卡顿,使用nvidia-smi查看发现,显示
    发表于 01-03 08:24

    MathWorks 增加对 NVIDIA GPU Cloud (NGC) 和 DGX 系统的支持

    和工作站上的 NVIDIA GPU,应用 MATLAB 中的深度学习工作流程。 构建 AI 解决方案的研发人员需要访问云和 HPC 资源,最大限度地缩短训练时间。利用来自 NGC 的 GPU
    发表于 11-01 00:22 409次阅读

    混合精度训练的优势!将自动混合精度用于主流深度学习框架

    仅通过添加几行代码,TensorFlow、PyTorch和MXNet中的自动混合精确功能就能助力深度学习研究人员和工程师基于NVIDIA Volta和Turing GPU实现高达3倍的
    的头像 发表于 04-03 11:31 7009次阅读

    NVIDIA GPU加速计算之路

    NVIDIA从提出GPU以及CUDA核心开始,NVIDIA便开始逐步迈出游戏圈,不断向全新的计算领域发起攻势。时至今日,NVIDIA GPU
    的头像 发表于 12-23 09:12 7298次阅读

    Nvidia GPU风扇和电源显示ERR!

    问题最近在Ubuntu上使用Nvidia GPU训练模型的时候,没有问题,过一会再训练出现非常卡顿,使用nvidia-smi查看发现,显示
    发表于 01-12 12:25 0次下载
    <b class='flag-5'>Nvidia</b> <b class='flag-5'>GPU</b>风扇和电源显示ERR!

    NVIDIA GPU加快深度神经网络训练和推断

    深度学习是推动当前人工智能大趋势的关键技术。在 MATLAB 中可以实现深度学习的数据准备、网络设计、训练和部署全流程开发和应用。联合高性能 NVIDIA GPU 加快深度神经网络
    的头像 发表于 02-18 13:31 2015次阅读

    NVIDIA DALI概述及主要特性

    NVIDIA 数据加载库(DALI)是一个可移植的开源库,专用于解码及增强图像、视频和语音,从而加速深度学习应用。
    的头像 发表于 08-03 10:20 2638次阅读

    NVIDIA GPU加速潞晨科技Colossal-AI大模型开发进程

    通过 NVIDIA GPU 加速平台,Colossal-AI 实现了通过高效多维并行、异构内存管理、大规模优化库、自适应任务调度等方式,更高效快速部署 AI 大模型
    的头像 发表于 10-19 09:39 1431次阅读

    Oracle 云基础设施提供新的 NVIDIA GPU 加速计算实例

    生成式 AI 和大语言模型(LLM)不断推动突破性创新,训练和推理对算力的需求也随之急剧上升。 这些现代生成式 AI 应用需要全栈加速计算,首先要有能够快速、准确处理大量工作负载的先进基础设施
    的头像 发表于 09-25 20:40 531次阅读
    Oracle 云基础设施提供新的 <b class='flag-5'>NVIDIA</b> <b class='flag-5'>GPU</b> <b class='flag-5'>加速</b>计算实例

    PyTorch GPU 加速训练模型方法

    在深度学习领域,GPU加速训练模型已经成为提高训练效率和缩短训练时间的重要手段。PyTorch作为一个流行的深度学习框架,提供了丰富的工具和
    的头像 发表于 11-05 17:43 446次阅读