Torch核心数据结构Tensor(张量)
Torch核心数据结构Tensor张量在深度学习和科学计算领域PyTorch 凭借其动态计算图和易用性成为了最受欢迎的框架之一。而这一切的基石便是其核心数据结构——Tensor张量。Tensor 可以理解为多维数组的泛化它不仅是存储数据的容器更是连接 CPU、GPU 计算以及自动微分Autograd的桥梁。本文将从原理层面深入剖析 Tensor并提供可运行的代码示例帮助读者理解其精髓。## Tensor 的基本概念与内存布局Tensor 本质上是一个多维数组但与传统数组不同它拥有更丰富的语义。从数学角度看标量0维张量、向量1维张量、矩阵2维张量都是张量的特例。在 PyTorch 中Tensor 包含两个核心部分-数据区存储在连续内存块中的数值支持整数、浮点数等类型。-元数据包括形状shape、步长stride、数据类型dtype和设备device如 CPU/GPU。步长stride是理解 Tensor 内存布局的关键。它表示在每个维度上从当前元素移动到下一个元素需要跳过的内存单元数量。例如一个形状为(3, 4)的矩阵默认的步长为(4, 1)即行间移动需跳过 4 个元素列间移动只需 1 个元素。PyTorch 通过步长实现了视图view操作在不复制数据的情况下重塑张量极大节省了内存。## Tensor 的创建与基本操作我们从一个简单的代码示例开始演示如何创建 Tensor 并观察其属性。pythonimport torch# 创建一个形状为 (2, 3) 的浮点型张量元素值随机tensor_a torch.randn(2, 3) # 标准正态分布随机数print(Tensor a:\n, tensor_a)print(形状:, tensor_a.shape)print(数据类型:, tensor_a.dtype)print(设备:, tensor_a.device)print(步长:, tensor_a.stride()) # 输出 (3, 1)表示行步长3列步长1# 创建全零张量并指定数据类型和设备if torch.cuda.is_available(): tensor_b torch.zeros(2, 3, dtypetorch.float64, devicecuda) print(\nTensor b (on GPU):\n, tensor_b)else: print(CUDA 不可用使用 CPU 代替) tensor_b torch.zeros(2, 3, dtypetorch.float64)# 从 Python 列表创建张量list_data [[1, 2, 3], [4, 5, 6]]tensor_c torch.tensor(list_data)print(\n从列表创建的张量:\n, tensor_c)print(数据类型:, tensor_c.dtype) # 默认为 int64运行上述代码你会看到 Tensor 的创建方式灵活多样且通过.dtype、.device等属性可以轻松管理计算资源。注意torch.randn会返回一个torch.float32类型的张量而torch.zeros允许显式指定dtype这在混合精度训练中非常重要。## Tensor 的运算与自动广播机制Tensor 支持逐元素运算如加法、乘法和矩阵运算如mm、matmul。其中广播Broadcasting机制允许不同形状的张量进行运算其原理类似于 NumPy。广播规则如下1. 从最后一个维度开始对齐。2. 如果一个维度的大小为 1 或不存在则将该维度扩展为匹配的尺寸。3. 如果维度大小不一致且都不为 1则报错。下面是一个演示广播和矩阵运算的代码示例pythonimport torch# 演示广播加法a torch.tensor([[1, 2, 3], [4, 5, 6]]) # 形状 (2, 3)b torch.tensor([10, 20, 30]) # 形状 (3,)print(广播加法结果:\n, a b) # b 被广播为 (2, 3)# 矩阵乘法形状需兼容 (m, n) (n, p) - (m, p)c torch.randn(3, 2) # 形状 (3, 2)d torch.randn(2, 4) # 形状 (2, 4)result torch.mm(c, d) # 等价于 c dprint(\n矩阵乘法结果形状:, result.shape) # 输出 (3, 4)# 逐元素运算与原地操作e torch.ones(2, 3)e.mul_(2) # 原地乘以2注意下划线表示原地操作print(\n原地操作后的张量:\n, e)# 使用 view 改变形状不复制数据f torch.arange(12) # 一维张量 [0,1,...,11]g f.view(3, 4) # 重塑为 3x4注意元素总数必须匹配print(\n原始张量 f:, f)print(视图 g:\n, g)# 修改视图会影响原始数据g[0, 0] 99print(修改后 f:, f) # f 的第一个元素也变为 99这段代码展示了 Tensor 运算的灵活性和高效性。view操作通过调整步长实现了零拷贝的形状变换但要求原始张量在内存中是连续的。如果遇到非连续张量如转置后的张量可以使用.contiguous()方法强制转换为连续内存。## Tensor 的自动微分原理Tensor 与 Autograd 紧密结合实现了自动梯度计算。当设置requires_gradTrue时Tensor 会记录所有操作构建一个计算图。每个 Tensor 都有一个.grad_fn属性指向生成它的函数如AddBackward用于反向传播时计算梯度。关键原理计算图是动态构建的每次前向传播都会创建新的图结构。叶子节点用户创建的张量的grad_fn为None而中间节点的梯度通过链式法则计算。下面是一个完整的自动微分示例pythonimport torch# 创建需要梯度的张量x torch.tensor([2.0, 3.0], requires_gradTrue)w torch.tensor([1.0, -1.0], requires_gradTrue)b torch.tensor(0.5, requires_gradTrue)# 定义计算y sum(x * w) by torch.sum(x * w) b # 等价于 2*1 3*(-1) 0.5 -0.5print(y 的值:, y.item())# 反向传播计算梯度y.backward()print(dy/dx:, x.grad) # 梯度为 [w1, w2] [1.0, -1.0]print(dy/dw:, w.grad) # 梯度为 [x1, x2] [2.0, 3.0]print(dy/db:, b.grad) # 梯度为 1.0# 梯度累积如果再次调用 backward梯度会累积y2 torch.sum(x * w) b # 重新计算 yy2.backward() # 梯度会累加到之前的梯度上print(\n累积后的梯度:, x.grad) # 变为 [2.0, -2.0]注意默认情况下 PyTorch 会累积梯度因此在训练循环中需要手动清零使用optimizer.zero_grad()。此外with torch.no_grad()上下文管理器可以临时禁用梯度计算常用于评估模式。## Tensor 的 GPU 加速与性能优化Tensor 可以通过.to(device)在 CPU 和 GPU 之间迁移。GPU 上的 Tensor 运算利用 CUDA 核心并行执行显著提升性能尤其是在矩阵运算和卷积中。但频繁的数据迁移会带来开销因此应尽量将数据保持在同一个设备上。性能优化技巧- 使用torch.cuda.Stream实现异步操作。- 使用torch.jit.script或torch.compilePyTorch 2.0进行图优化。- 合理选择数据类型如float16代替float32以减少显存占用。## 总结Tensor 是 PyTorch 生态的基石它通过统一的数据抽象实现了跨设备计算、自动微分和高效的内存管理。本文从内存布局、创建操作、广播机制、自动微分到 GPU 加速层层深入揭示了其设计原理。理解 Tensor 的内部机制不仅有助于编写高效的代码还能为自定义算子或模型优化打下坚实基础。无论是初学者还是资深研究者掌握 Tensor 的精髓都是掌握 PyTorch 的第一步。

