🧠 基础语法与使用
1. PyTorch --- 张量的 GPU 版本说明
在 PyTorch 中,张量的存储位置(CPU / GPU)不会自动切换 。
即使系统支持 CUDA,也需要手动指定设备(device)。
如果当前设备不支持 GPU,即便显式设置为 'cuda',也会自动回退到 CPU。
✅ 示例代码
import torch
# 1. 查看 PyTorch 版本与 CUDA 是否可用
print(torch.__version__)
print(torch.cuda.is_available())
# 2. 创建张量
cpu_tensor = torch.FloatTensor([1, 2, 3])
# 3. 自动判断可用设备(优先使用 GPU)
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 4. 显式转移张量到 GPU(或 CPU)
gpu_tensor_new = cpu_tensor.to(device)
print(f"张量设备:{gpu_tensor_new.device}")
2. PyTorch --- 常见张量创建方法
import torch
"""
张量创建方法总结:
torch.ones(size, device=None) # 创建全 1 张量
torch.ones_like(input, device=None) # 与 input 同形状的全 1 张量
torch.zeros(size, device=None) # 创建全 0 张量
torch.zeros_like(input, device=None) # 与 input 同形状的全 0 张量
torch.full(size, value, device=None) # 创建指定形状、指定值的张量
torch.full_like(input, value, device=None) # 与 input 同形状、指定值的张量
"""
# 创建一个一维全 1 张量
scalar = torch.ones(5)
print(f"scalar 张量: {scalar}, 维度: {scalar.dim()}")
# 创建与 scalar 形状相同的全 1 张量
scalar_like = torch.ones_like(scalar)
print(f"scalar_like 张量: {scalar_like}, 维度: {scalar_like.dim()}")
# 创建一个一维全 0 张量
scalar_zero = torch.zeros(5)
print(f"scalar_zero 张量: {scalar_zero}, 维度: {scalar_zero.dim()}")
# 创建一个 2×2 矩阵,值均为 100
scalar_fill_value = torch.full((2, 2), 100)
print(f"scalar_fill_value 张量:\n{scalar_fill_value}, 维度: {scalar_fill_value.dim()}")
# 创建一个与 scalar_fill_value 同形状、值为 99 的矩阵
scalar_fill_like = torch.full_like(scalar_fill_value, 99)
print(f"scalar_fill_like 张量:\n{scalar_fill_like}, 维度: {scalar_fill_like.dim()}")
🧩 运行结果:
scalar 张量: tensor([1., 1., 1., 1., 1.]), 维度:1
scalar_like 张量: tensor([1., 1., 1., 1., 1.]), 维度:1
scalar_zero 张量: tensor([0., 0., 0., 0., 0.]), 维度:1
scalar_fill_value 张量:
tensor([[100, 100],
[100, 100]]), 维度:2
scalar_fill_like 张量:
tensor([[99, 99],
[99, 99]]), 维度:2
Process finished with exit code 0
3. PyTorch --- 线性张量与随机张量
import torch
"""
张量的线性与随机生成函数:
torch.arange(start, end, step) # 等间隔序列(左闭右开)
torch.linspace(start, end, steps) # 等间隔序列(左闭右闭)
torch.rand(size, device='cpu') # 均匀分布 [0,1)
torch.randn(size, device='cpu') # 正态分布(均值0, 方差1)
torch.random.initial_seed() # 获取随机种子
torch.manual_seed(seed) # 手动设置随机种子
注意:
- CPU 串行执行,随机结果可复现;
- GPU 并行执行,随机结果不保证完全一致。
"""
# 左闭右开:生成 [1,10) 间隔为 2 的序列
scalar = torch.arange(1, 10, 2)
print(f"等间隔范围张量1: {scalar}, 设备: {scalar.device}")
# 左闭右闭:生成 [1,10] 中等间隔的 3 个点
scalar_1 = torch.linspace(1, 10, 3)
print(f"等间隔范围张量2: {scalar_1}, 设备: {scalar_1.device}")
# 均匀分布随机张量
scalar_rand = torch.rand(10)
print(f"scalar_rand 均匀分布随机张量: {scalar_rand}, 设备: {scalar_rand.device}")
# 正态分布随机张量
scalar_randn = torch.randn(2, 2)
print(f"scalar_randn 正态分布随机张量:\n{scalar_randn}, 设备: {scalar_randn.device}")
# 获取当前随机种子
scalar_seed = torch.random.initial_seed()
print(f"当前随机种子: {scalar_seed}")
# 使用相同随机种子复现结果
torch.manual_seed(scalar_seed)
cpu_randn1 = torch.randn(2, 2)
print(f"cpu_randn1:\n{cpu_randn1}")
# 固定随机种子,每次生成结果一致
torch.manual_seed(100)
cpu_randn2 = torch.randn(2, 2)
print(f"cpu_randn2:\n{cpu_randn2}")
🧮 运行结果示例:
等间隔范围张量1: tensor([1, 3, 5, 7, 9]), 设备:cpu
等间隔范围张量2: tensor([ 1.0000, 5.5000, 10.0000]), 设备:cpu
scalar_rand 均匀分布随机张量: tensor([0.03, 0.17, 0.67, 0.08, 0.23, 0.92, 0.95, 0.83, 0.96, 0.52]), 设备:cpu
scalar_randn 正态分布随机张量:
tensor([[-0.4156, -0.3852],
[ 0.4333, -0.6503]]), 设备:cpu
当前随机种子: 612789563853900
cpu_randn1:
tensor([[ 0.0428, 1.0367],
[ 0.8383, -1.1315]])
cpu_randn2:
tensor([[ 0.3607, -0.2859],
[-0.3938, 0.2429]])
4️⃣ PyTorch 张量类型与类型转换
import torch
# 每个 PyTorch 张量都有一个 .dtype 属性,返回 torch.dtype 对象,用于表示张量的数据类型。
🔹 常用数据类型对照表
| 数据类型 | 简写形式 | 含义 |
|---|---|---|
| torch.float32 | torch.float | 32 位浮点数(默认) |
| torch.float64 | torch.double | 64 位浮点数(双精度) |
| torch.float16 | torch.half | 16 位浮点数(半精度) |
| torch.int32 | torch.int | 32 位整数 |
| torch.int64 | torch.long | 64 位整数 |
| torch.int16 | torch.short | 16 位整数 |
| torch.int8 | 8 位整数 | |
| torch.uint8 | 8 位无符号整数 | |
| torch.bool | 布尔值 |
# 创建不同类型张量
float_tensor = torch.tensor([1.0, 2.0, 3.0])
int_tensor = torch.tensor([1, 2, 3], dtype=torch.int32)
bool_tensor = torch.tensor([True, False, True], dtype=torch.bool)
# 查看数据类型
print("float_tensor dtype:", float_tensor.dtype)
print("int_tensor dtype:", int_tensor.dtype)
print("bool_tensor dtype:", bool_tensor.dtype)
🔸 数据类型转换方法
| 方法 | 功能说明 |
|---|---|
tensor.to(dtype) |
转换为指定数据类型(不改变设备) |
tensor.type(dtype) |
转换为指定数据类型(同上) |
tensor.type_as(other) |
转换为与另一张量相同的数据类型 |
tensor.data.type(dtype) |
直接基于数据对象转换类型 |
# 类型转换示例
float_tensor_2 = int_tensor.to(torch.float16)
print("float_tensor_2 dtype:", float_tensor_2.dtype)
int_tensor = bool_tensor.type(torch.int32)
print("int_tensor dtype:", int_tensor.dtype)
⚠️ 注意事项
-
精度损失:从高精度(float64)→低精度(float32/int32)可能会损失数值精度。
-
数值溢出:浮点 → 整数时,若数值超出整数范围会被截断或溢出。
-
内存占用:不同数据类型占用的内存大小不同,应权衡精度与性能。
-
计算性能 :GPU 上一般使用
float32计算性能最佳。
5️⃣ PyTorch 张量与 NumPy 的类型转换
import torch
import numpy as np
🔹 为什么需要张量与 NumPy 互转?
-
生态兼容性:NumPy 是 Python 科学计算核心库,支持丰富的矩阵运算、数学函数和线性代数工具。
-
图像与信号处理:许多图像/音频库(如 OpenCV)以 NumPy 数组为输入格式。
-
数据分析:NumPy 的切片与广播机制更直观灵活。
-
设备差异:PyTorch 张量可运行在 GPU 上,而 NumPy 数组主要在 CPU 上运行。
🔸 张量 → NumPy 数组
# 创建一个 GPU 张量
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
tensor = torch.randn(3, 3, device=device)
print("原始张量:", tensor)
# 将张量转移至 CPU
tensor_cpu = tensor.cpu()
# 转换为 NumPy 数组(复制内存,防止互相影响)
numpy_array = tensor_cpu.numpy().copy()
print(f"类型转换后的数组:{numpy_array},类型:{type(numpy_array)}")
# 修改 numpy 数组的值
numpy_array[0][0] = 5
print(f"修改后的 numpy 数组:{numpy_array}")
print(f"修改后的张量:{tensor_cpu}")
⚠️ 注意:
.numpy()转换后默认共享内存 ,修改任一方会影响另一方。若不希望共享,请使用.copy()。
🔸 NumPy 数组 → 张量
# 创建一个 NumPy 数组
numpy_array_2 = np.array([[1, 2, 3], [4, 5, 6]])
print(f"原始 Numpy 数组:{numpy_array_2}")
# 转换为张量
tensor = torch.from_numpy(numpy_array_2)
print(f"转换后的张量:{tensor},类型:{type(tensor)}")
# 共享内存验证
tensor[0][0] = 5
print(f"修改后的张量:{tensor}")
print(f"修改后的 Numpy 数组:{numpy_array_2}")
✅
torch.from_numpy()共享内存❌
torch.tensor(ndarray)不共享内存(会拷贝数据)
🔹 标量张量与 Python 数字互转
print("------------ 标量张量与数字互转 --------------------")
# 张量 → 数字
scalar_4 = torch.tensor(3.14)
number_4 = scalar_4.item()
print(f"转换后的数字:{number_4},类型:{type(number_4)}")
# 数字 → 张量
number_4 = 5
scalar_4 = torch.tensor(number_4)
print(f"转换后的张量:{scalar_4},类型:{type(scalar_4)}")
⚠️
.item()仅适用于 标量张量(单个元素),否则会报错。
6️⃣ PyTorch 基本元素级与统计运算
🔸 常用算子与对应符号
| 运算 | 函数形式 | 等价写法 |
|---|---|---|
| 加法 | torch.add(a, b) |
a + b |
| 减法 | torch.sub(a, b) |
a - b |
| 乘法(点乘) | torch.mul(a, b) |
a * b |
| 除法 | torch.div(a, b) |
a / b |
| 取反 | torch.neg(a) |
-a |
🔧 以
_结尾的函数(如add_()、sub_())会 原地修改 原张量。
tensor_arr1 = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
tensor_arr2 = torch.tensor([1, 2], dtype=torch.float32)
print("a+b =", torch.add(tensor_arr1, tensor_arr2))
print("a+1 =", torch.add(tensor_arr1, 1))
print("a+b(简写):", tensor_arr1 + tensor_arr2)
print("a-b =", torch.sub(tensor_arr1, tensor_arr2))
print("a*b =", torch.mul(tensor_arr1, tensor_arr2))
print("a/b =", torch.div(tensor_arr1, tensor_arr2))
print("-a =", torch.neg(tensor_arr1))
运行结果:
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| a+b= tensor([[2., 4.], [4., 6.]]) a+b= tensor([[2., 4.], [4., 6.]]) a+1= tensor([[2., 3.], [4., 5.]]) a+b tensor([[2., 4.], [4., 6.]]) a+b(简写): tensor([[2., 4.], [4., 6.]]) a-b= tensor([[0., 0.], [2., 2.]]) a-1= tensor([[0., 1.], [2., 3.]]) a*b= tensor([[1., 4.], [3., 8.]]) a/b= tensor([[1., 1.], [3., 2.]]) -a= tensor([[-1., -2.], [-3., -4.]]) |
🔹 常用统计函数与说明
| 函数 | 作用 | 返回结果 | 常用场景 |
|---|---|---|---|
torch.mean() |
计算均值 | 平均值标量或张量 | 计算平均损失、均值归一化 |
torch.sum() |
计算总和 | 所有元素之和 | 累积求和、损失聚合 |
torch.max() |
最大值及索引 | (值, 索引) | 寻找预测类别、峰值检测 |
torch.min() |
最小值及索引 | (值, 索引) | 异常值筛选 |
torch.median() |
中位数 | 标量或张量 | 数据分布分析 |
torch.std() |
标准差 | 标量或张量 | 数据标准化、正则项计算 |
torch.var() |
方差 | 标量或张量 | 方差归一化 |
torch.mode() |
众数及索引 | (值, 索引) | 分类统计、投票集成 |
🔸 dim 参数说明
| 参数值 | 方向 | 示例 |
|---|---|---|
dim=0 |
按列计算(纵向) | 对每一列求均值 |
dim=1 |
按行计算(横向) | 对每一行求均值 |
| 未指定 | 所有元素参与计算 | 全局统计值 |
🔸 调用方式
| 调用方式 | 示例 |
|---|---|
| 函数式调用 | torch.mean(tensor) |
| 方法式调用 | tensor.mean() |
🧩 实例代码
import torch
a = torch.tensor([[1.0, 2.0],
[3.0, 4.0]])
# 基本统计计算
print(f"均值: {torch.mean(a)}") # 所有元素均值
print(f"按列求均值 dim=0: {torch.mean(a, dim=0)}") # 每列均值
print(f"总和: {torch.sum(a)}") # 所有元素之和
print(f"按列求和 dim=0: {torch.sum(a, dim=0)}") # 每列求和
print(f"标准差: {torch.std(a)}") # 标准差
# 数据标准化(Z-score 标准化)
normalized = (a - a.mean()) / a.std()
print(f"标准化后的张量:\n{normalized}")
输出结果示例:
均值: 2.5
按列求均值 dim=0: tensor([2., 3.])
总和: 10.0
按列求和 dim=0: tensor([4., 6.])
标准差: 1.29099
标准化后的张量:
tensor([[-1.1619, -0.3873],
[ 0.3873, 1.1619]])
8️⃣ PyTorch数学计算函数
🔹 常见函数及说明
| 函数 | 作用 | 数学表达 | 常见用途 |
|---|---|---|---|
torch.sqrt() |
平方根 | √x | 距离、标准差 |
torch.exp() |
指数函数 | eˣ | 激活函数、概率分布 |
torch.log() |
自然对数 | ln(x) | 损失函数、信息熵 |
torch.log2() |
以 2 为底的对数 | log₂(x) | 信息编码长度 |
torch.log10() |
以 10 为底的对数 | log₁₀(x) | 对数标度数据 |
torch.abs() |
绝对值 | x | |
torch.ceil() |
向上取整 | ⌈x⌉ | 索引取整、上限处理 |
torch.floor() |
向下取整 | ⌊x⌋ | 离散化、下限处理 |
🧩 示例代码
a = torch.tensor([[1.0, 2.0],
[3.0, 4.0]])
print("平方根:", torch.sqrt(a))
print("指数:", torch.exp(a))
print("自然对数:", torch.log(a))
print("以2为底的对数:", torch.log2(a))
print("绝对值:", torch.abs(a))
print("向上取整:", torch.ceil(a))
print("向下取整:", torch.floor(a))
💡 常见应用场景总结
| 函数 | 应用场景 |
|---|---|
sqrt() |
标准差、欧氏距离计算 |
exp() |
激活函数(Sigmoid、Softmax)、概率计算 |
log() |
信息熵、对数似然损失 |
abs() |
误差度量(如 L1 损失) |
ceil() / floor() |
索引处理、分桶离散化 |
9️⃣ PyTorch 点乘与矩阵乘法运算
点乘(Element-wise Multiplication)
🔹 概念定义
点乘(Hadamard Product) 是指两个张量对应位置的元素逐一相乘,
结果仍然是一个与输入张量形状相同的新张量。
🔹 运算规则
| 项目 | 描述 |
|---|---|
| 运算符 | * 或 torch.mul() |
| 前提条件 | 两个张量形状必须一致,或满足广播机制(broadcasting) |
| 输出形状 | 与输入张量形状相同 |
🔸 示例代码
import torch
a = torch.tensor([[1, 2],
[3, 4]])
b = torch.tensor([[5, 6],
[7, 8]])
# 点乘运算(逐元素相乘)
result = torch.mul(a, b)
print(f"矩阵与矩阵的点乘:\n{result}")
# 向量点积(内积)
c = torch.tensor([1, 2])
dot_product = torch.dot(c, c)
print(f"向量与向量的点积: {dot_product}")
输出结果:
矩阵与矩阵的点乘:
tensor([[ 5, 12],
[21, 32]])
向量与向量的点积: 5
🔹 广播机制(Broadcasting)
当两个张量的形状不同但满足特定条件时,PyTorch 会自动扩展(broadcast)较小的张量以匹配形状。
例如:
x = torch.tensor([[1, 2, 3],
[4, 5, 6]])
y = torch.tensor([1, 2, 3])
print(x * y)
输出:
tensor([[ 1, 4, 9],
[ 4, 10, 18]])
🔷 矩阵乘法(Matrix Multiplication)
🔹 概念定义
矩阵乘法是线性代数中的基础运算,计算方式为 行 × 列 的点积。
🔹 运算函数与符号
| 方法 | 说明 | 维度限制 |
|---|---|---|
torch.mm(A, B) |
二维矩阵相乘 | 仅支持 2D |
torch.matmul(A, B) |
通用矩阵乘法(支持高维广播) | 支持 n 维 |
A @ B |
与 torch.matmul(A, B) 等价 |
支持广播 |
torch.mv(A, v) |
矩阵与向量相乘 | A 为 2D,v 为 1D |
🔸 示例代码
import torch
a = torch.tensor([[1, 2],
[3, 4]])
b = torch.tensor([[5, 6],
[7, 8]])
c = torch.tensor([1, 2])
# 1️⃣ 矩阵与矩阵乘法
print(f"矩阵与矩阵的乘法:\n{torch.mm(a, b)}")
# 2️⃣ 矩阵与向量乘法
print(f"矩阵与向量的乘法:\n{torch.mv(a, c)}")
# 3️⃣ 高维矩阵乘法(推荐使用 matmul 或 @)
print(f"使用 matmul 函数:\n{torch.matmul(a, b)}")
print(f"使用 @ 符号:\n{a @ b}")
输出结果:
矩阵与矩阵的乘法:
tensor([[19, 22],
[43, 50]])
矩阵与向量的乘法:
tensor([ 5, 11])
使用 matmul 函数:
tensor([[19, 22],
[43, 50]])
使用 @ 符号:
tensor([[19, 22],
[43, 50]])
💡 常见区别与建议
| 运算类型 | 函数 | 是否支持高维广播 | 常用场景 |
|---|---|---|---|
| 点乘(逐元素) | * 或 torch.mul() |
✅ | 元素运算、Hadamard Product |
| 矩阵乘法 | torch.mm() |
❌ | 二维矩阵运算 |
| 通用矩阵乘法 | torch.matmul() / @ |
✅ | 高维矩阵、神经网络层计算 |
| 矩阵与向量乘法 | torch.mv() |
❌ | 线性代数计算 |