torch.utils.data.dataset 的数据组织形式——python list、dict、tuple内存消耗量

devtools/2024/11/22 22:32:23/

在这里插入图片描述
在Pytorch中,我们需要通过torch.utils.data.dataset来实现数据的读取。torch.utils.data.dataset是一种非流式的数据读取策略,需要将数据一次性导入至内存中.如果数据规模过大,可能存在内存不够的问题。

python">import torch
from torch.utils.data import Datasetclass TestDataset(Dataset):def __init__(self, image_path, label_path):'''从image_path中读取图片代码实现xxx''''''从label_path中读取标签代码实现xxx''''''保存为data,每一个元素为data和targetdata = ...'''self.data = datadef __getitem__(self, index):'''获取图像tensor和标签label代码实现xxx'''return image_tensor, labeldef __len__(self):return len(self.data)

例如代码中,将所有image_path和label都写到self.data中,可能会爆内存。如何优化呢?

优化

优化的关键点在于怎么减少self.data的内存占用,其中每一个元素可以采用list、dict或tuple这三种python产用的数据结构,哪一种在内存效率上最优呢?
答案是:
tuple < list < dict

实验

有两种统计python对象的内存占用大小,分别是sys.getsizeofpympler.asizeof

  • sys.getsizeof 只返回对象本身占用的内存大小,不包括对象引用的其他对象的内存大小
  • pympler.asizeof 返回对象及其所有引用的对象的总内存大小
    所以采用pympler.asizeof来统计对象内存占用
python">from pympler import asizeoftuple_info = [('pth_{}'.format(i),'label_{}'.format(i)) for i in range(1000000)]
print("tuple size: {} bytes".format(asizeof.asizeof(tuple_info)))
## tuple size: 192440648 byteslist_info = [['pth_{}'.format(i),'label_{}'.format(i)] for i in range(1000000)]
print("list size: {} bytes".format(asizeof.asizeof(list_info)))
## list size: 208440648 bytesdict_info = [{'pth': 'pth_{}'.format(i),'label': 'label_{}'.format(i)} for i in range(1000000)]
print("dict size: {} bytes".format(asizeof.asizeof(dict_info)))
## dict size: 368440760 bytes

可以发现,在1000000条数据情况下,利用tuple存储比利用dict存储减少了47%的内存占用,可以省下多少钱啊!!!!!!

原理

  • python中的dict涉及到哈希表的实现,因此需要额外的存储空间。不仅如此,python3.7+的dict是有序dict,也需要下标数组来维持有序特性,需要对下标数据做存储,因此,dict的存储效率最低。
  • python中的list是动态数组,需要额外的内存来存储引用,用于适应list内数据调整。list的每个元素都有一个指向实际数据的引用指针,这会导致额外的内存开销。
  • python中的tuple是不可变的,无额外的引用指针,导致存储效率更高。

如果真的涉及特别大规模的数据读取,建议采用torch.utils.data.IterableDataset,为流式的数据读取策略,每次仅读取一部分数据进到内存中,一定不会爆内存。但存在的问题是随机性不够高。
torch.utils.data.dataset预先知道了所有数据,支持对所有数据打乱顺序。
torch.utils.data.IterableDataset只能对一部分数据打乱顺序。
两种方式各有利弊。

笔者后续会单独写篇博客,来详细讲讲这两种数据读取策略。


http://www.ppmy.cn/devtools/136137.html

相关文章

ts: 定义一个对象接收后端返回对象数据,但是报错了有红色的红线为什么

问&#xff1a; const backendProgressData ref<object>&#xff08;{}&#xff09; 这是我的代码&#xff0c;但是当我进行使用的时候&#xff1a; backendProgressData.value xxxx接口返回数据progressData:{percentage:123,text:"文字"} 在template中{{…

AWTK VSCode 实时预览插件端口冲突的解决办法

AWTK XML UI 预览插件&#xff1a;在 vscode 中实时预览 AWTK XML UI 文件&#xff0c;在 Copilot 的帮助下&#xff0c;可以大幅提高界面的开发效率。 主要特色&#xff1a; 真实的 UI 效果。可以设置主题&#xff0c;方便查看在不同主题下界面的效果。可以设置语言&#xf…

centos7 如何卸载和安装达梦数据库实例

1.DM8数据库的卸载和安装 1.1 卸载数据库(卸载和安装部分建议反过来看) 1.1.1 运行uninstall.sh 脚本所在位置为DM8数据库安装所在目录 # 进入DM数据库所在安装目录 cd /dm8 # 运行卸载脚本 ./uninstall.sh 1.1.2 查看安装目录剩下的文件 ll 1.1.3 清空安装目录 #…

el-table最大高度无法滚动

解决el-table同时使用fixed和计算的最大高度时固定右边的列无法跟随滚动的问题 原因&#xff1a;el-table组件会根据传入的 max-height 计算表格内容部分 和 fixed部分的最大高度&#xff0c;以此来生成滚动条和产生滚动效果&#xff0c;当传入的 max-height 为一个计算的高度…

深入探索Apache JMeter:HashTree结构解析与应用

Apache JMeter的TestPlan .jmx文件中&#xff0c;HashTree是用于组织和管理测试计划元素的关键数据结构。以下是对HashTree及其在JMeter中的作用和特点的详细解释&#xff1a; 一、HashTree的定义与作用 定义&#xff1a;HashTree是JMeter中用于存储和管理测试计划元素的一种…

嵌入式驱动面试总结

操作系统&#xff1a; 中断的处理流程&#xff0c;中断处理需要注意些什么 软中断和硬中断区别 linux驱动用过那些锁&#xff0c;信号量&#xff0c;互斥锁 自旋锁和互斥锁的区别 二值信号量和互斥信号量有什么区别 进程锁怎么实现的&#xff0c;说一下流程&#xff1b; …

Linux基础指令(汇总)

文章目录 1. ls指令2. pwd指令3. cd指令4. touch指令5. mkdir指令6. rmdir指令&&rm指令7. man指令8. cp指令8. mv指令9. cat指令10. more指令11. less指令12. head指令13. tail指令14. date指令15. cal指令16. find指令17. which指令18. whereis指令19. alias指令20. g…

详解八大排序(三)------(快速排序)

文章目录 前言1. 递归版本&#xff08;QuickSort&#xff09;1.1 hoare版本1.1.1 核心思路1.1.2 实现代码 1.2 挖坑法1.2.1 核心思路1.2.2 实现代码 1.3 lomuto版本1.3.1 核心思路1.3.2 实现代码 2. 非递归版本&#xff08;QuickSortNonR&#xff09;2.1 核心思路2.2 实现代码 …