相关新闻

nftables精讲与例子(NAT、限速、限流量、禁ping等例子)

nftables精讲与例子(NAT、限速、限流量、禁ping等例子)

nftables精讲与例子(NAT、限速、限流量、禁ping等例子) 为什么选择nftables?在Linux网络管理领域,iptables曾长期占据统治地位。但随着网络规模扩大和功能需求增加,iptables的局限性日益显现:规则集难以维护…

2026/10/19 17:33:55 阅读更多 →
OpenClaw实战:AI自动化提升研发文档、代码评审与测试效率

OpenClaw实战:AI自动化提升研发文档、代码评审与测试效率

1. OpenClaw技术文档/代码评审/测试用例生成深度实战作为一名长期奋战在研发一线的技术老兵,我深知文档编写、代码评审和测试用例设计这三座大山对开发效率的拖累。最近深度体验了OpenClaw这个AI研发智能体平台,其三大核心能力确实给我们的工作流带来了革…

2026/10/20 21:56:00 阅读更多 →
BinDiff 7.0 安装配置与IDA Pro联动逆向分析实战指南

BinDiff 7.0 安装配置与IDA Pro联动逆向分析实战指南

1. 项目概述:为什么逆向工程师离不开BinDiff?如果你在逆向分析一个复杂的二进制文件,比如一个大型的恶意软件样本或者一个闭源的商业软件,你可能会遇到一个头疼的问题:这个版本和上个版本到底改了哪里?或者…

