Keras YOLOv3环境搭建实战:版本匹配与依赖安装避坑指南
刚把 yolov3 的环境搭完准备跑个 demo 验证一下结果一执行命令就是一连串的报错。折腾了一整天最后发现全是版本匹配的问题——TensorFlow、Keras、Python 三者之间稍微错一个版本整个环境就起不来。我估计不少人和我一样在一开始安装的时候觉得没什么等真正跑起来才发现坑全在后面。这篇就把我实际踩过并解决的 Keras yolov3 环境搭建全过程整理出来从版本选型到依赖安装再到权重转换和推理 Demo 跑通最后补充训练前的环境准备希望对正在搭这套环境的同学有帮助。1. 为什么环境搭不出来问题多半不在算法代码上第一次搭 Keras yolov3 环境的时候我犯了一个很典型的错误——直接从网上复制一段安装命令装完了就以为完事了。结果运行python convert.py转换权重的时候直接报AttributeError当时第一反应是代码有问题去翻了半天源码最后才发现是 TensorFlow 版本的问题。这类项目大多是基于 2018 年到 2020 年前后的代码库写的那个时间段主流的深度学习框架版本和现在完全不一样。很多当时的代码用的是 TensorFlow 1.x 的 API比如tf.Session()、tf.placeholder()而在 TensorFlow 2.x 里这些接口要么被移除了要么行为完全变了。如果你直接装最新版的 TensorFlow 跑老代码报错几乎是必然的。换个角度说环境搭建失败的主要原因不是代码本身而是版本生态的不兼容。Python 版本、TensorFlow 版本、Keras 版本、NumPy 版本、OpenCV 版本每一样都会互相影响。简单梳理一下常见的报错和原因大概是这些AttributeError: module tensorflow has no attribute Session装的是 TensorFlow 2.x代码是 1.x 写的ImportError: cannot import name keras from tensorflowTensorFlow 和独立 Keras 版本冲突TypeError: __init__() got an unexpected keyword argument axisNumPy 版本太高某些接口签名变了ModuleNotFoundError: No module named cv2OpenCV 没装或者装的是纯 headless 版本如果你在搜索资料的时候看到有人说装最新版就能跑别全信。这类老项目的正确打开方式是先确定项目的代码基线再反推与之兼容的环境版本。这比一股脑装最新版要靠谱得多。2. 环境选型对比几组我在本地与服务器上验证过的版本组合既然问题出在版本匹配上那最省力的办法就是找一组经过验证的版本组合直接照着装。下面我把验证过的组合列出来分 CPU 和 GPU 两种场景。先说 CPU 场景这也是我建议新手第一步先搭的环境。CPU 环境不用处理 CUDA、cuDNN 这些显卡驱动相关的东西安装步骤少很多适合先把代码流程跑通。我实际验证过这样一组组合组件推荐版本备注Python3.6 或 3.7太高容易遇到依赖包不兼容TensorFlow1.14.0 或 1.15.0与 Keras 2.2.4 配合最稳Keras2.2.4经典搭配兼容性好NumPy1.16.4 或 1.17.x过高会报接口错误OpenCV4.1.x处理图像输入输出Pillow6.2.1 左右图像加载用h5py2.10.0 左右保存模型权重格式这套组合我实测过多次无论在本地笔记本还是服务器上跑model.predict()或训练脚本都没有问题。唯一要注意的是Python 3.6 现在已经比较老了如果你系统里自带的是 3.9 或 3.10建议用 conda 单独建一个 3.6 的环境不要动系统默认的 Python。再说 GPU 场景。如果你手里有 NVIDIA 显卡想用 GPU 加速训练那环境的复杂度会明显上一个台阶。核心难点在于 TensorFlow、CUDA、cuDNN 三者的版本必须咬合。TensorFlow 1.14 对应 CUDA 10.0cuDNN 7.4 左右TensorFlow 1.15 则对应 CUDA 10.0 和 cuDNN 7.5。如果你显卡驱动版本太新装老版本的 CUDA 工具包可能不识别这时候要么换 TensorFlow 2.x要么换一套旧驱动。我建议的取舍标准是这样的如果只是跑推理优先 CPU 环境省心如果要训练模型再考虑 GPU 环境而且一定要先确认显卡驱动版本再决定 CUDA 版本最后才定 TensorFlow 版本。顺序反了后面全是坑。3. 动手搭建conda 隔离环境与依赖安装完整流程确定版本组合之后正式进入安装环节。我强烈建议用 conda 创建一个独立环境不要直接往系统 Python 里塞东西。原因很简单这套老代码的依赖和很多现代项目冲突隔离之后即使这个环境废了删掉重建就是不牵连其他项目。创建环境的命令如下conda create -n yolo3-keras python3.6 conda activate yolo3-keras环境创建好之后先安装核心依赖。我这里给出一组实测过的安装顺序先装 TensorFlow再装 Keras然后装 OpenCV 和其他辅助库。顺序不要乱因为 TensorFlow 安装时会自动带一些基础依赖如果先装别的可能会把版本弄乱。pip install tensorflow1.14.0 pip install keras2.2.4 pip install opencv-python4.1.2.30 pip install numpy1.16.4 pip install h5py2.10.0 pip install pillow6.2.1有几个细节要特别提一下。第一国内网络环境下载大文件时经常超时建议给 pip 配上国内镜像源一般能提速不少pip install -i 镜像地址 tensorflow1.14.0第二安装完 TensorFlow 之后先做个简单验证再装后面的东西python -c import tensorflow as tf; print(tf.__version__)如果这一步能正常打印版本号说明 TensorFlow 安装成功。这里用得上一个判断技巧——先验证层层依赖的底座再往上装别的排查问题会更高效。第三有时候pip install tensorflow1.14.0会提示找不到这个版本原因是新版 pip 的源里对某些旧版本的索引做了过滤。解决方法是把 pip 的源切换到官方源或者通过--index-url参数指定以前碰到过一次用镜像源反而找不到老版本切回官方源就好了。这种小问题最容易让人怀疑人生所以单独拿出来提醒一下。4. 模型文件准备权重下载与转换以及下载慢的替代方案环境装好只是第一步真正要跑起来还需要模型权重文件。Keras yolov3 项目里一般有两个关键文件一个是 YOLOv3 的原始权重文件另一个是用转换脚本生成的 Keras 权重文件通常是.h5格式。原始的 YOLOv3 权重在海外服务器上从国内直接下载经常是龟速几十分钟都下不完不说还有可能下到一半断掉。这里提供一个可行的替代思路先找一个中转下载的方式把权重文件临时放在自己的网盘或者服务器里再从这些地方拉下来会稳定很多。权重文件到手之后就看项目里有没有convert.py这样的转换脚本了。没有的话自己写一个也行核心逻辑就是用yolo_weights作为输入读原始权重然后按照模型结构把每一层的参数填进去最后保存为.h5。这个脚本需要注意一点模型结构定义必须和原始权重严格对齐层名、层顺序、filter 数量都不能有偏差否则权重匹配不上跑出来的结果是乱的。转换完可以验证一下python convert.py -w yolov3.cfg -c yolov3.weights -o model_data/yolo_weights.h5执行成功会看到类似Saved Keras weights to model_data/yolo_weights.h5的输出。如果这里报错常见原因有两个一是 OpenCV 缺了某个模块二是 NumPy 版本不对。回到上一节的环境组合重新核对一遍基本能解决。顺带提醒一下如果你的目标是训练自定义数据集这个步骤可以放到后面因为训练初始化时可以直接用yolo_weights.h5做预训练权重也可以从随机初始化开始。但从零训练收敛很慢多数场景下还是建议用预训练权重做冷启动。5. 跑通一个 Demo从命令行推理到常见报错排查权重文件准备好环境也装好了到了最激动人心的环节——跑一张图片试试。项目里一般自带yolo.py或yolo_video.py这样的推理脚本调用YOLO类加载模型然后对图像执行目标检测。用命令行推理的典型方式是这样python yolo_video.py --image --input path/to/your/image.jpg一切顺利的话你会看到终端打印出检测到的目标类别和置信度同时在图片上画出边界框。但说实话第一次跑很少有人一次就过。我把实际过程中碰到的高频报错整理成一张排查表报错信息根本原因解决方案ValueError: Negative dimension size caused by subtracting...输入图像尺寸过小或模型输入尺寸配置不对把输入尺寸统一设置成 416x416或对图像做 letterbox 填充TypeError: fetch argument None has invalid type模型输入占位符和 TF 版本不匹配核对 TF 1.x/2.x 的占位符写法必要时给tf.keras兼容层做 patchKeyError: yolo_model加载 h5 权重时层名对不上确认转换脚本的 cfg 文件和权重版本一致PermissionError: [Errno 13]模型文件没有读权限chmod r model_data/*.h5或检查路径CUDA_ERROR_OUT_OF_MEMORY显卡显存不足或别的进程占了显存减小批量大小或先释放显存必要时把config.gpu_options.allow_growth设成 True这里面最容易忽略的是图像输入尺寸的问题。YOLOv3 内部会对输入图像做缩放但是如果你传入的图像尺寸太小比如只有几十像素特征图尺寸会变成负数直接触发维度报错。好的做法是在送入模型之前先做 letterbox 填充把图像等比缩放到 416x416多余部分用灰色填充这样既能保留完整画面又能满足模型输入要求。第一次跑通 Demo 之后建议你做两件事一是把整个推理流程封装成函数方便后面批量处理图片二是用一个公开的测试图片集跑一遍检测确认边界框、类别、置信度输出都正常。这一步能帮你确认环境本身没问题后面无论是训练还是部署都在这个基础上进行。如果跑视频推理像yolo_video.py这种方式OpenCV 需要支持VideoWriter编码如果发现avcodec相关的报错一般是 OpenCV 是精简版导致的换成opencv-python完整版即可。建议第一次先用图片测试视频后面再说因为视频推理涉及逐帧处理踩的坑更多。6. 为训练做准备GPU 环境、配置修改与环境自查清单跑通推理之后很多人会直接开始准备训练自己的数据集。这一步之前有几个环境相关的准备工作建议先做好避免训练到一半才发现环境不满足。第一个是 GPU 环境的确认。训练比推理吃显存太多了如果你要用 GPU 训练建议先执行下面这段代码确认 TensorFlow 能否正常调用 GPUimport tensorflow as tf sess tf.Session(configtf.ConfigProto(log_device_placementTrue))或者用 TF 1.x 的tf.test.is_gpu_available()来判断。如果显示False先别急着找代码问题八成是 CUDA 或 cuDNN 没配对或者驱动版本太老。这块没有捷径只能按驱动 → CUDA → cuDNN → TensorFlow的顺序逐层排查。有个小技巧是先看nvidia-smi输出的 CUDA 版本再和 TensorFlow 要求的版本做比对偏差太大基本就是罪魁祸首。第二个是classes.txt和配置文件。训练前你要编辑模型配置里的类别列表把默认的 COCO 80 类改成你自己的类别名称同时yolo3.cfg里的classes和filters也要对应修改。这里特别容易出错的是filters的计算公式每个 yolo 层的 filter 数量 3 * (类别数 5)即每个格子预测 3 个锚框每个锚框有 4 个坐标、1 个目标置信度和类别数。如果你改完类别数但 filter 没同步改直接训练会报InvalidArgumentError说维度不匹配。第三个是显存配置。老版本 TensorFlow 默认会一次性占满可用显存多个进程跑的时候就会互相争抢。建议在训练脚本开头加上显存按需增长的设置import tensorflow as tf config tf.ConfigProto() config.gpu_options.allow_growth True sess tf.Session(configconfig)这样模型不会一上来就把显存占满多进程协同训练的时候也会友好很多。最后我给自己总结了一份环境自查清单每次换新机器搭环境都用它过一遍省了很多重复排查Python 版本是否在 3.6~3.7 之间TensorFlow 与 Keras 是否是经过验证的搭配组合NumPy 版本是否过高OpenCV 是否能正常导入且支持视频编码权重文件是否已转换且能被模型加载推理脚本能否对单张图片正常输出结果GPU 场景下nvidia-smi是否显示 CUDA 版本训练配置里的类别数、filter 数是否同步修改这套流程走一遍基本能把环境相关的坑都排掉。最近一次在另一台新机器上搭环境我用这份清单只花了半小时就全部搞定对比第一次搭的时候花了一整天找问题效率差得不是一点半点。如果你正卡在某个报错上建议先拿这份清单对一遍大概率能省下不少时间。