一次多框架实战,让我更懂深度学习工具的选择
引言:为何要对比这些深度学习框架?

三年前,我在一家做智能零售的初创公司负责视觉识别系统的搭建。当时的业务目标很明确:通过视频监控分析客户行为、商品关注度以及货架陈列情况。为了实现这一目标,我们需要在多个场景中快速迭代视觉模型,既要支持本地边缘部署,也要适配云端的大规模训练。
面对这样的需求,我们一开始并没有锁定某个特定的框架,而是计划先尝试主流的几个开源深度学习库,比如 TensorFlow、PyTorch 和 MxNet。这个过程持续了将近半年,在不断的对比和试错中,我们积累了丰富的落地经验。
这篇文章不是一篇技术论文,更像是我亲身经历的“技术踩坑笔记”。希望通过我的实际项目案例,能给你一些真实参考——特别是在选型和落地时少走弯路。
项目背景:从0到1打造一个端到端的视觉分析系统

我们的系统核心是基于视频流中的目标检测与行为分析模块。数据方面,来源于合作门店安装的200+摄像头,图像分辨率以720P为主,帧率在15fps~30fps之间不等。
项目初期的目标很简单:
- 构建一套可以识别商品货架、顾客动作(如拿起、放下)的行为识别模型
- 实现本地部署,保证响应延迟可控
- 能够进行增量训练,并适应不同环境下的光照变化
模型方面,我们一开始尝试的是经典的 Faster R-CNN + LSTM 的组合,后来迁移到了 YOLO 系列加上轻量级姿态估计方案。但真正让我们头疼的,不是模型本身,而是在各个框架下如何高效开发和部署。
问题描述:选型不当带来的连锁反应

第一个大坑出在框架选择阶段。
起初我们选择了 TensorFlow 1.x(当时 TF2 尚未广泛采用),原因有二:一是它的静态计算图更适合部署;二是社区资源丰富。但在实际使用过程中,我们遇到了几个关键问题:
- 模型构建复杂,调试困难,尤其是在自定义 loss 或数据预处理时。
- 部署模型时版本不兼容严重,导出 PB 文件和 SavedModel 常常因为内部操作符不被 TFLite 支持而导致报错。
- 训练流程臃肿,TF 1.x 中 session 机制让人抓狂。
与此同时,我们在研究新功能时发现社区很多 SOTA 模型都已经转向 PyTorch,比如 DETR、YOLOv5、HRNet 等。这促使我们决定在部分子模块上引入 PyTorch 1.8 进行试验。
结果却是冰火两重天。
虽然 PyTorch 的动态图让模型开发变得灵活又直观,但我们又在部署环节出了问题。用 TorchScript 导出 ONNX 后,在 Jetson Nano 上推理速度反而比 TensorFlow Lite 差,而且某些张量操作在转换过程中出现了精度丢失。
那段时间,我经常一边跑训练代码,一边想:“这到底该用谁?”
解决方案:因地制宜,混合使用才是王道

最终我们没有选择“非此即彼”的极端做法,而是采用了 “根据用途选择合适框架” 的策略。
框架分工如下:
| 使用目的 | 推荐框架 | 说明 |
|---|---|---|
| 模型开发/实验 | PyTorch | 动态计算图,易于调试和迭代 |
| 快速原型验证 | PyTorch + ONNX | ONNX 标准化后便于跨平台部署 |
| 边缘端部署 | TensorFlow Lite / TFLiteX | 小设备上优化最好 |
| 云服务批量训练 | TensorFlow | 支持分布式训练和自动检查点管理 |
举个具体的例子:
在我们尝试将一个改进版的 HRNet 姿态估计模型部署到边缘服务器上时,最初在 PyTorch 下开发非常顺手,但 ONNX 转换之后精度掉了 5% 左右。这个问题卡了我们将近两周时间才定位到根源 —— ONNX 对 Upsample 算子的支持不好,导致双线性插值误差放大。
最后我们转战 TensorFlow,在已有官方 pose estimation API 的基础上进行了微调,虽然改造成适合我们输入结构花了点时间,但在边缘端性能提升明显。
代码实践:关键代码片段分享
下面是一些我在项目中常用的代码片段,供你参考。
PyTorch -> ONNX 导出示例:
import torch
import torchvision
model = torchvision.models.resnet18(pretrained=True)
model.eval()
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(model,
dummy_input,
"resnet18.onnx",
export_params=True, # 存储训练参数
opset_version=11, # ONNX 算子集版本
do_constant_folding=True, # 优化常量
input_names=['input'], # 输入名
output_names=['output'], # 输出名
dynamic_axes={
'input': {0: 'batch_size'},
'output': {0: 'batch_size'}
})
TFLite 导入并推理(Python 版本):
import numpy as np
import tflite_runtime.interpreter as tflite
interpreter = tflite.Interpreter(model_path="model.tflite")
interpreter.allocate_tensors()
# 获取输入输出细节
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
# 准备输入数据
input_data = np.array(np.random.random_sample(input_details[0]['shape']), dtype=input_details[0]['dtype'])
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
# 获取输出
output_data = interpreter.get_tensor(output_details[0]['index'])
print("预测结果:", output_data)
踩坑经验:那些年我们一起掉过的坑
1. 混合精度训练别急着上,会翻车
我们曾经试图在 TensorFlow 中使用 mixed_float16 精度加速训练。看起来一切正常,但一段时间后测试准确率开始剧烈波动,甚至出现 NaN。排查了很久才发现是自定义损失函数里某些操作没对 float16 友好,最后只能降级回 float32。
经验教训:如果你用了第三方 loss,务必提前验证其在混合精度下的稳定性。
2. PyTorch Lightning 很香但别忽略底层控制
我们在中期引入了 PyTorch Lightning(PL),确实让训练流程变清晰不少。但有一次训练中断恢复时,PL 没有正确加载 optimizers 的状态,导致学习率调度器完全错乱。
最后查源码发现是版本差异引起的问题。所以即使你用了 PL,还是建议保留对底层 optimizer 的理解。
3. ONNX 导出不要只靠 shape 推断,手动加尺寸约束
有些网络结构依赖 shape 推断,在导出 ONNX 时如果输入尺寸不确定,会导致后续部署失败或性能下降。建议像下面这样显式声明输入 shape:
dynamic_axes = {
'input': {0: 'batch', 2: 'height', 3: 'width'},
'output': {0: 'batch'}
}
效果总结:框架选得好,上线快一半
经过一年的打磨,这套系统终于稳定下来,部署到了全国范围内的多家门店中。以下是几个关键成果:
- 行为识别模块在本地部署环境下延迟控制在 100ms 内,准确率达到了 91%
- 通过混合使用 PyTorch 和 TensorFlow,我们在保持模型先进性的同时也兼顾了部署效率
- 在训练成本上,借助 TensorFlow 的 tf.data.Dataset + prefetch 缓解了 IO 瓶颈,整体训练时间减少了约 30%
更有趣的是,团队成员的技术视野也随之拓宽了不少。现在看到新的论文出来,大家都能自己试试 PyTorch 实现,也能评估是否适合当前业务流程。
经验分享:关于深度学习框架的一些思考
如果你现在正站在选择框架的十字路口,这里有几点建议送你:
1. 不要盲目追求“最流行”的框架
每个框架都有自己的适用边界。PyTorch 更适合研究和实验,TensorFlow 则在生产部署上有成熟的生态。MxNet 虽然逐渐冷门了,但在 AWS Lambda 上部署却意外表现不错。
2. 多看模型仓库,少闭门造轮子
像 HuggingFace、TorchVision、TensorFlow Hub 这类资源站点,提供了大量可以直接使用的模块。合理复用这些模块,胜过反复写 DataLoader。
3. 提前考虑部署路径,否则模型再好也没用
很多人只关注模型指标,忽略了部署环节,等到准备上线才发现某些算子不支持、模型太大等问题。建议在模型设计之初就考虑部署目标,比如 Edge 设备限制内存,MobileNetv3 比 ResNet 更合适。
4. 自动化评测和可视化永远值得投入
在模型迭代过程中,我们建立了一套简单的自动化打分机制,结合 TensorBoard + Wandb,让每次调参都有明确方向。
结语:选框架就像找队友
在我眼里,深度学习框架就像是你的技术搭档。有人擅长表达,有人善于执行,有人稳扎稳打,有人锐意进取。没有谁比谁更好,只有谁更合适。
这场框架大战,最终没有赢家,有的只是不断演进的技术需求和开发者们的成长。
希望这篇实战笔记能帮你少走点弯路,找到属于你的“最佳拍档”。
👨💻 作者:某AI创业公司首席架构师,深耕CV系统落地,专注工业质检与智慧零售领域。欢迎留言交流或私信探讨更多实战经验。

评论 0