当前位置: 首页 > news >正文

Tensor的常用计算方法(torch示例说明)

Tensor(张量)是多维数组的泛化概念,在深度学习和科学计算中被广泛使用。以下是Tensor的常用计算方法,涵盖基础操作和高级应用。

一、基础创建与属性

1. 创建Tensor

import torch# 从Python列表创建
tensor_from_list = torch.tensor([[1, 2], [3, 4]])# 特殊初始化
zeros_tensor = torch.zeros(2, 3)      # 2x3的全0张量
ones_tensor = torch.ones(2, 3)        # 2x3的全1张量 
rand_tensor = torch.rand(2, 3)        # 2x3的随机张量(0-1均匀分布)
randn_tensor = torch.randn(2, 3)      # 2x3的标准正态分布张量tensor = torch.randint(1, 20, (2, 3)) # 1-20的2x3 int类型数字# 类似已有张量
new_tensor = torch.zeros_like(rand_tensor)  # 形状和类型与rand_tensor相同的全0张量

2. Tensor属性

x = torch.rand(2, 3, 4)
print(x.shape)      # 形状: torch.Size([2, 3, 4])
print(x.dtype)      # 数据类型: torch.float32
print(x.device)     # 存储设备: cpu/cuda
print(x.requires_grad)  # 是否计算梯度

二、基本数学运算

1. 元素级运算

a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])# 加法
c = a + b       # 等价于 torch.add(a, b)
c = torch.add(a, b, out=torch.empty(3))  # 指定输出tensor# 其他运算
d = a - b       # 减法
e = a * b       # 逐元素乘法(Hadamard积)
f = a / b       # 逐元素除法
g = a ** 2      # 平方
h = torch.sqrt(a)  # 平方根

2. 广播机制

x = torch.ones(2, 3)
y = torch.tensor([1, 2, 3])
z = x + y  # y被广播为[[1,2,3], [1,2,3]]

3. 矩阵乘法

  • 一维向量乘法 点积(内 外积)
import torch# 创建两个一维向量
v1 = torch.tensor([1, 2, 3])
v2 = torch.tensor([4, 5, 6])# 点积计算
dot_product = torch.dot(v1, v2)
print(f"向量点积结果:\n{dot_product}\n")
"""
向量点积结果:
tensor(32)
解释:1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
"""# 外积计算
outer_product = torch.outer(v1, v2)
print(f"向量外积结果:\n{outer_product}\n")
"""
向量外积结果:
tensor([[ 4,  5,  6],[ 8, 10, 12],[12, 15, 18]])
解释:结果矩阵的每个元素是v1[i] * v2[j]
"""
  • 二维矩阵乘法  
# 创建两个2x3和3x2的矩阵
mat1 = torch.tensor([[1, 2, 3], [4, 5, 6]])  # 2x3
mat2 = torch.tensor([[7, 8], [9, 10], [11, 12]])  # 3x2# 矩阵乘法
matrix_product = torch.mm(mat1, mat2)
print(f"二维矩阵乘法结果:\n{matrix_product}\n")
"""
二维矩阵乘法结果:
tensor([[ 58,  64],[139, 154]])
解释:
[1*7 + 2*9 + 3*11, 1*8 + 2*10 + 3*12] = [58, 64]
[4*7 + 5*9 + 6*11, 4*8 + 5*10 + 6*12] = [139, 154]
"""# 逐元素乘法(Hadamard积)
# 创建两个相同形状的矩阵
mat_a = torch.tensor([[1, 2], [3, 4]])
mat_b = torch.tensor([[5, 6], [7, 8]])# 逐元素乘法
elementwise_product = mat_a * mat_b
print(f"逐元素乘法结果:\n{elementwise_product}\n")
"""
逐元素乘法结果:
tensor([[ 5, 12],[21, 32]])
解释:对应位置相乘
"""
  • 三维矩阵乘法
