【机器学习深度学习】张量基本操作

目录

一、张量基本操作

1.1 执行代码

 1.2 运行结果

1.3 代码解析

 ✅ 1. 创建张量(tensor、randn、zeros)

✅ 2. 索引与切片(类似 NumPy)

✅ 3. 形状变换(reshape、转置、压缩)

✅ 4. 数学运算(逐元素 + 矩阵乘 + 求和)

✅ 5. 广播机制(不同维度也能加)

✅ 6. 内存共享验证(view 是原数据的视图)

二、什么是张量(Tensor)

三、示例代码中有哪些“张量”

四、小结一句话:


一、张量基本操作

1.1 执行代码

#张量的基本操作import torch
# ==============================
# 1. 张量的基本操作
# ==============================
print("="*50)
print("1. 张量基本操作示例")
print("="*50)# 创建张量
x = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)
y = torch.randn(2, 3)  # 正态分布随机张量
z = torch.zeros(3, 2)
print(f"创建张量:\n x={x}\n y={y}\n z={z}")# 索引和切片
print("\n索引和切片:")
print("x[1, 2] =", x[1, 2].item())  # 获取标量值
print("x[:, 1:] =\n", x[:, 1:])# 形状变换
reshaped = x.view(3, 2)  # 视图操作(不复制数据)
transposed = x.t()       # 转置
squeezed = torch.randn(1, 3, 1).squeeze()  # 压缩维度
print(f"\n形状变换:\n 重塑后: {reshaped.shape}\n 转置后: {transposed.shape}\n 压缩后: {squeezed.shape}")# 数学运算
add = x + y              # 逐元素加法
matmul = x @ transposed  # 矩阵乘法
sum_x = x.sum(dim=1)     # 沿维度求和
print(f"\n数学运算:\n 加法:\n{add}\n 矩阵乘法:\n{matmul}\n 行和: {sum_x}")# 广播机制
a = torch.tensor([1, 2, 3])
b = torch.tensor([[10], [20]])
print(a.shape)
print(b.shape)
print(f"\n广播加法:\n{a + b}")# 内存共享验证
view_tensor = x.view(6)
view_tensor[0] = 100
print("\n内存共享验证(修改视图影响原始张量):")
print(f"视图: {view_tensor}\n原始: {x}")

 1.2 运行结果

==================================================
1. 张量基本操作示例
==================================================
创建张量:
 x=tensor([[1., 2., 3.],
        [4., 5., 6.]])
 y=tensor([[ 0.1558, -1.4728,  0.0306],
        [ 0.8278,  1.3076,  0.5648]])
 z=tensor([[0., 0.],
        [0., 0.],
        [0., 0.]])

索引和切片:
x[1, 2] = 6.0
x[:, 1:] =
 tensor([[2., 3.],
        [5., 6.]])

形状变换:
 重塑后: torch.Size([3, 2])
 转置后: torch.Size([3, 2])
 压缩后: torch.Size([3])

数学运算:
 加法:
tensor([[1.1558, 0.5272, 3.0306],
        [4.8278, 6.3076, 6.5648]])
 矩阵乘法:
tensor([[14., 32.],
        [32., 77.]])

广播加法:
tensor([[11, 12, 13],
        [21, 22, 23]])

内存共享验证(修改视图影响原始张量):
视图: tensor([100.,   2.,   3.,   4.,   5.,   6.])
原始: tensor([[100.,   2.,   3.],
        [  4.,   5.,   6.]])


1.3 代码解析

 ✅ 1. 创建张量(tensorrandnzeros
x = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)
y = torch.randn(2, 3)  # 标准正态分布随机数
z = torch.zeros(3, 2)
  • x 是一个 2行3列 的手动定义张量。

  • y 是一个 2x3 的 随机张量,服从 N(0,1)。

  • z 是一个 3x2 的 全零张量


✅ 2. 索引与切片(类似 NumPy)

x[1, 2].item()     # 取第1行第2列的数,结果是 6.0
x[:, 1:]           # 所有行,保留第1列以后(含1)
  • x[1, 2] = 6,就是第2行第3列的元素;

  • x[:, 1:] 等价于:

[[2, 3],[5, 6]]

✅ 3. 形状变换(reshape、转置、压缩)
x.view(3, 2)       # 重塑形状为 3行2列(原数据数量不变)
x.t()              # 转置(只支持二维):行变列、列变行
torch.randn(1, 3, 1).squeeze()  # 删除维度为1的维
  • .view() 是 PyTorch 的 reshape,不复制数据;

