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

embedded/2024/11/20 11:28:12/

在这里插入图片描述
在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/embedded/139061.html

相关文章

Spark使用过程中的 15 个常见问题、详细解决方案

目录 问题 1&#xff1a;Spark 作业超时问题描述解决方案Python 实现 问题 2&#xff1a;内存溢出问题描述解决方案Python 实现 问题 3&#xff1a;Shuffle 性能问题问题描述解决方案Python 实现 问题 4&#xff1a;Spark 作业调度不均问题描述解决方案Python 实现 问题 5&…

美创科技膺选CNVD技术组支撑单位!

国家信息安全漏洞共享平台&#xff08;CNVD&#xff09;发布安全公告&#xff08;编号&#xff1a;CNTA-2024-0019&#xff09;&#xff0c;宣布新增八家支撑单位。美创科技凭借数据安全领域的技术实力和专业服务能力&#xff0c;顺利通过支撑能力候选考察&#xff0c;首次获得…

SQL 语句优化及编程方法

DBMS生成的执行计划在很大程度上要受到代码外部结构的影响。因此要想优化查询性能&#xff0c;就必须要知道如何写代码才能使优化器的执行效率更高。 但是&#xff0c;不能为了“效率”牺牲代码的可读性&#xff0c;要让代码清晰。 1 查询优化 在解决SQL造成的性能问题时&am…

Redis面试篇笔记(持续更新)

一、redis主从集群 单节点redis的并发能力是由上限的&#xff0c;要进一步提高redis的并发能力可以搭建主从集群&#xff0c;实现读写分离&#xff0c;一主多从&#xff0c;主节点写数据&#xff0c;从节点读数据 部署redis主从节点的docker-compose文件命令解析 version: &q…

基于单片机的厂房防火报警系统

本设计基于单片机的厂房防火报警系统&#xff0c;选用STC89C52RC作为核心的控制芯片&#xff0c;并且使用GSM技术来控制各种传感器&#xff0c;来实现多功能、多方面的安全监测。其中传感器主要包括&#xff1a;烟雾传感器、火焰传感器和温度传感器。主控芯片与这些传感器&…

【软件工程】一篇入门UML建模图(类图)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;软件开发必练内功_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

【PGCCC】PostgreSQL 数据库设计中的文本标识符 | 翻译

无论是设计独立应用程序还是微服务&#xff0c;您都不可避免地会遇到共享标识符的话题。无论是网页的 URL、RESTful API 资源、JSON 文档、CSV 导出还是其他内容&#xff0c;特定资源的标识符都会被暴露。 /orders/123 /products/345/variants/1虽然标识符只是一个数字&#x…

STM32电机运动控制与直线插补算法原理讲解

1.概念 不管是做自动化设备还是机器人运动学&#xff0c;都离不开对电机的控制&#xff0c;根据实际场景有各种各样的运动控制算法&#xff0c;而直线运动就是其中一种控制方式&#xff0c;今天就跟大家分享一个直线插补运动算法的原理&#xff0c;而代码的实现&#xff0c;则…