PyTorch:张量(Tensors)

2 阅读3分钟

PyTorch:张量(Tensors)

本示例实现一个三阶多项式模型,通过最小化欧式距离平方和,拟合区间 ([-π, π]) 内的正弦函数 (y=\sin(x))。

该实现基于 PyTorch 张量手动完成:

  • 前向传播计算预测值
  • 损失函数计算误差
  • 反向传播计算梯度

PyTorch 张量(Tensor)与 numpy 数组核心功能基本一致

  • 本质是通用的 n 维数组,本身不感知深度学习、计算图或梯度
  • 仅用于通用数值计算
  • 最大区别:PyTorch 张量可在 CPU 或 GPU 上运行,只需将张量转换为 CUDA 数据类型即可利用 GPU 加速

运行输出

99 365.8406677246094
199 261.43798828125
299 187.56802368164062
399 135.29942321777344
499 98.31527709960938
599 72.14590454101562
699 53.62869644165039
799 40.52601623535156
899 31.254634857177734
999 24.694162368774414
1099 20.051958084106445
1199 16.76709747314453
1299 14.442694664001465
1399 12.7979097366333
1499 11.634037017822266
1599 10.810457229614258
1699 10.22767448425293
1799 9.815286636352539
1899 9.523466110229492
1999 9.316967010498047
Result: y = -0.02365858480334282 + 0.8562836647033691 x + 0.00408150115981698 x^2 + -0.0932653546333313 x^3

完整代码

import torch
import math

# 设置数据类型和计算设备
dtype = torch.float
device = torch.device("cpu")
# device = torch.device("cuda:0")  # 取消注释即可在 GPU 上运行

# 创建输入和输出张量
# 在[-π, π]区间生成2000个均匀分布的点,指定设备和数据类型
x = torch.linspace(-math.pi, math.pi, 2000, device=device, dtype=dtype)
y = torch.sin(x)  # 生成正弦函数的真实值

# 随机初始化权重参数(标量张量),指定设备和数据类型
a = torch.randn((), device=device, dtype=dtype)
b = torch.randn((), device=device, dtype=dtype)
c = torch.randn((), device=device, dtype=dtype)
d = torch.randn((), device=device, dtype=dtype)

learning_rate = 1e-6  # 学习率
for t in range(2000):  # 迭代2000次
    # 前向传播:计算预测值y
    # 多项式公式:y = a + b*x + c*x² + d*x³
    y_pred = a + b * x + c * x ** 2 + d * x ** 3

    # 计算并打印损失(每100次迭代打印一次)
    # loss.item() 将张量类型的损失值转换为Python标量
    loss = (y_pred - y).pow(2).sum().item()
    if t % 100 == 99:
        print(t, loss)

    # 反向传播:手动计算a、b、c、d关于损失的梯度
    grad_y_pred = 2.0 * (y_pred - y)  # 损失对y_pred的梯度
    grad_a = grad_y_pred.sum()        # 损失对a的梯度
    grad_b = (grad_y_pred * x).sum()  # 损失对b的梯度
    grad_c = (grad_y_pred * x ** 2).sum()  # 损失对c的梯度
    grad_d = (grad_y_pred * x ** 3).sum()  # 损失对d的梯度

    # 梯度下降更新权重
    a -= learning_rate * grad_a
    b -= learning_rate * grad_b
    c -= learning_rate * grad_c
    d -= learning_rate * grad_d

# 打印最终拟合的多项式公式,.item()提取张量中的标量值
print(f'Result: y = {a.item()} + {b.item()} x + {c.item()} x^2 + {d.item()} x^3')

脚本运行耗时

0 分 0.221 秒

总结

  1. PyTorch 张量与 numpy 数组功能相似,但核心优势是支持 GPU 加速,只需修改 device 参数即可切换计算设备;
  2. 本示例仍手动实现反向传播(梯度计算),张量操作与 numpy 语法高度相似,降低了学习成本;
  3. 关键API说明:.item() 用于提取张量中的标量值,torch.linspace() 生成指定区间的均匀分布张量,torch.randn() 生成随机初始化的张量。