2026/10/20 12:53:59 阅读更多 →

最新新闻

Obsidian标签体系完整拆解:四种方案对比与落地模板

Obsidian标签体系完整拆解:四种方案对比与落地模板

开头笔记软件换了又换,最后能让我一直留下来的,反倒是 Obsidian 里那套看起来不起眼的标签系统。我见过不少人把 Obsidian 当成文件夹管理器,一个笔记塞进一个目录,回头找资料就翻了天;也见过更夸张的,半年…

2026/10/20 22:19:42 阅读更多 →
逆向工程自动化:REA与x64dbg-MCP的Agent协同分析实践

逆向工程自动化:REA与x64dbg-MCP的Agent协同分析实践

1. 逆向工程工作流的现状与痛点拆解1.1 传统逆向分析的真实节奏搞过逆向的人都有一个共同感受:这活儿本质上是个"体力活脑力活"的混合体。你拿到一个二进制文件,先扔进反编译器看伪代码,遇到看不懂的地方切到调试器下断点&#xff…

2026/10/20 22:19:42 阅读更多 →
C++实现线程同步的四种方式总结

C++实现线程同步的四种方式总结

前言 多线程编程的核心难点不在「怎么开线程」,而在「多个线程同时访问同一份数据时,如何保证结果可预期」。C 标准把没有同步保护的并发读写称为数据竞争(data race),而数据竞争是未定义行为(undefined be…

2026/10/20 22:19:42 阅读更多 →
通用Agent架构设计:大脑+技能+护栏,重构软件意图驱动新范式

通用Agent架构设计:大脑+技能+护栏,重构软件意图驱动新范式

1. 从“功能堆叠”到“意图驱动”:通用Agent到底在改什么过去十几年,我们做软件的方式基本没变过:产品经理画页面,后端定义接口,前端拼组件,测试写用例,最后打包发版。用户打开一个App&#xff…

2026/10/20 22:19:42 阅读更多 →
JMeter分布式压测Docker化实践:从原理到排坑

JMeter分布式压测Docker化实践:从原理到排坑

第一次在一次大促前的性能摸底中,我把JMeter分布式压测环境从一台台物理机迁到了Docker上,原以为只是把启动命令换成容器方式执行,结果光RMI连接就排查了一个下午。稳定跑起来之后我才确信,这个方向选对了——它解决了我过去两年在…

2026/10/20 22:19:42 阅读更多 →
知识蒸馏进阶:变分信息蒸馏VID原理与实战

知识蒸馏进阶:变分信息蒸馏VID原理与实战

1. 从知识蒸馏的瓶颈说起如果你这两年一直在跟进模型压缩和知识蒸馏方向,大概率会有一种感觉:传统KD(Knowledge Distillation)那套“软标签KL散度”的玩法,在早期分类任务上确实好使,但一旦碰到特征维度高、…

2026/10/20 22:18:29 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →