python gpu加速库比matlab快吗_DataLoader?直接切片更香!(pytorth GPU加速探讨)

DataLoader?直接切片更香!(pytorth GPU加速探讨)

写文章时作者刚看了两天pytorch,对其底层原理不甚了解。

仅从实际效果来讲一下遇到的情况

帮助一下具有效率优化强迫症的DataLoader受害者们

使用pytorch的小伙伴一定不会陌生这样的代码:

train_loader = DataLoader(

dataset=dataset,

batch_size=128,

shuffle=True,

)

for epoch in range(50):

for x, y in train_loader:

x = x.cuda()

y = y.cuda()

...

且不谈在windows下经常出现DataLoader中num_workers参数不为0会报各种错的缺点。

我在心里其实一直都有疑惑,dataloader的效率如何?

尤其是

x = x.cuda()

y = y.cuda()

这两行代码,因为我们的batch有时并不是很大,在循环中需要很多次cuda()的操作

那么这个将数据搬运到GPU上的函数效率如何?

每个epoch为什么重复都要搬到GPU上?

能不能直接一次将数据都搬到GPU上再进行运算?

因为通过DataLoader进行计算时,我们可以清楚地通过任务管理器看到GPU的状况

以MNIST数据集为例,迭代时GPU占用率如下:

b13b2d220e6fbac214503b46be990bf3.png

很明显的可以看到CUDA核心并没有占满,而且具有周期性,中间的占用并不连续。

后来在将Dataloader的num_workers=2,使用两个线程进行搬运数据

GPU的占用率如下:

94a4ee5083559aa044ee99c99ab7a979.png

可以看到,双线程明显比单线程的占用率要更大一些,但是仍然很低,周期性无法消除。

后来经过不断增加num_workers数量,发现其最大占用率也不超过40%

那么问题来了,为什么不用最简单的切片?

首先编写一个生成索引的类(模仿DataLoader的格式)

class BatchIndex:

def __init__(self, size, batch_size, shuffle=False, drop_last=True):

if drop_last:

self.index_list = [(x, x + batch_size,) for x in range(size) if

not x % batch_size and x + batch_size <= size]

else:

li = [(x, x + batch_size,) for x in range(size) if not x % batch_size]

x, y = li[-1]

li[-1] = (x, size)

self.index_list = li

self.shuffle = shuffle

self.drop_last = drop_last

if shuffle:

import random as r

r.shuffle(self.index_list)

def __next__(self):

self.pos += 1

if self.pos >= len(self.index_list):

raise StopIteration

return self.index_list[self.pos]

def __iter__(self):

self.pos = -1

return self

def __len__(self):

return len(self.index_list)

该类的size, batch_size, shuffle=False, drop_last=True等参数相想必不用多说。

该类是一个迭代器,能够产生切片所需的下标。

于是我们的代码就变成了:

# 一次性将所有内容放到GPU上

model.cuda()

x_data = x_data.cuda()

y_data = y_data.cuda()

x_test = x_test.cuda()

y_test = y_test.cuda()

for epoch in range(5):

for a,b in BatchIndex(60000,64,True): # batch_size = 64, shuffle = True

x = x_data[a:b]

y = y_data[a:b]

...

运行程序可以发现GPU占用率如下:

295d66b6d923169d5f0f6f2946053d42.png

占用率达到了70%,且不再出现周期波动(废话)。

时间缩短了近两三倍左右。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值