4、PyTorch基础与张量操作:PyTorch环境配置、张量创建与运算、自动求导机制、GPU加速

各位同学,欢迎来到第四章。说实话,这一章是整个图神经网络选股模型的「地基」。你想想看,后面所有的GCN、GAT、GraphSAGE,底层跑的都是张量运算。地基打不牢,后面盖楼肯定歪。我当年刚开始接触PyTorch时,也踩过不少坑,今天就把这些经验一次性分享给你们。

4.1 PyTorch环境配置:别让环境卡住你

配置环境这事儿,说简单也简单,说烦人也真烦人。我个人习惯用Anaconda来管理虚拟环境,这样不同项目之间不会打架。

核心要点:PyTorch的安装命令取决于你的CUDA版本。别盲目复制网上的命令,先查一下自己的显卡驱动支持哪个CUDA版本。

具体步骤很简单:

  1. 打开终端,创建一个新的虚拟环境:conda create -n gnn_stock python=3.9
  2. 激活环境:conda activate gnn_stock
  3. 去PyTorch官网(pytorch.org)选择对应的配置,复制安装命令。

举个例子,如果你用的是CUDA 11.8,命令大概是这样的:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

我的小技巧:如果你不确定CUDA版本,可以用 nvidia-smi 命令查看。我曾经有一次装错了CPU版本,跑模型慢得像蜗牛,排查了半天才发现是CUDA没对上。

装完之后,验证一下:

import torch
print(torch.__version__)
print(torch.cuda.is_available())  # 如果输出True,说明GPU可用

4.2 张量创建与运算:一切皆张量

张量(Tensor)是什么?说白了,它就是多维数组。标量是0维张量,向量是1维,矩阵是2维,再往上就是高维张量。在量化金融里,一只股票的历史价格序列是1维张量,多只股票的多日数据就是2维或3维张量。

4.2.1 创建张量的几种方式

我平时最常用的几种创建方式,列出来给你们看看:

方法 说明 示例
torch.tensor() 从列表或数组创建 torch.tensor([1.0, 2.0, 3.0])
torch.zeros() 创建全零张量 torch.zeros(3, 4)
torch.ones() 创建全一张量 torch.ones(2, 3)
torch.randn() 创建标准正态分布随机张量 torch.randn(5, 5)
torch.arange() 创建等差数列张量 torch.arange(0, 10, 2)

举个例子,假设我们要模拟10只股票5天的收盘价数据:

import torch

# 模拟10只股票,5天的数据
stock_data = torch.randn(10, 5)
print(stock_data.shape)  # 输出: torch.Size([10, 5])

4.2.2 张量运算:加减乘除与矩阵乘法

张量运算和NumPy非常像,但PyTorch多了自动求导的能力。基本的加减乘除就不多说了,重点说说矩阵乘法。

在选股模型里,我们经常要计算特征矩阵和权重矩阵的乘积。PyTorch提供了两种方式:

  • torch.mm():标准的矩阵乘法,只适用于2维张量。
  • torch.matmul():更通用的矩阵乘法,支持高维张量。
# 假设特征矩阵是 [10只股票 x 20个特征]
features = torch.randn(10, 20)
# 权重矩阵是 [20个特征 x 5个输出]
weights = torch.randn(20, 5)

# 矩阵乘法
output = torch.mm(features, weights)
print(output.shape)  # 输出: torch.Size([10, 5])

注意:矩阵乘法要求第一个矩阵的列数等于第二个矩阵的行数。我刚开始学的时候经常搞混维度,导致报错。建议每次运算前都打印一下 .shape 确认。

4.3 自动求导机制:PyTorch的灵魂

自动求导(Autograd)是PyTorch最核心的功能之一。你想想看,如果没有自动求导,我们得手动推导梯度公式,那对于复杂的图神经网络来说简直是噩梦。

原理其实很简单:PyTorch会记录所有张量上的操作,构建一个计算图。当你调用 .backward() 时,它会自动计算梯度。

4.3.1 开启梯度追踪

默认情况下,张量是不追踪梯度的。你需要设置 requires_grad=True

x = torch.tensor([2.0, 3.0], requires_grad=True)
y = x ** 2 + 3 * x
z = y.sum()

z.backward()  # 自动计算梯度
print(x.grad)  # 输出: tensor([7., 9.])

为什么会得到7和9?因为 y = x^2 + 3x,导数 dy/dx = 2x + 3。当 x=2 时,导数为7;当 x=3 时,导数为9。嗯,数学上完全正确。

避坑指南:我曾经在训练循环里忘记清零梯度,导致梯度不断累加,模型直接炸了。记得每次 backward() 之后调用 optimizer.zero_grad()

4.3.2 计算图与梯度累积

PyTorch的计算图是动态的,每次前向传播都会重新构建。这意味着你可以根据输入动态改变网络结构——这在处理变长序列时特别有用。

另外,默认情况下梯度是累积的。如果你有多个损失项,可以分别调用 backward(),梯度会自动累加。但大多数情况下,我们只需要一个损失函数。

4.4 GPU加速:让训练飞起来

做量化选股,数据量动不动就是几千只股票、几百个交易日、几十个特征。CPU跑起来?太慢了。GPU才是王道。

4.4.1 检查GPU是否可用

第一步,先看看你的机器有没有GPU:

if torch.cuda.is_available():
    device = torch.device("cuda")
    print(f"使用GPU: {torch.cuda.get_device_name(0)}")
else:
    device = torch.device("cpu")
    print("使用CPU")

4.4.2 将张量移动到GPU

有两种方式:

  • 创建时直接指定设备:torch.tensor([1, 2], device='cuda')
  • 创建后移动:tensor.to('cuda')
# 推荐方式:先创建,再移动
data = torch.randn(1000, 100)
data = data.to(device)

# 模型也要移动
model = MyGNNModel()
model = model.to(device)

重要提醒:张量和模型必须在同一个设备上。如果你把数据放在GPU上,但模型还在CPU,运算时会报错。我刚开始时经常犯这个错,排查了半天才发现是设备不匹配。

4.4.3 性能对比:CPU vs GPU

我做过一个简单的测试,用1000x1000的矩阵乘法,CPU用了0.5秒,GPU只用了0.02秒。对于图神经网络这种需要大量矩阵运算的模型,GPU加速是必须的。

4.5 本章知识体系总览

下面这张图是我自己画的,把本章的核心知识点串了起来。你可以把它当作一个「地图」,学完后再回来看,会更有感觉。

PyTorch基础与张量操作 - 知识体系 环境配置 张量创建与运算 自动求导机制 GPU加速 Anaconda虚拟环境 CUDA版本匹配 pip install 命令 torch.tensor / zeros / ones 矩阵乘法 mm / matmul 维度检查 .shape requires_grad=True 计算图与backward() 梯度清零 zero_grad() cuda.is_available() tensor.to(device) 模型与数据设备一致 核心目标:掌握PyTorch基础,为图神经网络选股模型打好地基

4.6 本章小结

好了,这一章的内容就到这里。我们讲了环境配置、张量创建与运算、自动求导机制,还有GPU加速。这些东西看起来基础,但每一个都是后面搭建图神经网络选股模型的基石。

我个人建议你动手敲一遍代码,别光看。只有亲手跑通了,才算真正掌握。下一章我们会开始接触图神经网络的核心概念,到时候这些基础就会派上大用场。

最后一个小提醒:如果你在运行代码时遇到任何问题,先检查三件事:设备是否一致、维度是否匹配、梯度是否清零。这三个问题占了PyTorch新手报错的80%。

专注资料整理