# 创建两个3D张量 (batch_size=2, 2x3和3x2)
batch1 = torch.tensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])  # 2x2x3
batch2 = torch.tensor([[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]])  # 2x3x2# 批量矩阵乘法
batch_product = torch.bmm(batch1, batch2)
print(f"三维批量矩阵乘法结果:\n{batch_product}\n")
"""
三维批量矩阵乘法结果:
tensor([[[ 22,  28],[ 49,  64]],[[214, 244],[277, 316]]])
解释:
第一个batch:
[[1*1 + 2*3 + 3*5, 1*2 + 2*4 + 3*6],  = [22, 28][4*1 + 5*3 + 6*5, 4*2 + 5*4 + 6*6]]   [49, 64]第二个batch:
[[7*7 + 8*9 + 9*11, 7*8 + 8*10 + 9*12],  = [214, 244][10*7 + 11*9 + 12*11, 10*8 + 11*10 + 12*12]]  [277, 316]
"""#广播矩阵乘法
# 3D张量与2D矩阵相乘
batch_mat = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])  # 2x2x2
mat = torch.tensor([[1, 0], [0, 1]])          # 2x2# 广播乘法
broadcast_product = torch.matmul(batch_mat, mat)
print(f"广播矩阵乘法结果:\n{broadcast_product}\n")
"""
广播矩阵乘法结果:
tensor([[[1, 2],[3, 4]],[[5, 6],[7, 8]]])
解释:相当于每个batch中的矩阵与单位矩阵相乘,结果不变
"""
  • 不同维数混合乘法

############### 矩阵与向量乘法 ##############
# 矩阵 (2x3) 与向量 (3)
matrix = torch.tensor([[1, 2, 3], [4, 5, 6]])  # 2x3
vector = torch.tensor([1, 0, 2])               # 3# 矩阵乘向量
mv_product = torch.mv(matrix, vector)
print(f"矩阵-向量乘法结果:\n{mv_product}\n")
"""
矩阵-向量乘法结果:
tensor([ 7, 16])
解释:
[1*1 + 2*0 + 3*2] = 7
[4*1 + 5*0 + 6*2] = 16
"""############### 批量矩阵与向量乘法 ############### 批量矩阵 (2x2x3) 与批量向量 (2x3)
batch_matrix = torch.tensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])  # 2x2x3
batch_vector = torch.tensor([[1, 0, 2], [0, 1, 1]])       # 2x3# 批量矩阵-向量乘法
batch_mv_product = torch.bmm(batch_matrix, batch_vector.unsqueeze(2)).squeeze()
print(f"批量矩阵-向量乘法结果:\n{batch_mv_product}\n")
"""
批量矩阵-向量乘法结果:
tensor([[ 7, 16],[17, 23]])
解释:
第一个batch:
[[1,2,3] @ [1,0,2] = 7[4,5,6] @ [1,0,2] = 16]第二个batch:
[[7,8,9] @ [0,1,1] = 17[10,11,12] @ [0,1,1] = 23]
"""############### 批量矩阵与向量乘法 ############### 批量矩阵 (2x2x3) 与批量向量 (2x3)
batch_matrix = torch.tensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])  # 2x2x3
batch_vector = torch.tensor([[1, 0, 2], [0, 1, 1]])       # 2x3# 批量矩阵-向量乘法
batch_mv_product = torch.bmm(batch_matrix, batch_vector.unsqueeze(2)).squeeze()
print(f"批量矩阵-向量乘法结果:\n{batch_mv_product}\n")
"""
批量矩阵-向量乘法结果:
tensor([[ 7, 16],[17, 23]])
解释:
第一个batch:
[[1,2,3] @ [1,0,2] = 7[4,5,6] @ [1,0,2] = 16]第二个batch:
[[7,8,9] @ [0,1,1] = 17[10,11,12] @ [0,1,1] = 23]
"""

三、张量操作

1. 形状操作

x = torch.randn(2, 3, 4)# 改变形状
y = x.view(2, 12)       # 调整为2x12 (必须保持元素总数不变)
z = x.reshape(2, 12)     # 更灵活的reshape# 转置
t = x.transpose(1, 2)    # 交换维度1和2 → 2x4x3
p = x.permute(2, 0, 1)   # 自定义维度顺序 → 4x2x3# 压缩/扩展维度
squeezed = x.squeeze()   # 移除所有长度为1的维度
unsqueezed = x.unsqueeze(0)  # 在第0维增加维度 → 1x2x3x4

2. 连接与分割

# 连接张量
x = torch.randn(2, 3)
y = torch.randn(2, 3)
cat = torch.cat([x, y], dim=0)  # 沿dim=0连接 → 4x3
stack = torch.stack([x, y])     # 新建维度堆叠 → 2x2x3# 分割张量
chunks = torch.chunk(x, 2, dim=1)  # 沿dim=1分成2块 → 两个2x2张量
split = torch.split(x, [1, 2], dim=1)  # 按[1,2]分割 → 2x1和2x2

四、归约操作

1. 统计计算

x = torch.tensor([[1, 2], [3, 4]])# 求和
sum_all = x.sum()           # 所有元素和 → 10
sum_dim0 = x.sum(dim=0)     # 沿dim=0求和 → [4, 6]# 其他统计
mean_val = x.mean()         # 平均值
max_val, max_idx = x.max(dim=1)  # 每行最大值及索引
min_val = x.min()           # 最小值
prod = x.prod()             # 所有元素乘积

2. 比较操作

x = torch.tensor([1, 2, 3])
y = torch.tensor([3, 2, 1])eq = x == y                 # [False, True, False]
gt = x > y                  # [False, False, True]
all_close = torch.allclose(x, y, rtol=1e-5)  # 是否近似相等

五、高级操作

1. 梯度计算

x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 + 3 * x + 1
y.backward()               # 计算梯度
print(x.grad)              # dy/dx = 2x+3 → 7.0

2. 索引与切片

x = torch.randn(3, 4)# 基础索引
row = x[1]                 # 第2行
col = x[:, 1]              # 第2列
element = x[1, 2]          # (2,3)位置的元素# 高级索引
indices = torch.tensor([0, 2])
selected = x[:, indices]   # 选择第1和第3列# 布尔索引
mask = x > 0.5
filtered = x[mask]         # 所有大于0.5的元素

3. 内存操作

x = torch.tensor([1, 2, 3])
y = x.clone()              # 深拷贝
z = x.detach()             # 分离计算图(用于固定某些层)# 设备转移
if torch.cuda.is_available():x_gpu = x.cuda()       # 转移到GPUx_cpu = x_gpu.cpu()    # 转回CPU

六、实用工具方法

1. 保存与加载

torch.save(x, 'tensor.pt')         # 保存
loaded = torch.load('tensor.pt')   # 加载# 状态字典保存(常用于模型)
state = {'tensor': x, 'step': 100}
torch.save(state, 'state.pt')

2. 类型转换

x = torch.tensor([1, 2, 3], dtype=torch.float32)
y = x.int()               # 转为int32
z = x.double()            # 转为float64

3. 与NumPy互转

import numpy as np# Tensor → NumPy
a = torch.ones(3)
b = a.numpy()             # 共享内存(当在CPU时)# NumPy → Tensor
c = np.array([1, 2, 3])
d = torch.from_numpy(c)   # 共享内存

七、性能优化技巧

  1. 避免CPU-GPU频繁传输:尽量减少设备间的数据转移
  2. 使用原地操作:后缀带下划线的方法可节省内存
x.add_(y)   # 原地加法,等价于 x += y
  1. 向量化操作:尽量使用内置函数而非循环
  2. 预分配内存:对于循环中的张量操作,预先分配好内存
result = torch.empty(1000)
for i in range(1000):result[i] = i * 2

​​​​​​​

Tensor矩阵乘法与点积的区分

