网易首页 > 网易号 > 正文 申请入驻

使用内存映射加快PyTorch数据集的读取

0
分享至

本文将介绍如何使用内存映射文件加快PyTorch数据集的加载速度

在使用Pytorch训练神经网络时,最常见的与速度相关的瓶颈是数据加载的模块。如果我们将数据通过网络传输,除了预取和缓存之外,没有任何其他的简单优化方式。

但是如果数据本地存储,我们可以通过将整个数据集组合成一个文件,然后映射到内存中来优化读取操作,这样我们每次文件读取数据时就不需要访问磁盘,而是从内存中直接读取可以加快运行速度。

什么是内存映射文件

内存映射文件(memory-mapped file)是将完整或者部分文件加载到内存中,这样就可以通过内存地址相关的load或者store指令来操纵文件。为了支持这个功能,现代的操作系统会提供一个叫做mmap的系统调用。这个系统调用会接收一个虚拟内存地址(VA),长度(len),protection,一些标志位,一个打开文件的文件描述符,和偏移量(offset)。

由于虚拟内存代表的附加抽象层,我们可以映射比机器的物理内存容量大得多的文件。 正在运行的进程所需的内存段(称为页)从外部存储中获取,并由虚拟内存管理器自动复制到主内存中。

使用内存映射文件可以提高I/O性能,因为通过系统调用进行的普通读/写操作比在本地内存中进行更改要慢得多,对于操作系统来说,文件以一种“惰性”的方式加载,通常一次只加载一个页,因此即使对于较大的文件,实际RAM利用率也是最低的,但是使用内存映射文件可以改善这个流程。

什么是PyTorch数据集

Pytorch提供了用于在训练模型时处理数据管道的两个主要模块:Dataset和DataLoader。

DataLoader主要用作Dataset的加载,它提供了许多可配置选项,如批处理、采样、预读取、变换等,并抽象了许多方法。

Dataset是我们进行数据集处理的实际部分,在这里我们编写训练时读取数据的过程,包括将样本加载到内存和进行必要的转换。

对于Dataset,必须实现:,和 三个方法

__init_

__len__

__getitem__

实现自定义数据集

接下来,我们将看到上面提到的三个方法的实现。

最重要的部分是在中,我们将使用 numpy 库中的 函数来创建一个ndarray将内存缓冲区映射到本地的文件。

__init__

np.memmap()

在数据集初始化时,将ndarray使用可迭代对象进行填充,代码如下:

class MMAPDataset(Dataset):
def __init__(
self,
input_iter: Iterable[np.ndarray],
labels_iter: Iterable[np.ndarray],
mmap_path: str = None,
size: int = None,
transform_fn: Callable[..., Any] = None,
) -> None:
super().__init__()
self.mmap_inputs: np.ndarray = None
self.mmap_labels: np.ndarray = None
self.transform_fn = transform_fn
if mmap_path is None:
mmap_path = os.path.abspath(os.getcwd())
self._mkdir(mmap_path)
self.mmap_input_path = os.path.join(mmap_path, DEFAULT_INPUT_FILE_NAME)
self.mmap_labels_path = os.path.join(mmap_path, DEFAULT_LABELS_FILE_NAME)
self.length = size
for idx, (input, label) in enumerate(zip(input_iter, labels_iter)):
if self.mmap_inputs is None:
self.mmap_inputs = self._init_mmap(
self.mmap_input_path, input.dtype, (self.length, *input.shape)
)
self.mmap_labels = self._init_mmap(
self.mmap_labels_path, label.dtype, (self.length, *label.shape)
)
self.mmap_inputs[idx][:] = input[:]
self.mmap_labels[idx][:] = label[:]
def __getitem__(self, idx: int) -> Tuple[Union[np.ndarray, torch.Tensor]]:
if self.transform_fn:
return self.transform_fn(self.mmap_inputs[idx]), torch.tensor(self.mmap_labels[idx])
return self.mmap_inputs[idx], self.mmap_labels[idx]
def __len__(self) -> int:
return self.length