变形后变成:

[[1, 2],[3, 4],[5, 6]]

🔑 核心规则:总元素数量不变(2×3 = 3×2 = 6),只是重新安排形状。

  • .t() 是转置:原来 2x3 → 3x2;

.t() 进行转置,行变列、列变行,结果是:

[[1, 4],[2, 5],[3, 6]]

就像把矩阵绕主对角线翻了一下。

📌 注意:

  • .t() 只适用于二维张量;

  • 如果是三维或更高,需要用 .transpose(dim0, dim1)

  • .squeeze() 把 [1, 3, 1] 变成 [3],因为它删除所有 维度=1 的轴。

原始张量:

a = torch.randn(1, 3, 1)
print(a.shape)  # torch.Size([1, 3, 1])

这代表一个形状是 [1, 3, 1] 的张量:

它有 3 个元素,但加了两个维度为 1 的“壳”:

  • 第 1 个维度是 1(只有 1 个“通道”)

  • 第 3 个维度是 1(每个值外面包了一层)

【为啥会有维度为1的“壳”?】

很多场景(图像、批处理、模型输出)为了格式统一,会多包几层:

比如:

[Batch, Features, Channel]

即使某些维度大小为1,也会保留,以统一接口。


✅ 4. 数学运算(逐元素 + 矩阵乘 + 求和)
x + y              # 对应位置相加(维度一样)
x @ x.t()          # 矩阵乘法(2x3 与 3x2)
x.sum(dim=1)       # 每一行求和,返回 [6, 15]
  • x + y 是元素加(相同位置相加);

x =
[[1, 2, 3],[4, 5, 6]]y =
[[0.1, 0.2, 0.3],[0.4, 0.5, 0.6]]x + y =
[[1+0.1, 2+0.2, 3+0.3],[4+0.4, 5+0.5, 6+0.6]]
=
[[1.1, 2.2, 3.3],[4.4, 5.5, 6.6]]#最终结果
tensor([[1.1, 2.2, 3.3],[4.4, 5.5, 6.6]])
  • x @ x.T 是线性代数中的矩阵乘法;

这表示:

注意:@ 表示矩阵乘法,不是逐元素乘法!

x =
[[1, 2, 3],[4, 5, 6]]x.t() =
[[1, 4],[2, 5],[3, 6]]

计算过程

第一行 dot 第一列:
1×1 + 2×2 + 3×3 = 1 + 4 + 9 = 14第一行 dot 第二列:
1×4 + 2×5 + 3×6 = 4 + 10 + 18 = 32第二行 dot 第一列:
4×1 + 5×2 + 6×3 = 4 + 10 + 18 = 32第二行 dot 第二列:
4×4 + 5×5 + 6×6 = 16 + 25 + 36 = 77✅ 结果:
x @ x.t() =
[[14, 32],[32, 77]]

  • x.sum(dim=1) 结果是:

x.sum(dim=1):每一行求和x =
[[1, 2, 3],[4, 5, 6]]沿着“行的方向”(dim=1)求和:第一行:1 + 2 + 3 = 6第二行:4 + 5 + 6 = 15
[1+2+3, 4+5+6] → [6, 15]✅ 输出:
tensor([6, 15])

✅ 5. 广播机制(不同维度也能加)
a = torch.tensor([1, 2, 3])       # shape: [3]
b = torch.tensor([[10], [20]])   # shape: [2, 1]
a + b

a.shape = [3]
b.shape = [2, 1]

通过广播规则:

  • a 是一个长度为 3 的一维张量 [1, 2, 3],形状是 [3]

  • b 是一个二维张量:

[[10],[20]]

形状是 [2, 1]

🔁广播规则回顾(Broadcasting Rules)

从后往前比较维度(右对齐),满足以下任一即可广播:

  • 维度相等 ✅

  • 其中一个维度为 1 ✅

  • 缺失维度视为 1 ✅

记忆口诀:“广播先对齐,缺1来撑齐,横竖补成行列齐”

▲第一步:把 ab 的形状写完整!

即把它们“补齐维度”,方便对齐:

张量原始形状看作是二维矩阵
a[3][1, 3] → 横向一排
b[2, 1][2, 1] → 纵向两列

你可以这样想象:

a = [1, 2, 3]         →     [[1, 2, 3]]  ← 横排,1行3列  
b = [[10], [20]]      →     [[10],       ← 竖排,2行1列[20]]

▲第二步:广播机制让它们形状“变一样”

