首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【论文复现】YOLOv1代码复现

【论文复现】YOLOv1代码复现

作者头像
Eternity._
发布2024-11-27 08:22:02
发布2024-11-27 08:22:02
7460
举报
文章被收录于专栏:登神长阶登神长阶

论文介绍


复现论文名称:You Only Look Once: Unified, Real-Time Object Detection 论文作者:Joseph Redmon, Santosh Divvala, Ross Girshick, Ali Farhadi 该论文就是YOLOv1,YOLOv1是YOLO系列目标检测算法的第一个版本,由Joseph Redmon等人于2015年提出。它是一种端到端的卷积神经网络,以极高的速度实现目标检测,尤其在实时应用中表现出色

主要内容


YOLO系列都包括:输入端、Backbone、Neck,Head 其中 输入端:含有输入数据(图片or视频)、数据增强算法以及预处理操作部分 Backbone结构:核心特征提取器 Neck结构:V3版本才有,参考了FPN的特征融合思想,明显提升小物体的检测效果 Head结构:包含Head检测头、损失函数以及Head结构的优化策略

实验部分


1.卷积网络结构


在数据集上进行训练卷积层。预训练使用下图的前20个卷积层,再跟上后边的平均池化层以及一个全连接层。

2.计算损失

___

背景概率损失 坐标损失 类别预测损失 只有前景概率(三四行)达到一定值,判断为真的存在检测目标的时候,才会接着计算坐标损失(第一二行)和类别预测损失(第五行)。因此预测损失不是对每一个gird cell都做的。 在该文章中是用一周时间达到在ImageNet 2012数据集上88%的精度,整了一个预训练权重方便计算。

核心代码


原代码是c语言,这里代码是参考了C语言的pytorch代码,用的ResNet网络,省事

代码语言:javascript
复制
class ResNet(nn.Module):
    def __init__(self, block, layers):
        
        super(ResNet, self).__init__()
        # 通道数64
        self.inplanes = 64
        # 卷积层和池化层
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        # block块
        self.layer1 = self._make_layer(block, 64, layers[0])
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
        # output_block
        self.layer5 = self._make_out_layer(in_channels=2048)
        # 将输出变为30个通道数 7*7*30
        self.avgpool = nn.AvgPool2d(2)  # kernel_size = 2  , stride = 2
        self.conv_end = nn.Conv2d(256, 30, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn_end = nn.BatchNorm2d(30)
        # 参数初始化
        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, block, planes, blocks, stride=1):

    def _make_out_layer(self, in_channels):

    def forward(self, x):
        # 网络就长这样
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = self.layer5(x)
        x = self.avgpool(x)
        x = self.conv_end(x)
        x = self.bn_end(x)
        x = F.sigmoid(x)  # sigmoid归一化到0-1
        # 改代码只要保证最后是7,7,30就行
        x = x.permute(0, 2, 3, 1)  # (-1,7,7,30)
        return x

关于7x7x30的张量: 7x7是把整张图像分成7x7个 30=(2x4+2x1+20) 其中4代表4个边框坐标信息 x y w h 1代表是否包含需要检测的目标 2代表每个格子上有两个候选框(会拿概率是否包含检测目标概率高的候选框出来用) 20是因为测试的voc2012数据集由20个类别 当1这个概率有大于一个阈值的时候,就会调用20个类别概率中概率最高的那个作为目标检测概率 得到一张图片的7x7x30的张量之后,需要生成目标数据的7x7x30的张量 生成目标数据由于类别概率是确定的,所以1的部分概率均是P概率=1,20部分只有在对应类别概率是P=1,其余都是P=0

缺点


一个图片只能有98个检测框(7x7x2),在经过非极大值抑制后剩下的框更少,就容易有漏检。没有更好平衡小目标和大目标损失。


编程未来,从这里启航!解锁无限创意,让每一行代码都成为你通往成功的阶梯,帮助更多人欣赏与学习!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 论文介绍
  • 主要内容
  • 实验部分
    • 1.卷积网络结构
    • 2.计算损失
  • 核心代码
  • 缺点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档