我们在上面提供的代码中还使用了两个辅助函数。

def _mkdir(self, path: str) -> None:
if os.path.exists(path):
return
try:
os.makedirs(os.path.dirname(path), exist_ok=True)
return
except:
raise ValueError(
"Failed to create the path (check the user write permissions)."
)
def _init_mmap(self, path: str, dtype: np.dtype, shape: Tuple[int], remove_existing: bool = False) -> np.ndarray:
open_mode = "r+"
if remove_existing:
open_mode = "w+"
return np.memmap(
path,
dtype=dtype,
mode=open_mode,
shape=shape,
)

可以看到,上面我们自定义数据集与一般情况的主要区别就是中调用的,所以这里我们对 做一个简单的解释:

_init_mmap

np.memmap()

np.memmap()

Numpy的memmap对象,它允许将大文件分成小段进行读写,而不是一次性将整个数组读入内存。memmap也拥有跟普通数组一样的方法,基本上只要是能用于ndarray的算法就也能用于memmap。

使用函数并传入一个文件路径、数据类型、形状以及文件模式,即可创建一个新的memmap存储在磁盘上的二进制文件创建内存映射。

np.memmap

对于更多的介绍请参考Numpy的文档,这里就不做详细的解释了

基准测试

为了实际展示性能提升,我将内存映射数据集实现与以经典方式读取文件的普通数据集实现进行了比较。 这里使用的数据集由 350 张 jpg 图像组成。

从下面的结果中,我们可以看到我们的数据集比普通数据集快 30 倍以上:

总结

本文中介绍的方法在加速Pytorch的数据读取是非常有效的,尤其是使用大文件时,但是这个方法需要很大的内存,在做离线训练时是没有问题的,因为我们能够完全的控制我们的数据,但是如果想在生产中应用还需要考虑使用,因为在生产中有些数据我们是无法控制的。

https://avoid.overfit.cn/post/33d9496e1f8440d69a220fe6b9ab700c

作者:Tudor Surdoiu

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
重磅发现:人类心脏拥有巨大的再生潜能,存在着启动自我修复的密钥

重磅发现:人类心脏拥有巨大的再生潜能,存在着启动自我修复的密钥

生物世界
2024-12-01 17:59:31
鱼刺“卡嗓子”别再喝醋、吞米饭,教你3招,鱼刺自己“跑出来”

鱼刺“卡嗓子”别再喝醋、吞米饭,教你3招,鱼刺自己“跑出来”

猫小狸同学
2024-12-01 17:50:02
最新战报!名将1球不进,5-7落后,小特冲冠,达仔大赛门票稳了?

最新战报!名将1球不进,5-7落后,小特冲冠,达仔大赛门票稳了?

刘姚尧的文字城堡
2024-12-02 04:50:48
黄晓明宣布姥姥去世,离婚后不忘带儿子尽孝,杨颖备受黄家人认可

黄晓明宣布姥姥去世,离婚后不忘带儿子尽孝,杨颖备受黄家人认可

懂瓜瓜
2024-12-01 22:52:49
女孩素颜去喝粥火了,老板娘一眼相中介绍给儿子,网友:国民儿媳

女孩素颜去喝粥火了,老板娘一眼相中介绍给儿子,网友:国民儿媳

梅子的小情绪
2024-12-01 19:39:29
为什么现在电影行业突然就凉了?

为什么现在电影行业突然就凉了?

芯怡飞
2024-11-29 12:48:29
77岁老汉因盗窃入狱,点名时被发现疑点,一查才知道他真实身份

77岁老汉因盗窃入狱,点名时被发现疑点,一查才知道他真实身份

白云故事
2024-11-26 21:15:02
尺度太生猛,Netflix把A片之王搬上了荧幕