1. 点积 (Dot Product)

  • 仅适用于1D向量

  • 结果是一个标量值

  • 计算方式:对应位置元素相乘后求和

import torch# 示例1: 向量点积
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])dot_product = torch.dot(a, b)  # 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
print("向量点积:", dot_product)  # 输出: tensor(32)# 示例2: 使用@运算符(当操作数是1D时等同于点积)
print("a @ b:", a @ b)  # 同样输出: tensor(32)

2.矩阵乘法 (Matrix Multiplication)

  • 适用于2D矩阵或更高维张量

  • 结果是一个矩阵或张量

  • 计算方式:行与列的点积

# 示例3: 基本矩阵乘法
A = torch.tensor([[1, 2], [3, 4]])  # 2x2
B = torch.tensor([[5, 6], [7, 8]])  # 2x2# 手动计算验证:
# 第一行: [1,2]·[5,7] = 1*5+2*7=19, [1,2]·[6,8]=1*6+2*8=22
# 第二行: [3,4]·[5,7]=3*5+4*7=43, [3,4]·[6,8]=3*6+4*8=50
mat_mul = A @ B
print("矩阵乘法结果:\n", mat_mul)
# 输出:
# tensor([[19, 22],
#         [43, 50]])# 示例4: 不同形状的矩阵乘法
C = torch.tensor([[1, 2, 3], [4, 5, 6]])  # 2x3
D = torch.tensor([[1, 2], [3, 4], [5, 6]]) # 3x2# 结果应为2x2矩阵
# [1,2,3]·[1,3,5] = 1*1+2*3+3*5=1+6+15=22
# [1,2,3]·[2,4,6]=1*2+2*4+3*6=2+8+18=28
# [4,5,6]·[1,3,5]=4*1+5*3+6*5=4+15+30=49
# [4,5,6]·[2,4,6]=4*2+5*4+6*6=8+20+36=64
print("C @ D:\n", C @ D)
# 输出:
# tensor([[22, 28],
#         [49, 64]])

3. 常见混淆场景

场景1: 向量与矩阵的乘法
# 向量(1D)与矩阵(2D)相乘
v = torch.tensor([1, 2, 3])      # 形状 (3,)
M = torch.tensor([[1, 2], [3, 4], [5, 6]])  # 形状 (3,2)# 这是矩阵乘法,不是点积!
# 向量被自动视为行向量 (1x3)
# 结果是一个行向量 (1x2)
result = v @ M  # 等价于 torch.matmul(v, M)
print("向量与矩阵乘法:", result)  # 输出: tensor([22, 28])
# 计算: 1*1 + 2*3 + 3*5 = 22, 1*2 + 2*4 + 3*6 = 28
场景2: 批量矩阵乘法 (3D张量)
# 批量矩阵乘法 (3D张量)
batch_A = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])  # 形状 (2,2,2)batch_B = torch.tensor([[[2, 0], [0, 2]], [[3, 0], [0, 3]]])  # 形状 (2,2,2)# 批量矩阵乘法
# 对每个2x2矩阵独立进行乘法
batch_result = batch_A @ batch_B
print("批量矩阵乘法结果:\n", batch_result)
# 输出:
# tensor([[[ 2,  4],   # 第一个批次: [[1,2],[3,4]] @ [[2,0],[0,2]] = [[2,4],[6,8]]
#          [ 6,  8]],
#
#         [[15, 18],   # 第二个批次: [[5,6],[7,8]] @ [[3,0],[0,3]] = [[15,18],[21,24]]
#          [21, 24]]])

4. 特殊情况的等价性

只有当两个1D向量相乘时,点积和矩阵乘法结果是等价的:

u = torch.tensor([1, 2, 3])
v = torch.tensor([4, 5, 6])# 三种等效表示
print(torch.dot(u, v))      # 点积函数: tensor(32)
print(u @ v)                # @运算符: tensor(32)
print(torch.matmul(u, v))   # 矩阵乘法函数: tensor(32)