原则是:当两个张量维度不一致时,PyTorch 会尝试扩展它们

我们来手动画一下:

a 的形状 [1, 3]

[[1, 2, 3]]

想和 b 的 [2, 1] 相加,就会自动复制 2 行,变成:

[[1, 2, 3],[1, 2, 3]]   ← 广播成 [2, 3]

b 的形状 [2, 1]

[[10],[20]]

要和 [2, 3] 相加,就会复制每行的 1 个值成 3 列,变成:

[[10, 10, 10],[20, 20, 20]] ← 广播成 [2, 3]

▲第三步:相加

两个 [2, 3] 的矩阵对应位置相加:

[[1+10, 2+10, 3+10],     = [11, 12, 13][1+20, 2+20, 3+20]]     = [21, 22, 23]

最终结果是:

广播加法:
tensor([[11, 12, 13],[21, 22, 23]])

✅ 6. 内存共享验证(view 是原数据的视图)
view_tensor = x.view(6)
view_tensor[0] = 100
print(x)
  • x.view(6) 是将 x 展平成 1 维数组(6个元素);

  • 修改 view_tensor[0] = 100同时修改了原始 x 的第一个值

  • 因为 .view()共享内存的视图,不是拷贝副本。

原始张量 x 是:
x = torch.tensor([[1, 2, 3],[4, 5, 6]])
形状是 (2, 3),也就是:
行 0: [1, 2, 3]  
行 1: [4, 5, 6]

▲第一步:view_tensor = x.view(6)

这一步是把 x 重塑成一个一维向量,有 6 个元素:

view_tensor = [1, 2, 3, 4, 5, 6]  # shape: [6]

⚠️ 注意:不是复制数据!只是换了形状!它和 x 共用同一块内存。

▲第二步:view_tensor[0] = 100

修改了第一个元素,把原来的 1 改成了 100:

view_tensor = [100, 2, 3, 4, 5, 6]

因为它和 x 共享内存,所以 x 的第一个元素(也就是 x[0, 0])也被改了!

▲第三步:print(x)

现在 x 的原始矩阵变成了:

x =
[[100, 2, 3],[  4, 5, 6]]

最终结果:

x =
tensor([[100., 2., 3.],[4., 5., 6.]])

🔚 总结

