尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

深入解析:PyTorch张量切片的陷阱:视图与副本

深入解析:PyTorch张量切片的陷阱:视图与副本
📅 发布时间:2026/6/20 1:54:08

问题导入:

        在使用PyTorch框架开发中,你是否也也遇到过这样的问题,就是明明获取了张量的切片,却发现修改了原张量后,切片的结果也跟着变!

        我今天训练一个一个做下游mask完形填空任务的语言模型,

在书写整理函数是,我是这样写的:

然后正常训练模型

过程中发现我的训练指标一下就变得非常好看

损失值下降非常快,正确率可以用飙升来形容。

我觉得不可思议,所以决定把训练好的模型,去加载出来做测试

可是测试结果就是:

无论我预测什么句子,结果都是:

[MASK]

可问题出在哪里呢? 我检查了几遍代码,确定逻辑没有问题的,那为题出在哪??

没错!就是前面在获取正式标签时,没有做拷贝,只是用了切片。

一起看看看

使得模型训练时,只要将第16位置的值预测为[MASK]就可以将损失值降到最低,从而得到虚高的
训练指标,但是本质模型值学会了,预测为[MASK] ,任何句子都是将16位置预测为[MASK]

原因解析

这里我先写一段测试代码

import torch
arr =[
[1,2,3,4,5],
[4,5,6,7,8]
]
arr = torch.tensor(arr)
result = arr[:,3]
print(result)  # tensor([4,7])
arr[:,3]=8
print(result)  # tensor([8,8])

这里可以发现,改变原始张量,通过切片获取的值也发生了改变、

但是这时候,可能很多朋友们回想为什么?

直觉告诉我们result应该保存修改前的值[4,7],但实际输出却是修改后的值[8,8]。这与 Python 列表的行为截然不同:

在看看列表

# Python列表的行为
arr = [
[1,2,3,4,5],
[4,5,6,7,8]
]
result = [row[3] for row in arr]  # 列表推导式获取第3列
for row in arr:
row[3] = 8
print(result)  # 输出:[4, 7](保持原始值)

为什么会有这种差异?

答案就藏在 "视图" 与 "副本" 的区别中。

核心原理:视图(View)不是副本(Copy)

PyTorch 中,张量的切片操作返回的是视图(view) 而非副本(copy):

  • 视图:只是原张量数据的一个引用,不占用额外内存,与原张量共享同一块数据存储空间
  • 副本:是原数据的完整复制,占用独立的内存空间,与原张量互不影响

这种设计是为了提高计算效率 —— 在处理大型张量时,频繁复制数据会导致内存浪费和性能下降。PyTorch 默认采用视图方式,避免了不必要的数据复制。

在我们的例子中:

  1. result = arr[:,3]创建了一个视图,指向arr第 3 列的内存地址
  2. arr[:,3] = 8修改了这块内存中的值
  3. 因此result也会显示修改后的值

如何解决

获取真正的副本如果需要获取不受原张量影响的独立切片,可使用.clone()方法显式创建副本:

import torch
arr = torch.tensor([
[1,2,3,4,5],
[4,5,6,7,8]
])
result = arr[:,3].clone()  # 创建副本而非视图
arr[:,3] = 8
print(result)  # 输出:tensor([4, 7])(保持原始值)

.clone()会创建一个全新的张量,拥有独立的内存空间,后续对原张量的修改不会影响副本。

所以之前我的获取label值的代码应该改为:

总结:

哪些操作返回视图,哪些返回副本?

PyTorch 中常见的返回视图的操作:

  • 基本切片操作(如arr[:, 3]、arr[1:3, :])
  • .view()方法(重塑张量形状)
  • .transpose()和.permute()(维度转换)

返回副本的操作:

  • .clone()(显式复制)
  • .detach()(在计算图中分离并复制)
  • 某些高级索引操作(如使用列表索引arr[[0,2], :])

注意:注意:高级索引(如arr[[0,1], [2,3]])通常返回副本,但具体行为可能因情况而异,建议通过.clone()确保获得副本。

相关新闻

  • 英语_阅读_Industry 4.0_待读
  • Python获取CPU和内存使用率
  • 深入解析:实战:基于 BRPC+Etcd 打造轻量级 RPC 服务——从注册到调用的核心架构与基础实现

最新新闻

  • 2026年6月宁波生成式引擎GEO优化服务商技术实力解析 - 起跑123
  • 2026 年南通市厨卫屋顶防水修缮三家对比测评 吉修匠 99.8 分稳居榜首 - 吉修匠
  • 表主必存!2026年宝玑官方售后中心实地体核验报告:全国网点最新地址、电话同步升级启用 - 亨得利中国服务中心
  • ApexSQL Log 2018:SQL Server事务日志可视化分析与精准回滚工具
  • 孤能子视角:涌现的本体论、动力学与认识论
  • Redis的数据结构

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号