Dark in My eyes 2023-04-25 23:43 采纳率: 0%
浏览 41
已结题

yolov4权重文件.pth转.weight

求一个把yolov4在pytorch中训练的.pth权重文件转为在darknet中训练的.weight权重文件的脚本

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-04-26 09:10
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:
    • 这篇博客也许可以解决你的问题👉 :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文件。

      希望能对您有所帮助!


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月27日
  • 赞助了问题酬金15元 4月26日
  • 创建了问题 4月25日

悬赏问题

  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 易优eyoucms关于二级栏目调用的问题
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题