YOLOv4-Pytorch开发API时加载yolov4-tiny权重出现shape无效的RuntimeError
问题现象
- 基于YOLOv4-Pytorch开源项目二次开发搭建Flask推理API时,在调用
m.load_weights(weight_file)加载yolov4-tiny.weights预训练权重的流程中,触发报错:RuntimeError: shape '[256, 384, 3, 3]' is invalid for input of size 767781 - 代码适配说明:已将原项目中
tool目录下的darknet2pytorch模块重命名为Darknet.py,适配本地导入逻辑,其余推理流程未做自定义结构修改。
问题定位思路
- 报错本质拆解:PyTorch执行张量reshape操作时,目标shape要求的总元素数量和当前输入张量的实际元素数量不匹配。计算可知目标shape
[256, 384, 3, 3]的总元素数为2563843*3=884736,但实际从权重文件读取到的有效元素数仅为767781,两者存在116955个元素的差值。 - 数值差值匹配校验:该差值刚好对应YOLOv4-tiny末端两个检测头的全部可训练参数量,说明权重读取流程出现了层索引错位:本该读取卷积层权重的位置,实际读取到了检测头的层参数,整体读取指针发生了固定偏移。
- 错位常见触发原因:
- 本地配置文件与预训练权重的结构不匹配,比如cfg中手动修改了类别数、anchor数量、卷积层通道数,和官方预训练权重的网络结构完全对应不上
Darknet.py模块的权重加载逻辑存在适配bug,对无参数的网络层(上采样、Route拼接、Shortcut残差连接)没有正确处理读取指针偏移,导致后续所有层的参数读取位置全部错位
具体修复方案
- 第一步:校验配置与权重的匹配性
- 重新获取和当前网络结构完全对应的官方yolov4-tiny预训练权重,校验文件完整性:官方发布的yolov4-tiny.weights文件大小约为23MB,文件大小偏差过大说明权重损坏或版本不匹配。
- 打开本地
./cfg/yolov4-tiny.cfg做结构核对:- 两个YOLO检测层的
classes参数为80,和data/coco.names的类别总数对应 - 两个YOLO层的
mask值分别为0,1,2和3,4,5,和默认anchor分组匹配 - 网络各卷积层的通道数顺序和官方cfg完全一致,没有手动新增、删除或修改层结构
- 两个YOLO检测层的
- 第二步:修正Darknet权重加载的错位逻辑
打开Darknet.py的load_weights方法,重点修正两处核心bug:- 卷积层权重的reshape维度顺序:Darknet格式的卷积权重存储顺序为
[输出通道数, 输入通道数, 卷积核高, 卷积核宽],reshape时需要严格匹配该顺序,不要使用错误的维度排列导致元素数计算偏差 - 无参数层的指针偏移逻辑:上采样层、Route层、Shortcut层本身没有可训练参数,读取权重时需要保持读取指针的位置不变,不要随意前进或后退指针位置,避免造成后续所有层的参数读取错位
- 卷积层权重的reshape维度顺序:Darknet格式的卷积权重存储顺序为
- 第三步:增加加载过程的校验逻辑
在权重加载的循环中加入每层的参数数校验:读取每层权重前,先计算当前层目标shape的总元素数,和权重文件剩余可读元素数做对比,数值不匹配时直接抛出对应层的错位提示,避免所有参数读完后才触发无明确上下文的reshape报错。 - 第四步:验证加载流程
权重加载完成后,构造随机输入张量(1, 3, 416, 416)执行一次全流程前向推理,若前向无shape类报错,说明权重和网络结构完全对齐,再接入Flask接口的调用逻辑即可。
内容的提问来源于stack exchange,提问作者Varun Singh
相关产品推荐
相关产品推荐

