作者:
(1) Iason Ofeidis,耶鲁大学电气工程系、耶鲁网络科学研究所,纽黑文{同等贡献};
(2)Diego Kiedanski,耶鲁大学电气工程系、耶鲁网络科学研究所,纽黑文{同等贡献};
(3) Leandros TassiulasLevon Ghukasyan,Activeloop,美国加利福尼亚州山景城,电气工程系,耶鲁大学网络科学研究所,纽黑文。
在训练深度学习模型的过程中,需要从内存中读取数据集并进行预处理,然后才能将其作为输入传递给模型。此操作需要将数据一次性加载到内存中。在大多数情况下,尤其是对于大型数据集,由于系统中可用的内存量有限,会出现内存短缺,这也会降低系统的响应时间。深度学习库中通常使用所谓的数据加载器来解决此瓶颈。此结构提供了一种通过利用并行处理、预取、批处理和其他技术来迭代数据集的方法,以尽可能减少数据加载时间和内存开销(Paszke 等人,2019 年)。
数据加载器的主要目标是执行将数据样本从存储位置传输到与处理单元共置的内存以进行训练的操作,以形成一批样本输入到模型中。这些操作受到存储系统带宽和 I/O 性能的限制。因此,根据系统的硬件规格、为其服务的文件系统以及与计算单元的链接吞吐量,它可能对完成训练所需的总时间产生巨大影响。
以下数据加载器组件的规范主要针对 PyTorch(torch.DataLoader()(PyTorch 核心团队)),而其 TensorFlow 对应组件(tf.Dataset()(Abadi 等,2015))虽然不相同,但却具有很大的相似性。
使用数据加载器时,除了提供数据集作为输入外,用户还可以选择配置多个超参数,以满足他们的需求和资源。所有数据加载器中都提供的一个通用参数是批处理大小,如前所述,批处理大小定义了在更新内部模型参数之前将使用的样本数量。此参数与随机梯度下降中的“小批量”概念有着内在联系(Hinton 等人,2012 年),因此,当需要获得更好的训练结果时,它是通常要进行微调的首批参数之一。
其次,用户可以定义采样方法,该方法决定了从数据集中提取样本并将其插入批处理的策略。这可能包括根据特定标准以及概率分布选择样本。在此步骤中存在混洗选项,其中可以在每次数据集迭代之前重新排列样本,通常目的是提高训练模型的泛化能力。另一个参数是 collate/padding 函数,它本质上指定了将批处理内的所有单个样本链接在一起的过程(想想将向量堆叠成张量),以形成单个元素作为训练模型的输入。此外,可以配置数据加载器以自动将获取的数据样本存储在固定(页面锁定)内存中,从而能够更快地将数据传输到支持 CUDA 的设备。
数据加载器带有一个名为 worker 的组件,其目的是优化此数据传输过程。Workers 被定义为负责以异步方式执行数据加载的子进程。在创建数据加载器实例时,用户可以选择指定将生成并控制此操作的 worker 数量。如果 worker 数量等于零,则不会创建任何子进程,这反过来意味着数据提取在同一进程中同步发生,因此计算单元 (GPU) 必须等待数据加载完成 (PyTorch 核心团队)。相反,将生成与 worker 数量相等的子进程,这将防止计算代码因数据加载而阻塞。这是通过预先获取未来批次以在需要时准备就绪来实现的。