深度学习_原理和进阶_PyTorch入门(2)后续语法2

🧠 基础语法与使用


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() 指数函数 激活函数、概率分布
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() 线性代数计算
相关推荐
小白狮ww4 小时前
VASP 教程:使用 VASP 进行机器学习力场训练
人工智能·深度学习·机器学习·大模型·分子动力学·计算机程序·vasp
小年糕是糕手4 小时前
【数据结构】常见的排序算法 -- 插入排序
c语言·开发语言·数据结构·学习·算法·leetcode·排序算法
我先去打把游戏先5 小时前
ESP32C3开发指南(基于IDF):console控制台命令行交互功能
笔记·嵌入式硬件·mcu·物联网·学习·esp32·交互
摘星观月7 小时前
【深度学习5】多层感知机
人工智能·深度学习
Blossom.1187 小时前
把AI“贴”进路灯柱:1KB决策树让老旧路灯自己报「灯头松动」
java·人工智能·python·深度学习·算法·决策树·机器学习
QT 小鲜肉7 小时前
【QT/C++】Qt网络编程进阶:TCP网络编程的基本原理和实际应用(超详细)
c语言·开发语言·网络·c++·qt·学习·tcp/ip
qzhqbb7 小时前
神经网络—— 人工神经网络导论
人工智能·深度学习·神经网络
极客BIM工作室7 小时前
ControlNet:Adding Conditional Control to Text-to-Image Diffusion Models
人工智能·深度学习·机器学习
浮游本尊7 小时前
React 18.x 学习计划 - 第六天:React路由和导航
前端·学习·react.js