尺度太生猛,Netflix把A片之王搬上了荧幕

美剧院线
2024-11-28 22:52:32
六味地黄丸的新妙用,针对12种老年病!

六味地黄丸的新妙用,针对12种老年病!

乡村白大褂之家
2024-11-30 14:04:28
灵活务实有想法!阿莫林3场都是早早换掉4人,欧联60分钟用完换人

灵活务实有想法!阿莫林3场都是早早换掉4人,欧联60分钟用完换人

直播吧
2024-12-01 23:42:21
炸裂!姆巴佩惊艳停球+兜射10分角世界波,现场视角,太丝滑了

炸裂!姆巴佩惊艳停球+兜射10分角世界波,现场视角,太丝滑了

侧身凌空斩
2024-12-02 00:46:19
谁能让我不穿优衣库?

谁能让我不穿优衣库?

美芳
2024-12-01 14:12:21
主办方回应李行亮商演被网友抵制:已支付演出定金 本地观众反感声音并不大

主办方回应李行亮商演被网友抵制:已支付演出定金 本地观众反感声音并不大

极目新闻
2024-12-01 15:43:34
已婚少妇参加同学会喝醉,醒来已在酒店内:感觉体内有抽离的痛感

已婚少妇参加同学会喝醉,醒来已在酒店内:感觉体内有抽离的痛感

云端书馆
2024-12-01 09:10:48
大马士革发生政变?反对派在哈马遇阻,库尔德武装站在阿萨德一边

大马士革发生政变?反对派在哈马遇阻,库尔德武装站在阿萨德一边

鹰眼Defence
2024-12-01 18:13:12
18板+14板+14板!超级内线诞生,你再这样打下去,快船真要后悔了

18板+14板+14板!超级内线诞生,你再这样打下去,快船真要后悔了

巴叔GO聊体育
2024-12-01 16:31:30
99年朱总理访美,被问中国给克林顿30万献金,总理:怎么才30万?

99年朱总理访美,被问中国给克林顿30万献金,总理:怎么才30万?

WarOH协虎
2024-12-01 22:10:02
美籍健身教练自曝与1242名中国年轻漂亮女孩交往,并且有视频为证

美籍健身教练自曝与1242名中国年轻漂亮女孩交往,并且有视频为证

真实故事汇
2024-11-25 15:12:16
前所未有!中国企业赴美参加CES,遭美国大规模拒签

前所未有!中国企业赴美参加CES,遭美国大规模拒签

大洛杉矶LA
2024-12-01 05:20:40
俄罗斯布良斯克再遭大规模空袭!乌军F-16连击7枚导弹

俄罗斯布良斯克再遭大规模空袭!乌军F-16连击7枚导弹

项鹏飞
2024-12-01 18:40:01
2024-12-02 07:04:49
deephub
deephub
CV NLP和数据挖掘知识
1507文章数 1417关注度
往期回顾 全部

科技要闻

我国首个商业航天发射场首发成功

头条要闻

湖南省委原常委落马后 其妻追讨5000万巨额债务引关注

头条要闻

湖南省委原常委落马后 其妻追讨5000万巨额债务引关注

体育要闻

勇士四连败,到底是谁的错?

娱乐要闻

黄晓明姥姥去世,祖孙俩手牵手好温馨

财经要闻

女首富,死刑!交出800亿,免死!

汽车要闻

科技是中国豪车梦的支点 腾势Z9走心试驾体验

态度原创

时尚
健康
艺术
房产
本地

今冬流行“不露腿”穿搭!舒适还保暖,巨洋气!

花18万治疗阿尔茨海默病,值不值?

艺术要闻

故宫珍藏的墨迹《十七帖》,比拓本更精良,这才是地道的魏晋写法

房产要闻

一燃再燃!又卖2亿!白鹅潭顶流,引爆全城!

本地新闻

云游中国|来伦布夏果感受充满Passion的人生

无障碍浏览 进入关怀版