前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一个简单的更改让PyTorch读取表格数据的速度提高20倍:可大大加快深度学习训练的速度

一个简单的更改让PyTorch读取表格数据的速度提高20倍:可大大加快深度学习训练的速度

作者头像
deephub
发布于 2020-05-09 08:54:04
发布于 2020-05-09 08:54:04
1.8K00
代码可运行
举报
文章被收录于专栏:DeepHub IMBADeepHub IMBA
运行总次数:0
代码可运行
深度学习:需要速度

在训练深度学习模型时,性能至关重要。数据集可能非常庞大,而低效的训练方法意味着迭代速度变慢,超参数优化的时间更少,部署周期更长以及计算成本更高。

由于有许多潜在的问题要探索,很难证明花太多时间来进行加速工作是合理的。但是幸运的是,有一些简单的加速方法!

我将向您展示我在PyTorch中对表格的数据加载器进行的简单更改如何将训练速度提高了20倍以上,而循环没有任何变化!这只是PyTorch标准数据加载器的简单替代品。对于我正在训练的模型,可以16分钟的迭代时间,减少到40秒!

所有这些都无需安装任何新软件包,不用进行任何底层代码或任何超参数的更改。

研究/产业裂痕

在监督学习中,对Arxiv-Sanity的快速浏览告诉我们,当前最热门的研究论文都是关于图像(无论是分类还是生成GAN)或文本(主要是BERT的变体)。深度学习在传统机器学习效果不好的这些领域非常有用,但是这需要专业知识和大量研究预算才能很好地执行。

许多公司拥有的许多数据已经以很好的表格格式保存在数据库中。一些数据包括用于终生价值估算的客户详细信息,优化和财务的时间序列数据。

表格数据有何特别之处?

那么,为什么研究与产业之间的裂痕对我们来说是一个问题呢?好吧,最新的文本/视觉研究人员的需求与那些在表格数据集上进行监督学习的人的需求截然不同。

以表格形式显示数据(即数据库表,Pandas DataFrame,NumPy Array或PyTorch Tensor)可以通过以下几种方式简化操作:

  1. 可以通过切片从连续的内存块中获取训练批次。
  2. 无需按样本进行预处理,从而使我们能够充分利用大批量培训来提高速度(请记住要提高学习率,所以我们不会过拟合!)
  3. 如果您的数据集足够小,则可以一次将其全部加载到GPU上。(虽然在技术上也可以使用文本/视觉数据,但数据集往往更大,并且某些预处理步骤更容易在CPU上完成)。 对于表格数据而不是文本/视觉数据,这些优化是可能的,他们存在两个主要区别:模型和数据。

模型:视觉研究倾向于使用大型深层卷积神经网络(CNN);文本倾向于使用大型递归神经网络(RNN)或转换器;但是在表格数据上,完全连接的深度神经网络(FCDNN)可以很好地完成工作。尽管并非总是如此,但与表格数据中变量之间的交互作用相比,一般而言,视觉和文本模型需要更多的参数来学习更多的细微差别的表示,因此向前和向后传递可能需要更长的时间。

数据:视觉数据倾向于将数据保存为充满图像的嵌套文件夹,这可能需要大量的预处理(裁剪,缩放,旋转等)。文本数据可以是大文件或其他文本流。通常,这两种方法都将保存在磁盘上,并从磁盘上批量加载。这不是问题,因为瓶颈不是磁盘的读写速度,而是预处理或向后传递。另一方面,表格数据具有很好的特性,可以轻松地以数组或张量的形式加载到连续的内存块中。表格数据的预处理往往是预先在数据库中单独进行,或者作为数据集上的矢量化操作进行。

不同类型的监督学习研究的比较

pytorch和Dataloader

如我们所见,加载表格数据非常容易,快捷!因此,默认情况下,PyTorch当然可以很好地处理表格数据…对吗?

事实证明并非如此!?

就在上周,我正在训练一些表格数据上的PyTorch模型,并想知道它为什么花了这么长时间来训练。我看不到任何明显的瓶颈,但是由于某些原因,GPU使用率比预期的要低得多。当我进行一些分析时,我发现了罪魁祸首……DataLoader。

什么是DataLoader? DataLoader完全按照您的想象做:将数据从任何位置(在磁盘,云,内存中)加载到模型使用它所需的任何位置(RAM或GPU内存)中。除此之外,他们还负责将您的数据分为几批,重新整理,并在必要时对单个样本进行预处理。将此代码包装在DataLoader中比散布在整个代码中更好,因为它可以使您的主要训练代码保持整洁。官方的PyTorch教程还建议使用DataLoader。

您如何使用它们?这取决于您拥有的数据类型。对于表格数据,PyTorch的默认DataLoader可以使用TensorDataset。这是围绕训练所需的张量的轻量级包装,通常是X(或特征)和Y(或标签)张量。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 data_set = TensorDataset(train_x, train_y)
 train_batches = DataLoader(data_set, batch_size=1024, shuffle=False)

然后,您可以在训练循环中使用它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 for x_batch, y_batch in train_batches:    
     optimizer.zero_grad()    
     loss = loss_fn(model(x_batch), y_batch)    
     loss.backward()    
     optimizer.step()    
     ...

为什么这样不好? 这看起来不错,当然也很干净!问题在于,每次加载批处理时,PyTorch的DataLoader会在每个示例中调用一次DataSet上的__getitem __()函数并将其连接起来,而不是一次大批量地读取批处理!因此,我们最终不会利用表格数据集的优势。当我们使用大批量时,这尤其糟糕。

我们该如何解决?用下面的两行替换上面的前两行,然后从该文件复制FastTensorDataLoader的定义(有关此项,请在PyTorch论坛上获得Jesse Mu的支持):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 train_batches = FastTensorDataLoader(train_x, train_y, batch_size=1024, shuffle=False)

FastTensorDataLoader只是一个小的自定义类,除了PyTorch之外没有任何依赖关系-使用它不需要对您的训练代码进行任何更改!它也支持改组,尽管下面的基准测试适用于未改组的数据。

这有什么区别? 在我使用的基准测试集上,自定义表格格式DataLoader的运行速度快了20倍以上。在这种情况下,这意味着用40秒钟的时间运行之前超过15分钟的程序-迭代速度上的巨大差异!

两次接近相同的运行-除了一次需要15分钟以上,而另一次不到一分钟!

该基准是在本《自然》论文中使用的希格斯数据集上运行的。与11m个示例相比,它为大多数公共表格建立ML数据集(可能很小!)提供了更现实的深度学习基准。这是一个二进制分类问题,具有21个实值特征。很高兴看到,在进行任何超参数优化之前,我们只需训练40秒钟就能在测试装置上获得超过0.77的ROC AUC!尽管我们离本文所达到的0.88尚有一段距离。

希望对您有所帮助,并且您可以在自己的训练代码中看到类似的速度提升!实施此方法后,我发现了一些进一步的优化措施,从而使总加速接近100倍!如果您想了解更多信息,请发表评论,我们可以在后续文章中介绍这些内容。

有关如何自己运行基准代码的信息,请参见附录。该示例包括用于运行默认PyTorch DataLoader,更快的自定义代码以及计时结果并记录到TensorBoard的代码。

这篇帖子的实现源于Genesis Cloud的计算功劳:以令人难以置信的成本效率实现云GPU,并在冰岛的数据中心中使用100%可再生能源。注册时可获得$ 50的免费赠送金额,使用GTX 1080Ti可获得160多个小时!

附录:运行基准测试

您可以自己查看结果,以下是复制实验的说明。如果您已经安装了本地GPU和PyTorch,则可以跳过前两个步骤!

  1. 使用您最喜欢的GPU云提供商创建一个新的Ubuntu 18.04实例(我使用Genesis cloud-注册后可获得$ 50的免费积分,足以运行此实验数百次!)。
  2. 使用Lambda Stack一口气安装CUDA和PyTorch :(这样做后请不要忘记重启!)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 LAMBDA_REPO=$(mktemp) && \
 wget -O${LAMBDA_REPO} https://lambdalabs.com/static/misc/lambda-stack-repo.deb && \
 sudo dpkg -i ${LAMBDA_REPO} && rm -f ${LAMBDA_REPO} && \
 sudo apt-get update && \
 sudo apt-get — yes upgrade && \
 sudo apt-get install — yes — no-install-recommends lambda-server && \
 sudo apt-get install — yes — no-install-recommends nvidia-headless-440 nvidia-utils-440 && \
 sudo apt-get install — yes — no-install-recommends lambda-stack-cuda
  1. 下载数据集
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 wget http://archive.ics.uci.edu/ml/machine-learning-databases/00280/HIGGS.csv.gz
  1. 克隆存储库
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 git clone git@github.com:hcarlens/pytorch-tabular.git
  1. 运行基准脚本
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 python3 pytorch-tabular/higgs_benchmark.py

