【python深度学习】——tensor内部存储结构|内存优化与as_strided|内存紧凑化contiguous

【python深度学习】——tensor内部存储结构|内存优化与as_strided|内存紧凑化contiguous

  • 1. tensor的元数据(metadata)和存储区(storage)
    • 1.1 元数据(metadata)
    • 1.2 存储区(Storage)
    • 1.3 查看tensor信息的代码示例
  • 2. 通过步长(Stride)、偏移量(storage_offset)以及“as_strided”实现内存优化
    • 2.1 步长(Stride)、偏移量(storage_offset)避免不必要的数据拷贝原理
    • 2.2 示例代码——通过as_strided来实现高级视图操作
  • 3. 内存紧凑化方法contiguous

1. tensor的元数据(metadata)和存储区(storage)

pytorch中的tensor内部存储结构分为两个部分——元数据(metadata)和存储区(storage)

1.1 元数据(metadata)

元数据中包含以下信息:

  • 形状——size(也是shape)
  • 数据类型——dtype
  • 设备——device
  • 步长——stride。步长告诉我们, 在内存中,移动到该tensor的下一个元素需要移动多少个位置。
  • 内存偏移—— storage_offset。当前 Tensor 的第一个元素在其底层存储区中的起始位置, storage_offset 的概念对于理解视图操作(如切片、reshape 等)非常重要。

通过调整 storage_offset 和步长(stride),我们可以高效地重新排列和访问数据,而不需要实际的数据拷贝, 这些在后面来详细介绍

1.2 存储区(Storage)

存储区是实际存储 Tensor 数据的地方。它包含了 Tensor 中所有元素的实际值,是一个一维的连续内存区, 它是可以共享的!
存储区有以下几点特性:

  • 连续性:虽然 Tensor 可以是多维的,但存储区是一维的,所有元素按照特定顺序存储在内存中。步长(stride)和形状(shape)帮助我们理解这些元素在多维空间中的排列方式。
  • 引用计数:存储区可以被多个 Tensor 共享。引用计数机制用于跟踪有多少个 Tensor 引用了同一个存储区,这有助于管理内存。
  • 数据类型一致:存储区中的所有数据元素类型一致,并且由 dtype 指定。

1.3 查看tensor信息的代码示例

我们可以这样查看tensor的信息:

import torch
# 创建一个形状为 (3, 4) 的 Tensor
tensor = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=torch.float32)

# 查看 Tensor 的元数据
print(f"形状: {tensor.shape}") #等价于print(f"形状: {tensor.size}")
print(f"数据类型: {tensor.dtype}")
print(f"设备: {tensor.device}")
print(f"步长: {tensor.stride()}")
print(f"存储区: {tensor.storage_offset()}")
# 查看存储区信息
print(f"存储区: {tensor.storage()}")
print(f"存储区数据类型: {tensor.storage().dtype}")
print(f"存储区元素数: {tensor.storage().size()}")

2. 通过步长(Stride)、偏移量(storage_offset)以及“as_strided”实现内存优化

2.1 步长(Stride)、偏移量(storage_offset)避免不必要的数据拷贝原理

深度学习中数据量往往是非常庞大的, 因此, tensor的storage是可以共享的, 如下图所示——tensor A和B的元素是相同的, 在内存中,其实是指向同一片空间的, 只是通过stride的不同,来实现呈现的tensor不同。

2.2 示例代码——通过as_strided来实现高级视图操作

# 创建一个 3x4 的 Tensor
tensor = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=torch.float32)

# 使用 as_strided 创建一个新的视图
as_strided_tensor = tensor.as_strided((2, 2), (4, 2), storage_offset=0)
print(f"as_strided Tensor:\n{as_strided_tensor}") # output: tensor([[1,3],[5,7]])

as_strided_tensor = tensor.as_strided((2, 2), (4, 2), storage_offset=1)
print(f"as_strided Tensor:\n{as_strided_tensor}") # output: tensor([[2,4],[6,8]])

3. 内存紧凑化方法contiguous

由前面两节我们已经知道, 有些情况下, tensor数据只是视图不同, 元素的存储其实没有改变, 那么在反复操作时, 有可能带来计算效率的下降。
那么当我们完成了视图操作并希望得到一个新的紧凑的 Tensor,可以使用 contiguous 方法将视图变为内存连续的, 例如下面的代码:

# 创建一个转置视图
transposed_tensor = tensor.t()

# 将转置视图变为连续的 Tensor
contiguous_tensor = transposed_tensor.contiguous()

print(f"连续 Tensor:\n{contiguous_tensor}")
print(f"连续 Tensor 的步长: {contiguous_tensor.stride()}")

在这个例子中,contiguous_tensor 是一个新的 Tensor,数据被复制到一个新的连续存储区中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/675884.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

excel公式怎么完全复制到另一列?

例如:A1单元格的内容是E1F1;想要复制到B列,内容也是E1F1,而不是F1G1;怎么做呢? 如果公式复制粘贴到其它位置出现偏差,通常有这么两个原因: 一、公式中的相对引用或混合引起 这个情…

操作字符串获取文件后缀名

记录一种操作字符串获取文件类型的操作方式,方便后期的使用。示例: 输入:"D:/code/Test/Test.txt" 输出:".txt" 设计逻辑: 1.通过查找”/“或者”\\“,找到文件名所在位置&#xff…

【并发程序设计】总篇集(八万字)

