3. Python与深度学习基础速通:NumPy、Pandas基础、PyTorch张量操作、自动求导机制

说实话,很多同学一上来就急着搭模型,结果连数据怎么装、梯度怎么算都没搞明白。我当年也是这样,踩了不少坑。这一章咱们就把这些基本功打扎实,后面跑模型时才不会手忙脚乱。

3.1 NumPy:深度学习的数据基石

NumPy 是 Python 科学计算的灵魂。说白了,它就是帮你高效处理多维数组的工具。我在做缺陷检测时,一张 1024×1024 的晶圆图,用原生 Python 列表处理要好几秒,换成 NumPy 数组,几十毫秒就搞定。

3.1.1 创建数组

import numpy as np

# 从列表创建
arr = np.array([[1, 2, 3], [4, 5, 6]])

# 全零数组,常用于初始化权重
zeros = np.zeros((3, 4))

# 随机数组,模拟噪声数据
noise = np.random.randn(2, 3)
我的习惯:创建测试数据时,我常用 np.random.seed(42) 固定随机种子,这样每次跑结果都一样,方便调试。

3.1.2 数组运算与广播

NumPy 的广播机制,说白了就是让不同形状的数组也能做运算。举个例子:

a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([10, 20, 30])

# 广播:b 自动扩展成 [[10,20,30], [10,20,30]]
result = a + b
我曾经踩过的坑:广播虽然方便,但形状不匹配时不会报错,而是悄悄给你"补"成奇怪的结果。做缺陷分类时,有一次我把标签形状搞错了,模型居然还收敛了,但准确率死活上不去。排查了半天才发现是广播把标签"复制"错了。

3.2 Pandas:表格数据的瑞士军刀

做深度学习,数据预处理占掉 80% 的时间。Pandas 就是帮你处理 CSV、Excel 这些表格数据的利器。

3.2.1 DataFrame 基础操作

import pandas as pd

# 读取缺陷样本的 CSV 文件
df = pd.read_csv('defect_samples.csv')

# 查看前5行,快速了解数据长什么样
df.head()

# 统计缺失值
df.isnull().sum()

# 按缺陷类型分组统计
df.groupby('defect_type').size()
操作 代码 说明
筛选行 df[df['label'] == 1] 选出正样本
删除空值 df.dropna() 去掉缺失行
填充空值 df.fillna(0) 用0填充
列重命名 df.rename(columns={'old':'new'}) 改列名

实战经验:我在处理工业缺陷数据时,经常遇到标签不平衡——好样本几万张,坏样本才几十张。这时候用 df.sample(frac=1) 打乱数据,再用分层抽样保证训练集和验证集的比例一致。

3.3 PyTorch 张量操作:从 NumPy 到 GPU

PyTorch 的张量(Tensor)和 NumPy 数组长得像,但多了两个杀手锏:GPU 加速和自动求导。

3.3.1 创建张量

import torch

# 从 NumPy 转过来
np_arr = np.array([[1, 2], [3, 4]])
tensor = torch.from_numpy(np_arr)

# 直接在 GPU 上创建
if torch.cuda.is_available():
    gpu_tensor = torch.randn(3, 3).cuda()

# 需要梯度的张量(后面自动求导用)
x = torch.tensor([2.0, 3.0], requires_grad=True)

3.3.2 张量变形与运算

你想想看,一张图片在 PyTorch 里通常表示成 (batch, channel, height, width) 的形状。我刚开始总搞混维度顺序,后来养成了一个习惯:每次 reshape 前先打印 .shape 看一眼。

# 模拟一张 3 通道的 224x224 图片
img = torch.randn(3, 224, 224)

# 增加 batch 维度
img_batch = img.unsqueeze(0)  # 变成 (1, 3, 224, 224)

# 矩阵乘法(全连接层核心)
W = torch.randn(128, 256)
x = torch.randn(256)
out = W @ x  # 等价于 torch.matmul(W, x)
我建议:刚开始用 PyTorch 时,把 torch.Tensor 和 torch.nn.functional 的常用函数打印出来贴在工位上。我当年就是这么干的,一个月后基本就烂熟于心了。

3.4 自动求导机制:深度学习引擎的核心

自动求导,说白了就是 PyTorch 帮你自动算梯度。你只需要定义好前向计算,反向传播的导数它全包了。

3.4.1 计算图与反向传播

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

# 反向传播,计算 dy/dx
y.backward()

# 查看梯度
print(x.grad)  # 输出: tensor([7.]),因为 dy/dx = 2x + 3 = 7

为什么会这样?PyTorch 内部维护了一张计算图,记录了每一步操作。调用 .backward() 时,它沿着图反向传播,用链式法则算出每个参数的梯度。

3.4.2 梯度清零与优化器

这里有个新手必踩的坑:梯度会累积!

# 错误示范:梯度会累加
for i in range(3):
    y = (x ** 2).sum()
    y.backward()
    print(x.grad)  # 每次都会加上之前的梯度

# 正确做法:每次迭代前清零
optimizer = torch.optim.SGD([x], lr=0.01)
for i in range(3):
    optimizer.zero_grad()  # 梯度清零
    y = (x ** 2).sum()
    y.backward()
    optimizer.step()  # 更新参数
我曾经犯过的错:训练一个缺陷分类模型时,loss 死活不降。排查了半天,发现是忘了在每轮迭代前调用 optimizer.zero_grad()。梯度一直在累加,参数更新完全乱套了。从那以后,我写训练循环的第一件事就是把 zero_grad() 写上。

3.5 本章知识体系

下面这张图把 NumPy、Pandas、PyTorch 三者的关系串起来了。你仔细看看,它们各自负责什么,又是怎么衔接的。

深度学习基础工具链 NumPy Pandas PyTorch 多维数组 + 广播运算 随机数 / 线性代数 DataFrame 筛选 / 分组 缺失值处理 / 数据清洗 GPU 张量 + 自动求导 优化器 + 反向传播 深度学习模型训练 NumPy 负责数据加载与预处理 → Pandas 做清洗与探索 → PyTorch 做模型训练与梯度更新

嗯,这一章的内容就到这里。NumPy 和 Pandas 是数据预处理的两把刷子,PyTorch 张量和自动求导是模型训练的核心。把这些基础打牢了,后面搭 CNN、训练分类器的时候,你就能把精力放在模型设计上,而不是被这些底层操作绊住脚。