操作功能易错点
.view()重塑形状会共享内存,修改影响原张量
.t()转置仅支持2D
.squeeze()去掉维度=1 的轴常用于数据降维
+元素加维度不一样时会广播
@矩阵乘法对应线性代数矩阵运算
🔚 内存共享与不共享对比图


    二、什么是张量(Tensor)

    张量(Tensor)就是“任意维度的数值容器”,一维、二维、三维、甚至 N 维都可以。

    在 PyTorch 中,所有通过 torch.tensor()torch.randn()torch.zeros()torch.view() 等操作得到的对象,都是张量

    张量就是一种 可以包含数字、并支持数学操作的多维数组。它是 PyTorch 的核心数据结构,类似于 NumPy 的 ndarray,但支持自动求导、GPU 运算等。

    🎯 更清晰地说:

    维度名称举例PyTorch 类型
    0 维标量3.14不是张量,float
    1 维向量[1, 2, 3]张量(shape=[3]
    2 维矩阵[[1, 2], [3, 4]]张量(shape=[2, 2]
    3 维张量RGB图像(3通道)张量(如 shape=[3, H, W]
    N 维高维张量NLP中词向量batch等张量

    ✅ 所以说:

    所有的矩阵、向量,乃至于多维数组,在 PyTorch 中都是张量。


    早期数学/物理中张量的严格定义:

    • 张量通常是二维或更高的数学对象

    • 标量是 0阶张量,向量是 1阶张量,矩阵是 2阶张量……

    • 所以有时人们说“张量是多维结构”,把标量另算

    但在 PyTorch / NumPy / 深度学习实际编程中

    所有数字类型(0维、1维、2维……)统一叫 张量


    角度标量是不是张量?解释
    数学传统❌ 不一定有时专门分开谈
    PyTorch 实际编程✅ 是torch.Size([]) 代表 0维张量
    NumPy 一致行为✅ 是np.array(3.14).ndim == 0

     ✅ 但注意:不是“多维才是张量”

    0维(只有一个数的情况)也是张量!

    例子:

    x = torch.tensor(7)
    print(x.shape)  # torch.Size([])
    

    这是一个0维张量,只是你看不到形状,它只有一个数字

    张量 = 标量(0维) + 向量(1维) + 矩阵(2维) + 多维数组(3维以上)

    可以理解为:

    • “张量 = 包括所有维度的数组”

    • “维度越高,数据结构越复杂,但都是张量”


    三、示例代码中有哪些“张量”

    变量名是不是张量来源注释说明
    x✅ 是torch.tensor(...)2x3 手动创建的浮点张量
    y✅ 是torch.randn(...)2x3 正态分布随机张量
    z✅ 是torch.zeros(...)3x2 全 0 张量
    x[1, 2]❌ 不是张量的元素是张量中的标量值(float),用 .item() 取出
    x[:, 1:]✅ 是x 的切片子张量,仍然是张量
    reshaped✅ 是x.view(...)同一块内存的不同形状张量
    transposed✅ 是x.t()转置后张量(2x3 → 3x2)
    squeezed✅ 是squeeze()压缩维度后的张量
    add✅ 是x + y张量加法结果(形状相同)
    matmul✅ 是x @ x.t()张量矩阵乘法结果
    sum_x✅ 是x.sum(dim=1)每行求和后的张量(形状为 [2]
    a✅ 是torch.tensor(...)一维张量,shape: [3]
    b✅ 是torch.tensor(...)二维张量,shape: [2, 1]
    a + b✅ 是广播相加后的结果shape: [2, 3]
    view_tensor✅ 是x.view(6)原张量的“扁平化视图”
    view_tensor[0]❌ 不是单个元素张量里的一个标量,不再是张量本体

     

    四、小结一句话:

    只要是 torch.xxx(...) 创建出来的、或张量切片、变换、计算出来的结果,都是张量;
    只有 .item()[i][j] 取出的是具体数字(标量),不是张量。

     

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

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    【微信小程序】8、获取用户当前的地理位置

    1、获取当前的地理位置 获取当前的地理位置、速度。当用户离开小程序后,此接口无法调用。开启高精度定位,接口耗时会增加,可指定 highAccuracyExpireTime 作为超时时间。 注意: 地图相关使用的坐标格式应为 gcj02。高频率调用会…

    Jenkins 常用定时构建脚本

    Jenkins 常用定时构建脚本 Jenkins 使用 cron 风格的语法来配置定时构建任务,以下是常用的定时构建脚本示例和说明: 基本语法 Jenkins 定时构建使用五个字段表示时间,格式为: MINUTE HOUR DOM MONTH DOWMINUTE - 分钟 (0-59)H…

    ActiveMQ漏洞复现

    以下内容均在nextcyber靶场环境中完成,请勿用于非法途径! ActiveMQ 反序列化漏洞(CVE-2015-5254) Apache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息…

    环保处理设备远程运维管理解决方案

    在环保产业蓬勃发展的当下,环保处理设备厂商面临着愈发激烈的市场竞争。为助力环保处理设备厂商在竞争中脱颖而出,御控工业智能网关打造了一套完善的PLC数据采集设备运维管理平台解决方案。此方案凭借其独特优势,能为环保处理设备厂商带来显著…

    嵌入式学习笔记DAY43(ARM架构)

    一、RAM分类 sram(静态随机存取存储器): 原理:使用晶体管来存储二进制数据0和1,通过双稳态电路(由多个晶体管组成)来保持数据状态,只要持续供电,数据就能稳定保存。数据读…

    2025国际无人机应用及防控大会四大技术专题深度解析

    2025国际无人机应用及防控大会四大技术专题深度解析 2025国际无人机应用及防控大会四大技术专题深度解析1 无人机系统技术专题技术特点与应用领域国内领军企业及案例风险挑战与发展方向 2 测控与通信导航技术专题技术创新与应用突破领先企业及解决方案现存问题与发展趋势 3 任务…

    DD3118S:USB3.0+Type-c双头TF/SD二合一高速0TG多功能手机读卡器ic

    DD3118S封装是QFN42, GL3224封装是QFN32 ,设计同样一款3.0读卡方案,GL3213S需要电容、电阻外围器件一起要29颗,而DD3118S只需要13颗,方案精简且设计简单 DD3118S支持USB3.0Type-c双头TF/SD二合一 ,高速0TG多功能手机读…

    如何在FastAPI中玩转GitHub认证,让用户一键登录?

    title: 如何在FastAPI中玩转GitHub认证,让用户一键登录? date: 2025/06/22 09:11:47 updated: 2025/06/22 09:11:47 author: cmdragon excerpt: GitHub第三方认证集成通过OAuth2.0授权码流程实现,包含用户跳转GitHub认证、获取授权码、交换访问令牌及调用API获取用户信息四…

    深入JVM:从零到实战,解锁Java性能与调优的终极武器

    “什么?你还在写CRUD?面试官问个JVM调优直接哑火?线上服务OOM了只能重启大法?” —— 别慌,掌握JVM,你也能成为团队里的“定海神针”! 作为一名Java开发者,无论你是刚入行的新人还是…

    MyBatis 中的 resultType 与 resultMap:区别、使用场景及示例详解

    目录 一、什么是 resultType 1. 定义 2. 特点 3. 使用场景 4. 示例 示例 1:返回一个实体类对象 对应的 Java 类: 示例 2:返回 Map 集合 返回的每个记录是一个 Map,例如: 二、什么是 resultMap 1. 定义 2. …

    Mac安装Apache CXF的时候报错:/Library/Internet: No such file or directory

    该问题的原因因为配置的JAVA_HOME环境变量路径中的包括空格字符导致的错误。 一、问题排查 输出当前环境变量 $JAVA_HOME的路径地址,观察路径中是否存在空格 echo $JAVA_HOME二、问题解决 将JAVA_HOME路径改为你安装的jdk路径,注意你的版本号可能与我的会…

    npm(或pnpm)时报:证书过期 certificate has expired问题

    项目场景: 提示:这里简述项目相关背景: 首先安装pnpm npm install -g pnpm //检查安装成功的版本 pnpm -v 在拉芋道管理系统,安装依赖pnpm i 时报证书过期 更改了镜像也一样 解决方案: 提示:这里填写该…

    回归预测 | Matlab实现KAN神经网络多输入单输出回归预测模型

    回归预测 | Matlab实现KAN神经网络多输入单输出回归预测模型 目录 回归预测 | Matlab实现KAN神经网络多输入单输出回归预测模型效果一览基本介绍程序设计参考资料 效果一览 基本介绍 KAN作为这两年最新提出的机制,目前很少人用,很适合作为预测的创新点&…

    人生笔记Real:记录生活点滴,守护珍贵记忆

    在快节奏的现代生活中,我们常常会有一些瞬间的灵感、难忘的经历或者需要记录的重要事项。然而,如何高效地记录这些内容,并确保它们不会随着时间的流逝而丢失,成为了一个值得思考的问题。《人生笔记Real》正是这样一款简单好用的笔…

    自动驾驶数据特征提取实战:用Python打开智能驾驶的新视角

    自动驾驶数据特征提取实战:用Python打开智能驾驶的新视角 聊起自动驾驶,很多朋友第一时间想到的可能是“车上的摄像头多牛,传感器多先进”,但让我告诉你,真正决定自动驾驶“大脑”能不能跑得顺畅、跑得准的,是数据的“骨头”—特征。 没错,机器学习、深度学习的基础都…

    从零搭建共享棋牌室物联网系统:硬件选型与避坑指南!

    近来,24小时共享棋牌室凭借“低成本、无人化、高坪效”的特点成为创业热点。但许多项目在硬件选型阶段就踩坑不断——设备不兼容、安装返工、售后无门等问题频发。本文将结合实战经验,手把手教你从零搭建稳定可靠的棋牌室物联网硬件系统,并附…

    NPM 依赖包版本号 `~` 和 `^` 的区别及最佳实践

    本文将深入浅出地解释 ~ 与 ^ 在 package.json 中的含义,并结合实际开发流程给出团队协作与发布上线的最佳版本管理策略。 一、版本号的基本结构 NPM 依赖的版本号遵循 SemVer(语义化版本) 标准: 主版本号.次版本号.补丁号Major…

    uniapp报错Cannot read property ‘dataset‘ of null

    如果你引入的组件在uniapp分包路径中,就会报错

    服务器常见问题以及解决方案

    以下是服务器常见问题及对应的维护解决方案,涵盖硬件、网络、软件、安全等核心场景,基于最新行业实践整理: 一、硬件层故障‌ 硬盘失效‌ 现象‌:系统崩溃、IO错误、SMART告警。 解决‌: 立即更换故障盘&#xff0c…

    企业级 Java 应用灰度发布设计方案与实践全解析

    引言 在当今互联网产品快速迭代的背景下,如何在保证服务稳定性的同时,快速验证新功能的有效性,成为了技术团队面临的重要挑战。灰度发布(Canary Release)作为一种重要的发布策略,能够将新版本逐步推向部分用…