5. 错误用法示例

# 错误1: 两个2D矩阵使用dot()
try:torch.dot(A, B)  # A和B都是2x2
except RuntimeError as e:print("错误:", e)  # 输出: 1D tensors expected, but got 2D and 2D tensors# 错误2: 维度不匹配的矩阵乘法
X = torch.tensor([[1, 2]])    # 1x2
Y = torch.tensor([[3, 4, 5]]) # 1x3try:X @ Y  # 需要X的列数(2)等于Y的行数(1),但2≠1
except RuntimeError as e:print("错误:", e)  # 输出: mat1 and mat2 shapes cannot be multiplied (1x2 and 1x3)

点积 (1D + 1D → 0D):[a₁, a₂, a₃] · [b₁, b₂, b₃] = a₁b₁ + a₂b₂ + a₃b₃矩阵乘法 (2D + 2D → 2D):⎡a₁₁ a₁₂⎤   ⎡b₁₁ b₁₂⎤   ⎡a₁₁b₁₁+a₁₂b₂₁  a₁₁b₁₂+a₁₂b₂₂⎤⎣a₂₁ a₂₂⎦ @ ⎣b₂₁ b₂₂⎦ = ⎣a₂₁b₁₁+a₂₂b₂₁  a₂₁b₁₂+a₂₂b₂₂⎦向量-矩阵乘法 (1D + 2D → 1D):[v₁, v₂] @ ⎡m₁₁ m₁₂⎤ = [v₁m₁₁+v₂m₂₁, v₁m₁₂+v₂m₂₂]⎣m₂₁ m₂₂
  • 点积:用于计算相似度、注意力分数等

  • 矩阵乘法:神经网络层的核心操作(全连接层、Transformer等)

  • 批量矩阵乘法:高效处理批量数据(卷积、RNN等)

相关文章:

  • RPC - 客户端注册和发现模块
  • Unity Addressable使用之AddressableAssetSettings
  • Java UDP Socket 实时在线刷卡扫码POS消费机服务端示例源码
  • 【全开源】填表问卷统计预约打卡表单系统+uniapp前端
  • 亚马逊认证考试系列 - 第一部份:基础服务 - AWS SAA C03
  • GPT-1 与 BERT 架构
  • Duende Identity Server学习之一:认证服务器及一个Oidc/OAuth认证、用于Machine 2 Machine的客户端
  • 前端开发面试题总结-vue3框架篇(二)
  • LangServer 与 Langgraph 融合架构:构建智能语言服务系统
  • 一种新的参数高效微调方法-LoRI
  • Armbian 开机启动点灯脚本
  • Unix ODBC和Mysql ODBC
  • 【论文笔记】【强化微调】TinyLLaVA-Video-R1:小参数模型也能视频推理
  • `customRef` 在实战中的使用:防抖、计算属性缓存和异步数据获取
  • 广州华锐互动:以技术创新引领虚拟现实体验新高度
  • 基于机器学习的侧信道分析(MLSCA)Python实现(带测试)
  • 【Linux】Ubuntu 24.04 远程桌面控制
  • RA4M2开发涂鸦模块CBU(2)----配置按键开启LED
  • 神经中枢革命:对象模型耦合CMMM,AI进化引擎重塑PLM-实现智能工厂从卓越级到领航级的自驱跃迁,打造制造业数字进化操作系统
  • 【批量文件查找】根据文件名清单一次性查找多个文件复制到指定位置,批量查找文件的使用步骤和注意事项
  • 网站全网建设 莱芜/安卓优化大师旧版
  • 推荐一下网站谢谢/方法seo
  • 做建材营销型网站/搜索引擎优化工具
  • 小程序代理能赚钱吗/百度搜索关键词优化
  • 做菠菜网站好赚吗/店铺推广方案怎么写
  • 做编程的网站有哪些方面/哪些浏览器可以看禁止访问的网站