如果您在使用GTX 1080Ti的实例(例如我使用的Genesis Cloud)上运行,则应获得以下结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ubuntu@genesis:~$ python3 pytorch-tabular/higgs_benchmark.py
 2020-04-12 15:05:55.961134: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.0
 Epoch 0 done.
 Epoch 1 done.
 Epoch 2 done.
 Epoch 3 done.
 Epoch 4 done.
 Epoch 5 done.
 Epoch 6 done.
 Epoch 7 done.
 Epoch 8 done.
 Epoch 9 done.
 Epoch 0 done.
 Epoch 1 done.
 Epoch 2 done.
 Epoch 3 done.
 Epoch 4 done.
 Epoch 5 done.
 Epoch 6 done.
 Epoch 7 done.
 Epoch 8 done.
 Epoch 9 done.
 Standard dataloader: 124.55s/epoch.
 Custom dataloader: 5.24s/epoch.

作者:Harald Carlens

deephub翻译组:孟翔杰

请关注 deephub-imba 发送 20200508 即可获取 FastTensorDataLoader 源代码github地址

DeepHub

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DeepHub IMBA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
如何实现一个new方法
• 创建一个空对象,将它的引用赋给 this,继承函数的原型。 • 通过 this 将属性和方法添加至这个对象 • 最后返回 this 指向的新对象,也就是实例(如果没有手动返回其他的对象)
刘嘿哈
2022/10/25
2470
JavaScript —— New
热身 New 这个关键字 是创建对象的? JS中万物皆是对象。 new 关键字是用来继承的。 => 面向对象的基础 new function DN(name, age) { this.name = name; this.age = age; this.salary = '30k'; } DN.prototype.ability = 100; DN.prototype.sayYourName = function(){ console.log('I am' + this.name); }
FinGet
2019/06/28
5630
前端面试(2)javascript
当使用构造函数创建一个对象后,在这个对象内部包含一个指针,这个指针指向构造函数的 prototype 属性所对应的值,这个指针被称为对象的为原型。
leader755
2022/03/08
1.3K0
前端面试(2)javascript
【THE LAST TIME】一文吃透所有JS原型相关知识点
首先我想说,【THE LAST TIME】系列的的内容,向来都是包括但不限于标题的范围。
Nealyang
2019/11/04
1.1K0
[我的理解]Javascript的原型与原型链
一、原型与原型链的定义 原型:为其他对象提供共享属性的对象     注:当构造器创建一个对象,为了解决对象的属性引用,该对象会隐式引用构造器的"prototype"属性。程序通过constructor.prototype可以直接引用到构造器的"prototype"属性。并且添加到对象原型里的属性,会通过继承与所有共享此原型的对象共享。 原型链:每个由构造器创建的对象,都有一个隐式引用(叫做对象的原型)链接到构造器的"prototype"属性。再者,原型可能有一个非空隐式引用链接到它自己的原型,以此类推,这叫
sam dragon
2018/01/17
9160
[我的理解]Javascript的原型与原型链
深入理解javascript中的继承机制 之 12种继承模式总结原型链法仅从原型继承临时构造器原型属性拷贝所有属性拷贝(浅拷贝)深拷贝原型继承法扩展与增强模式多重继承法寄生式继承借用构造函数:构造器于
之前我们介绍了多种javascript中的继承方式,最后我们开始总结概括这些继承方式,先将javascript中的继承分类,根据不同的条件,可以分成不同的类别。 最常用的我们可以分为这两类:
desperate633
2018/08/22
5090
JavaScript 面向对象
创建函数 Foo 的时候,就会有一个内置的 Foo.prototype 属性,并且这个属性是对象。
零式的天空
2022/03/02
2870
JavaScript继承的实现方式:原型语言对象继承对象原理剖析
对象的继承:A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。
周陆军
2021/08/14
8400
深入理解JavaScript(一)
2.支持函数式编程(高阶函数、内置的map和reduce)和面向对象编程(对象、继承)的混合编程风格
硬核项目经理
2019/08/06
1.5K0
JavaScript 常用功能总结
小编吐血整理加上翻译,太辛苦了~求赞! 本文主要总结了JavaScript 常用功能总结,如一些常用的JS 对象,基本数据结构,功能函数等,还有一些常用的设计模式。 目录: 众所周知,JavaScript是动态的面向对象的编程语言,能够实现以下效果: 1. 丰富Web 网页功能 2. 丰富Web界面 3. 实现本地或远程存储。 4. 实现分布式网络应用的前端组件,并在后台进行数据存储管理。 5. 使用JavaScript可以实现完整的分布式Web 应用。 JavaScript 中的数据类型 JavaScri
葡萄城控件
2018/01/10
2.7K0
JavaScript 常用功能总结
JavaScript两种继承方式详解
由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念。所以,要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现
疯狂的技术宅
2019/03/27
7100
由浅入深,66条JavaScript面试知识点
来源:https://juejin.im/post/5ef8377f6fb9a07e693a6061
zz_jesse
2020/07/07
1.1K0
由浅入深,66条JavaScript面试知识点
JavaScript学习总结(四)——this、原型链、javascript面向对象
根据题目要求,对给定的文章进行摘要总结。
张果
2018/01/04
1.5K0
JavaScript学习总结(四)——this、原型链、javascript面向对象
涨薪必备Javascript,快点放进小口袋!
摘要: 嗨,新一年的招聘季,你找到更好的工作了吗?小姐姐最近刚换的工作,来总结下面试必备小技能,从this来看看javascript,让我们更深入的了解它。 前言 在JavaScript中,被吐槽最多的this,原型,继承,闭包等这些概念。接下来这篇文章会把我自己对于JavaScript中这些点通过this指向做个总结并分享给大家,希望可以帮助大家更好的了解这些所谓的难点。 一、this this是什么?this的常见使用场景呢? 普通调用,this指向为调用者 call/apply调用,this指向为当前
用户2145235
2018/05/18
7000
由浅入深,66条JavaScript面试知识点
作者:Jake Zhang https://juejin.cn/post/6844904200917221389
用户4456933
2021/06/01
7450
由浅入深,66条JavaScript面试知识点
JS中的面向对象、原型、原型链、继承总结大全
补充: js中说一切都是对象,是不完全的,在js中6种数据类型(Undefined,Null,Number,Boolean,String,Object)中,前五种是基本数据类型,是原始值类型,这些值是在底层实现的,他们不是object,所以没有原型,没有构造函数,所以并不是像创建对象那样通过构造函数创建的实例。关于对象属性类型的介绍就不介绍了。
疯狂的技术宅
2019/03/27
1.5K0
JS中的面向对象、原型、原型链、继承总结大全
【面试】386- JavaScript 面试 20 个核心考点
Javascript是前端面试的重点,本文重点梳理下 Javascript 中的常考基础知识点,然后就一些容易出现的题目进行解析。限于文章的篇幅,无法将知识点讲解的面面俱到,本文只罗列了一些重难点,如果想要了解更多内容欢迎点击https://github.com/ljianshu/Blog。
pingan8787
2019/10/23
4940
【面试】386- JavaScript 面试 20 个核心考点
JS与ES6高级编程学习笔记(三)——JavaScript面向对象编程
面向对象程序编程(Object-oriented programming,缩写:OOP)是用抽象方式构建基于现实世界模型的一种编程模式,JavaScript是一种基于对象(object-based)的语言,支持面向对象编程与函数式编程,但JavaScript的面向对象与其它的面向对象语言有较大差异,ECMAScript中没有类的概念,所以对象也有所不一样。
张果
2022/06/06
7980
JS与ES6高级编程学习笔记(三)——JavaScript面向对象编程
《JavaScript 模式》读书笔记(6)— 代码复用模式3
我们之前聊了聊基本的继承的概念,也聊了很多在JavaScript中模拟类的方法。这篇文章,我们主要来学习一下现代继承的一些方法。
zaking
2020/05/01
5560
ECMA-262-3深入解析第七章:2、OOP ECMAScript 实现
从来没有深入了解ECMA,网上找了一下,发现早在2010年就有大佬 Dmitry Soshnikov 总结了ECMA中的核心内容,我这里只是翻译记录,加深自己的印象。文章原文来自 ECMA-262-3 in detail. Chapter 7.2. OOP: ECMAScript implementation.
踏浪
2021/06/09
6290
推荐阅读
相关推荐
如何实现一个new方法
更多 >
LV.1
环数科技有限公司数据库开发工程师
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验