PyTorch快速入门:深度学习框架初探
引言:为什么选择PyTorch?

记得刚进公司的时候,我被分配到了一个AI组,负责开发一个图像分类项目。那时我对深度学习的框架一知半解,只知道TensorFlow和PyTorch这两个名字,但在实际使用上完全没有经验。
刚开始几天,前辈们让我先学学PyTorch,说它在研究领域用得越来越多了。当时的我心里直打鼓:“真的比TensorFlow更简单吗?”但事实证明,PyTorch的确非常适合上手快、实验性强的项目,特别是对于我们这些刚接触深度学习的新手来说。
今天我就结合自己的亲身经历,分享一下我是如何从零开始上手PyTorch,以及在这个过程中踩过的坑、学到的经验。希望能帮你在学习PyTorch的路上少走点弯路。
项目背景与挑战:图像分类的起点

我们当时做的项目是“商品类别识别”。用户上传一张图片,系统要能自动判断这是哪一类的商品——比如衣服、电子产品、食品等。数据集来自电商网站的公开数据(当然是脱敏处理过的),总共有10个类别,每个类别的样本数量大概在2万张左右。
听起来是不是挺标准的一个图像分类任务?但真正做起来才发现问题不少:
- 数据不平衡:有些类别数据多得吓人,有些却特别稀有。
- 图像分辨率参差不齐:有的清晰到像素级,有的模糊得像是隔着毛玻璃。
- 硬件资源有限:我们只能跑单卡训练,没有GPU集群。
而我们的目标是,在两周内完成一个初步模型的训练和验证。时间紧、任务重,必须选一个上手快、调试方便的框架。于是,我们选择了PyTorch。
解决方案:PyTorch到底适合哪些场景?
如果你也遇到类似的情况,比如:
- 想快速实现一个想法
- 需要频繁调整网络结构
- 希望代码可读性高、便于调试
那PyTorch真的很适合你!
相比静态图机制的TensorFlow,PyTorch采用的是动态计算图(Dynamic Computation Graph),也就是大家常说的“define-by-run”,这意味着每一条操作都会立即执行,而不是先定义再运行。这对于调试非常友好,尤其是当你写完一行代码就想知道输出是什么样的时候,简直不要太爽。
我们的整体思路如下:
- 搭建基础模型:用预训练的ResNet-18作为backbone,微调部分层。
- 数据增强:统一输入大小、颜色空间转换、随机翻转等。
- 数据采样策略:使用WeightedRandomSampler来缓解类别不平衡的问题。
- 模型优化器选择:Adam + 学习率衰减策略。
- 性能评估:准确率+混淆矩阵分析关键错误来源。
整个过程都是用PyTorch来实现的。
代码实践:从零开始构建你的第一个PyTorch项目
1. 安装与环境配置
首先当然是安装PyTorch,建议用pip或者conda安装:
pip install torch torchvision torchaudio
这里要注意版本兼容性,推荐使用torchvision一起安装,因为很多常用的数据集和transform都封装在其中。
我们用了一个简单的Dataloader结构:
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, WeightedRandomSampler
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
train_dataset = datasets.ImageFolder(root='data/train', transform=transform)
val_dataset = datasets.ImageFolder(root='data/val', transform=transform)
# 构建sampler解决数据不平衡问题
targets = train_dataset.targets
class_counts = [i for i in list(Counter(targets).values())]
weights = 1. / np.array(class_counts)
samples_weights = weights[targets]
sampler = WeightedRandomSampler(weights=samples_weights,
num_samples=len(samples_weights),
replacement=True)
train_loader = DataLoader(train_dataset, batch_size=64, sampler=sampler)
val_loader = DataLoader(val_dataset, batch_size=64)
这一段看似简单,其实非常重要。尤其是那个WeightedRandomSampler,如果不加的话,训练中模型会偏向样本多的类别,严重影响最终效果。
2. 构建模型:迁移学习实战
接着我们用预训练的ResNet-18来初始化网络,并冻结前面几层:
import torch.nn as nn
import torchvision.models as models
model = models.resnet18(pretrained=True)
# 冻结所有层
for param in model.parameters():
param.requires_grad = False
# 只微调最后的全连接层
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 10) # 假设总共有10个类别
model = model.to(device) # device可以是'cuda'或'cpu'
然后定义损失函数和优化器:
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.fc.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)
注意我们只对最后一层fc启用梯度更新,其余参数冻结。这样可以在保证性能的同时节省训练时间。
3. 开始训练
训练的逻辑其实和传统Python程序差不多,只是多了backward和step:
def train_model(model, dataloader, criterion, optimizer, device):
model.train()
running_loss = 0.0
corrects = 0
for inputs, labels in dataloader:
inputs = inputs.to(device)
labels = labels.to(device)
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item() * inputs.size(0)
corrects += torch.sum(preds == labels.data)
epoch_loss = running_loss / len(dataloader.dataset)
epoch_acc = corrects.double() / len(dataloader.dataset)
return epoch_loss, epoch_acc
这个函数会在每个epoch中调用一次,每次训练完后打印loss和accuracy。
踩坑经验:那些年我们一起踩过的坑
🐞 1. 数据预处理搞错了Normalize参数
一开始我没仔细看文档,直接用了ImageNet的标准Normalization参数 [0.5, 0.5, 0.5],结果模型训练半天也没涨点。后来发现官方说明里已经指出应该用:
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
这玩意儿直接影响输入特征的分布,千万不能乱改。
🐞 2. GPU内存溢出 OOM
有一次我贪心地把batch size设成了128,结果报错 CUDA out of memory。后来改成64还勉强能跑。这时候我才明白,PyTorch默认不会自动释放显存,一定要控制batch size和模型大小之间的平衡。
建议新手用以下方式检查当前显存占用情况:
torch.cuda.memory_allocated() / (1024 ** 2) # MB
🐞 3. 误用了DataLoader的shuffle参数
之前我在用了WeightedRandomSampler的情况下又加上了shuffle=True,导致两个抽样逻辑互相冲突,训练效果大打折扣。后来查了文档才知道,一旦用了自定义的sampler,就不需要再设置shuffle=True了。
效果总结:两周后的收获
经过两周的努力,我们在测试集上的top-1准确率达到了82.3%,虽然不是很高,但对于一个刚起步的团队来说已经是不错的开始。
更重要的是,我们通过这个项目熟悉了PyTorch的工作流程,掌握了从数据加载、模型构建、训练优化、到评估指标的一整套工作链,为后续更复杂的模型打下了坚实的基础。
经验分享:给新手的几点建议
如果你现在正准备入坑PyTorch,不妨参考下面几个小建议:
✅ 1. 动态图 vs 静态图:按需选择
PyTorch适合快速原型设计和科研实验,TensorFlow更适合工业部署。如果你主要在做算法研究或者需要灵活性,PyTorch绝对是首选。
✅ 2. 多写Debug代码:print一切可能的东西
PyTorch不像Jupyter那样可以实时看到变量内容,所以你可以适当加入一些打印语句,观察输入shape、loss值是否合理。
print(f"Input shape: {inputs.shape}, Labels: {labels[:5]}")
✅ 3. 利用好torchvision和pretrained库
PyTorch生态里有很多现成的数据集、模型、Transform工具,不要自己造轮子。多查官方文档,事半功倍。
✅ 4. 多画图!可视化很重要
可以用Matplotlib或seaborn来画混淆矩阵、loss曲线,帮助发现问题所在:
import matplotlib.pyplot as plt
plt.plot(loss_history)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()
✅ 5. 记录好实验日志
别怕麻烦,建议你为每一次训练建立一个log文件,记录learning rate、batch size、acc、备注等等。后期你会发现这些日志简直就是救命稻草。
后记:从PyTorch开始,不止于PyTorch
如今回过头来看,PyTorch只是一个工具,但它却打开了我进入深度学习世界的大门。它教会我如何动手、如何调试、如何迭代改进。
也许你也会在某个深夜因为一个bug抓耳挠腮,但我相信,只要坚持下去,你一定能感受到那种“终于跑通”的喜悦。
希望这篇文章对你有帮助,也欢迎留言交流你们在PyTorch实践中遇到的有趣故事。毕竟,技术之路从来不是一个人的战斗。
作者:一位互联网公司的AI开发者,经历过从0到1构建深度学习项目的全过程,热爱分享技术点滴。

评论 0