11_Concurrent_Programing 1.进程概念 在Linux中,进程是操作系统分配资源和调度运行的基本单位。 Linux中的进程有以下用处: 提高CPU利用率:通过进程的并发执行,可以让多个程序同时利用计算机的资源,这样每个用户都…

学习 SSH Key 生成方法

SSH Key 是用于身份验证的一对密钥,包括公钥和私钥。公钥可以放在需要访问的服务器上,私钥则保留在本地。当你使用SSH连接到支持SSH Key认证的服务器时,服务器会用公钥来加密一个随机生成的字符串发送给客户端,客户端用私钥解密并…

(ICLR,2024)HarMA:高效的协同迁移学习与模态对齐遥感技术

文章目录 相关资料摘要引言方法多模态门控适配器目标函数 实验 相关资料 论文:Efficient Remote Sensing with Harmonized Transfer Learning and Modality Alignment 代码:https://github.com/seekerhuang/HarMA 摘要 随着视觉和语言预训练&#xf…

vscode快捷键英文单词对照表

今天想改我的vscode快捷键,unfoldall这条跟我其他的ide都不一样,我得挨个记……但是ctrlshiftp一打开快捷键 点击右侧齿轮进行快捷键录制,但是我这次点左边进去查看了一下unfoldall当前是什么 后来看到了……这些oem_5是什么鬼? {…

03-07Java自动化之JAVA基础之循环

JAVA基础之循环 一、for循环 1.1for循环的含义 for(初始化语句;条件判断;条件控制或–){ ​ //代码语句 } 1、首先执行初始话语句,给变量一个起始的值 2、条件判断进行判断,为true,执行循环体中的代码语句 ​ …

从零开始学习Linux(9)----文件系统

1.前言 1.铺垫 a.文件内容属性 b.访问文件之前,都得先打开,修改文件,都是通过执行代码的方式完成修改,文件必须被加载到内存中 c.谁打开文件?进程在打开文件 d.一个进程可以打开多少个文件呢?可以打开多个…

idea springboot woff/woff2/eot/ttf/svg等小图标不显示的问题 - 第515篇

历史文章(文章累计500) 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

swiftUI使用VideoPlayer和AVPlayer播放视频

使用VideoPlayer包播放视频:https://github.com/wxxsw/VideoPlayer 提供一些可供测试的视频链接,不保证稳定可用哦: https://vfx.mtime.cn/Video/2019/06/15/mp4/190615103827358781.mp4https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp…

基于ssh的实验室设备管理系统java项目实验室管理系统spring项目jsp项目

文章目录 实验室设备管理系统一、项目演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目源码(9.9¥带走) 实验室设备管理系统 一、项目演示 实验室设备管理系统 二、项目介绍 基于sshjsp的实验室设备管理系统 系统角色…

6-Django项目--分页模块化封装参数共存

目录 utils/page_data.py 分页模块化封装 在app当中创建一个python package 在当前包里面创建py文件 参数共存 完整代码 utils/page_data.py --包里创建py文件. # -*- coding:utf-8 -*- from django.utils.safestring import mark_safe from copy import deepcopyclass…

网线水晶头为什么要按标准线序打

网线接水晶头为什么要按照线序接? 减少串扰和增强信号质量: 双绞线的设计是为了减少信号间的串扰( Crosstalk),每一对线芯在传输过程中通过相互扭绞抵消外部电磁干扰。按照标准线序接线能够确保每一对线芯之间的信号传…

maridb10.4.30数据库数据迁移

1.新建数据存储文件夹,例如E:\maridb_data 2.修改原数据所在目录的my.ini文件,例如D:\Program Files\MariaDB 10.4\data\my.ini 3.剪切除my.ini文件外的其他所有文件到迁移目的地文件(E:\maridb_data) 结果如下: 原数据文件目录&#xff1a…

MySQL—约束—外键约束(基础)

一、引言 概念:外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。 举个例子: 提示说明:(有两张表) (1)员工表:emp id:主键、姓名、年龄、…

qt+ffmpeg 实现音视频播放(四)之音视频同步

在处理音视频数据时,解码音频的数据往往会比解码视频的数据比较慢,所以我们在播放音视频时,音频和视频的数据会出现渐渐对不上的情况。尤其在播放时间越长的时候,这种对不上的现象越明显。 为了解决这一问题,人们想出…

485通讯网关

在工业自动化与智能化的浪潮中,数据的传输与交互显得尤为重要。作为这一领域的核心设备,485通讯网关凭借其卓越的性能和广泛的应用场景,成为了连接不同设备、不同协议之间数据转换和传输的桥梁。在众多485通讯网关中,HiWoo Box以其…

MySQL报ERROR 2002 (HY000)解决

今天在连接客户服务器时MySQL的时候报: ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql/mysql.sock’ (2) [rootXXX ~]# mysql -uroot -p Enter password: ERROR 2002 (HY000): Can’t connect to local MySQL server through socket…

SpringBoot邮件发送的安全性如何有效保障?

SpringBoot邮件发送服务如何集成?怎么优化邮件发送? Spring Boot作为一个流行的Java开发框架,提供了便捷的邮件发送功能,使得开发者可以轻松地集成邮件发送到他们的应用程序中。AokSend将探讨如何有效地保障Spring Boot邮件发送的…

linux驱动学习(四)之module

一、内核模块 内核模块是一种可以动态加载到操作系统内核中并扩展其功能的软件。它们允许在运行的操作系统内核中增加新的功能或驱动程序,而无需重新启动计算机。 在linux系统中,驱动程序是各自独立存在的,而且驱动程序中包含一个moudle&am…