求一个把yolov4在pytorch中训练的.pth权重文件转为在darknet中训练的.weight权重文件的脚本
1条回答 默认 最新
关注
不知道你这个问题是否已经解决, 如果还没有解决的话:- 这篇博客也许可以解决你的问题👉 :yolov3(pytorch)训练问题,完美解决./darknet无法运行问题
- 除此之外, 这篇博客: YOLOv3 损失函数详解【论文笔记 + pytorch实现 附.pth权重文件】中的 2 Darknet-53网络结构 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
首先回想一下
YOLOv2中提出的Darknet-19网络结构作为主干特征提取网络。考虑到对于小物体的检测,结合FPN(特征金字塔)的思想,YOLOv2简单添加一个 passthrough layer,把浅层特征图(分辨率为26 × 26,即提取特征图的倒数第二卷积层结果)连接到深层特征图。通过把高低分辨率的特征图做连结,叠加相邻特征到不同通道(而非空间位置),类似于ResNet中的identity mappings。在YOLOv3中,作者可能觉得Darknet-19网络还是不够深(因为更深的网络结构可以学习到更加丰富的特征),故再次借鉴ResNet网络和FPN(特征金字塔)的思想,提出了
Darknet-53
网络结构,如下图所示(图片来源)。
Darknet53中的Residual Block
进行一次3X3、步长为2的卷积,然后保存该卷积结果layer;再进行一次1X1的卷积和一次3X3的卷积,并把这个结果加上layer作为最后的结果。 残差网络的特点是容易优化,并且能够通过增加相当的深度来提高准确率。其内部的残差块使用了跳跃连接,缓解了在深度神经网络中增加深度带来的梯度消失问题。上图中左半部分虚线框内即为Darknet-53网络机构,可以看到该网络结构的输入为
416×416×3
,之后通过一个3×3
的卷积层来扩增通道数。接下来通过堆叠一系列Residual Block来构建网络,其具体个数为[1, 2, 8, 8, 4]
,最终主干网络输出大小为13×13、26×26、52×52
三个大小的特征图,目的是可以检测到图像中更小的物体。特征图分割越密集,则每一个特征点相对于原图中的区域越小,从而可以监测到更小的物体。下图为9种先验框的尺寸,其中蓝色框为聚类得到的先验框。黄色框是ground truth,红框是检测对象中心点所在的网格。
Darknet-53主干网络代码如下:
import torch import torch.nn as nn import math from collections import OrderedDict # 基本的darknet块 class BasicBlock(nn.Module): def __init__(self, inplanes, planes): # resnet block中是 先进行一个1×1卷积 再进行一个3×3卷积 super(BasicBlock, self).__init__() self.conv1 = nn.Conv2d(inplanes, planes[0], kernel_size=1, # 1×1卷积目的是下降通道数 stride=1, padding=0, bias=False) self.bn1 = nn.BatchNorm2d(planes[0]) self.relu1 = nn.LeakyReLU(0.1) self.conv2 = nn.Conv2d(planes[0], planes[1], kernel_size=3, # 3×3卷积目的是扩张通道数,注意这里并不减少特征图的大小!! stride=1, padding=1, bias=False) # 这样做可以帮助减少参数量 self.bn2 = nn.BatchNorm2d(planes[1]) self.relu2 = nn.LeakyReLU(0.1) def forward(self, x): residual = x out = self.conv1(x) out = self.bn1(out) out = self.relu1(out) out = self.conv2(out) out = self.bn2(out) out = self.relu2(out) out += residual return out class DarkNet(nn.Module): def __init__(self, layers): super(DarkNet, self).__init__() self.inplanes = 32 self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=3, stride=1, padding=1, bias=False) # 第一个卷积 3->32 self.bn1 = nn.BatchNorm2d(self.inplanes) self.relu1 = nn.LeakyReLU(0.1) self.layer1 = self._make_layer([32, 64], layers[0]) self.layer2 = self._make_layer([64, 128], layers[1]) self.layer3 = self._make_layer([128, 256], layers[2]) self.layer4 = self._make_layer([256, 512], layers[3]) self.layer5 = self._make_layer([512, 1024], layers[4]) self.layers_out_filters = [64, 128, 256, 512, 1024] # 进行权值初始化 for m in self.modules(): if isinstance(m, nn.Conv2d): n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels m.weight.data.normal_(0, math.sqrt(2. / n)) elif isinstance(m, nn.BatchNorm2d): m.weight.data.fill_(1) m.bias.data.zero_() def _make_layer(self, planes, blocks): # 进行下采样且不断堆叠残差块 layers = [] # 下采样,步长为2,卷积核大小为3,用于减少特征图尺寸 layers.append(("ds_conv", nn.Conv2d(self.inplanes, planes[1], kernel_size=3, stride=2, padding=1, bias=False))) layers.append(("ds_bn", nn.BatchNorm2d(planes[1]))) layers.append(("ds_relu", nn.LeakyReLU(0.1))) # 加入darknet模块 self.inplanes = planes[1] for i in range(0, blocks): layers.append(("residual_{}".format(i), BasicBlock(self.inplanes, planes))) return nn.Sequential(OrderedDict(layers)) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu1(x) x = self.layer1(x) x = self.layer2(x) out3 = self.layer3(x) out4 = self.layer4(out3) out5 = self.layer5(out4) return out3, out4, out5 # pretrained为权重文件路径 def darknet53(pretrained, **kwargs): model = DarkNet([1, 2, 8, 8, 4]) if pretrained: if isinstance(pretrained, str): model.load_state_dict(torch.load(pretrained)) else: raise Exception("darknet request a pretrained path. got [{}]".format(pretrained)) return model
网络结构的右半部分包括将主干网络Darknet-53的输出进行生成特征金字塔。具体做法为首先将
13×13×1024
的特征层进行上采样变为26×26×256
,再与26×26×512
的特征层进行堆叠,其结果为26×26×768
大小的特征;同理,大小为52×52×256
的特征层与下一层网络堆叠后的结果为52×52×384
。
对于这三个堆叠后的结果,分别在进行5次卷积操作,最后接上一个3×3
的卷积和1×1
的卷积,用于输出预测结果,三个层对应的输出结果大小分别为13×13×75、26×26×75、52×52×75
。其中75 = (4+1+20)×3
,4表示一个边界框对应的调整参数x, y, w, h
,1表示置信度,20表示VOC数据集分为20个类,3表示特征图上的每一个点对应有3个anchor。 - 以下回答来自chatgpt:
我可以为您提供一份将yolov4在pytorch中训练所得的.pth权重文件转换为darknet中训练所需的.weight权重文件的脚本。
首先,您需要安装好Pytorch和Darknet框架,并下载好权重文件。
步骤如下:
1.新建weights文件夹,在其中放入pytorch训练得到的.pth权重文件和darknet的配置文件。请确保配置文件和权重文件的名称和路径与下面的代码中相对应。
2.在终端中运行以下代码:
pip install pytorch2darknet # 导入相关库 import pytorch2darknet # 输入pytorch权重文件路径和darknet的cfg配置文件路径,生成相应的.darknet权重文件 pytorch2darknet.pytorch_2_darknet('path_to_pytorch_weights.pt', 'path_to_darknet_cfg.cfg', output_path='output_path_to_weights.weight')
将上述代码中的“path_to_pytorch_weights.pt”替换为pytorch训练得到的.pth权重文件的路径;将“path_to_darknet_cfg.cfg”替换为darknet配置文件的路径;将“output_path_to_weights.weight”替换为将要输出的权重文件的路径。
提醒:如果您使用的不是yolov4,而是其他版本的yolo,请将以上过程中的“darknet.cfg”文件换成您所使用yolo对应的cfg文件。
希望能对您有所帮助!
如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^解决 无用评论 打赏 举报
悬赏问题
- ¥200 csgo2的viewmatrix值是否还有别的获取方式
- ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
- ¥15 请把下列每一行代码完整地读懂并注释出来
- ¥15 pycharm运行main文件,显示没有conda环境
- ¥15 易优eyoucms关于二级栏目调用的问题
- ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
- ¥15 为什么eclipse不能再下载了?
- ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
- ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
- ¥15 特定网页无法访问,已排除网页问题