详解yolov1理论 代码

news2025/2/24 8:41:00

目标检测要解决的3大问题:

1、有没有?

图片中是否有要检测的物体?(检测物体,判定前景背景)

2、是什么?

这些物体分别是什么?(检测到的物体是什么)

3、在哪里?

这些物体在哪里?(画框,描边,变色都行)

yolov1模型图

在这里插入图片描述

预测结果

在这里插入图片描述

当物体中心落到某个网格中,该网格就负责预测这个物体。
每个网络会生成两个预测框,所以yolov1共有 7x7x2=98个预测框,相对于fast-rcnn成百上千个预测框,yolov1少了很多。
每个预测框对应 维度为2x5 + 20 = 30的向量。 
20代表:yolov1用的数据有20个类别。这20个类别用独热编码表示,是哪个类别就让该类别标记为1.
5代表 : 4个坐标和一个置信度。
置信度计算的是预测边框 与 真实边框的 IOU,IOU用来选择哪个边框作为预测边框。

在这里插入图片描述
参考:https://zhuanlan.zhihu.com/p/595221376

损失函数

在这里插入图片描述

1.对坐标进行预测,坐标损失

预测第i个网格,的第j个bbox是否有该object。 方法是计算每个网格的两个bbox与真实框的IOU,IOU最大bbox对应的网格中包含这个object。

在这里插入图片描述
在这里插入图片描述
如果不用根号,则是个线性关系 w越大,该物体与小物体的loss就越大。模型的学习会收到它的影响,主要去满足大物体去了。

超参数 λ_coord 默认是5,是为了平衡非物体(背景)的bbox过多的影响。因为目标对于背景来说是很小的,损失函数占比的权重就很小。

置信度损失

在这里插入图片描述
此时加入了一个非物体的置信度和权重 λnoobj=0.5,如果 让一个网络去学习n个类别的分类,那么必须让网络学习n+1个类别的分类。1是背景。背景占比比较多,所以调小它的权重。

对类别进行预测

判断是否有object的中心落入网格中,网格中包含有object的中心,就负责预测该object的类别概率。
在这里插入图片描述
直接预测类别-真实类别,这个方法不好,后面Yolo对它改进。

在这里插入图片描述
拥挤物体的中心,会跑到一个网格中去,那么一个网络就会预测两个物体。很不好。
对小物体检测也不好,小物体权重小。
对不规则物体(长宽比不正常)

voc数据集

以PASCAL VOC2017为例,它包含如下5个文件夹:

Annotations
JPEGImages
ImageSets
SegmentationClass
SegmentationObject

JPEGImages

PASCAL VOC提供的所有的图片,其中包括训练图片,测试图片。

Annotations

xml格式的标签文件,每个xml对应JPEGImage中的一张图片。各个目标的位置和类别。以(x,y)的格式不保存坐标点。
<annotation>  
    <folder>VOC2012</folder>                             
    <filename>2007_000392.jpg</filename> //文件名  
    <source>                             //图像来源(不重要)  
        <database>The VOC2007 Database</database>  
        <annotation>PASCAL VOC2007</annotation>  
        <image>flickr</image>  
    </source>  
    <size>                              //图像尺寸(长宽以及通道数)                        
        <width>500</width>  
        <height>332</height>  
        <depth>3</depth>  
    </size>  
    <segmented>1</segmented>            //是否用于分割(在图像物体识别中01无所谓)  
    <object>                            //检测到的物体  
        <name>horse</name>              //物体类别  
        <pose>Right</pose>              //拍摄角度  
        <truncated>0</truncated>        //是否被截断(0表示完整)  
        <difficult>0</difficult>        //目标是否难以识别(0表示容易识别)  
        <bndbox>                        //bounding-box(包含左下角和右上角xy坐标)  
            <xmin>100</xmin>  
            <ymin>96</ymin>  
            <xmax>355</xmax>  
            <ymax>324</ymax>  
        </bndbox>  
    </object>  
    <object>              //检测到多个物体  
        <name>person</name>  
        <pose>Unspecified</pose>  
        <truncated>0</truncated>  
        <difficult>0</difficult>  
        <bndbox>  
            <xmin>198</xmin>  
            <ymin>58</ymin>  
            <xmax>286</xmax>  
            <ymax>197</ymax>  
        </bndbox>  
    </object>  
</annotation> 

ImageSets

训练要用到的:

1.train.txt:训练集 (注意,均为图片名,没有后缀。以train.txt为例,分为两列,第一列为图像名如00012;第二列为-11-1表示目标在对应的图像没有出现,1则表示出现。)
2.val.txt:验证集
3.trainval.txt:训练和验证集
# 训练用不到的其它内容
Action:人的动作
Layout:人体的具体部位
Main: 图像物体识别的数据,总共20, 需要保证train val没有交集。
Segmentation:用于分割的数据
验证集(val)与测试集(test)是有区别的。
验证集:val是validation的简称,验证是否过拟合、以及用来调节训练参数等。
测试集:当模型训练完成后,用于检测模型的准确性。

https://blog.csdn.net/weixin_43570470/article/details/123659793

write_txt.py

'''
    读取XML文件信息
'''

import xml.etree.ElementTree as ET
import os
import random

VOC_CLASSES = (  # 定义所有的类名
    'aeroplane', 'bicycle', 'bird', 'boat',
    'bottle', 'bus', 'car', 'cat', 'chair',
    'cow', 'diningtable', 'dog', 'horse',
    'motorbike', 'person', 'pottedplant',
    'sheep', 'sofa', 'train', 'tvmonitor')   # 使用其他训练集需要更改
# 创建两个文件用于存放
train_set = open('voctrain.txt', 'w')
test_set = open('voctest.txt', 'w')
Annotations = 'VOCdevkit/VOC2017/Annotations'
# 返回Annotations文件下的所有文件名 (里面是所有xml文件,一个图片对应一个xml文件,是对图片的标注)
xml_files = os.listdir(Annotations)
# 打乱数据集
random.shuffle(xml_files)

train_num = int(len(xml_files) * 0.7) # 设置训练集个数
train_lists= xml_files[:train_num] # 训练集列表
test_lists= xml_files[train_num:] # 测试集列表

def parse_rec(filename): # 输入xml文件名
    tree = ET.parse(filename)
    objects = []
    # 读取xml文件中的 <object></object>下的内容
    '''
    <object>                            //检测到的物体  
        <name>horse</name>              //物体类别  
        <pose>Right</pose>              //拍摄角度  
        <truncated>0</truncated>        //是否被截断(0表示完整)  
        <difficult>0</difficult>        //目标是否难以识别(0表示容易识别)  
        <bndbox>                        //bounding-box(包含左下角和右上角xy坐标)  
            <xmin>100</xmin>  
            <ymin>96</ymin>  
            <xmax>355</xmax>  
            <ymax>324</ymax>  
        </bndbox>  
    </object>  

    '''
    for obj in tree.findall('object'):
        # 创建一个结构体
        obj_struct = {}
        # 获取到 difficult元素,如果值为1,表示目标难以识别,则跳过
        difficult = int(obj.findall('difficult').text)
        if difficult ==1:
            continue
        obj_struct['name'] = obj.find('name').text
        bbox = obj.find('bndbox')
        obj_struct['bbox'] = [int(float(bbox.find('xmin').text)),
                             int(float(bbox.find('ymin').text)),
                             int(float(bbox.find('xmax').text)),
                             int(float(bbox.find('ymax').text))]
        objects.append(obj_struct)

    return objects

def write_txt():
    count = 0
    for train_list in train_lists: # 生成训练集txt
        count += 1
        image_name = train_list.split('.')[0] + '.jpg'  # 图片文件名
        results = parse_rec(Annotations + train_list)
        if len(results) == 0:
            print(train_list)
            continue
        train_set.write(image_name)
        for result in results:
            class_name = result['name']
            bbox = result['bbox']
            class_name = VOC_CLASSES.index(class_name)
            train_set.write(' ' + str(bbox[0]) +
                            ' ' + str(bbox[1]) +
                            ' ' + str(bbox[2]) +
                            ' ' + str(bbox[3]) +
                            ' ' + str(class_name))
        train_set.write('\n')
    train_set.close()

    for test_list in test_lists:   # 生成测试集txt
        count += 1
        image_name = test_list.split('.')[0] + '.jpg'  # 图片文件名
        results = parse_rec(Annotations + test_list)
        if len(results) == 0:
            print(test_list)
            continue
        test_set.write(image_name)
        for result in results:
            class_name = result['name']
            bbox = result['bbox']
            class_name = VOC_CLASSES.index(class_name)
            test_set.write(' ' + str(bbox[0]) +
                            ' ' + str(bbox[1]) +
                            ' ' + str(bbox[2]) +
                            ' ' + str(bbox[3]) +
                            ' ' + str(class_name))
        test_set.write('\n')
    test_set.close()


if __name__ == '__main__':
    write_txt()

最终生成的训练集和数据集标签如下:
红框中前四个数是左上和右下角坐标,第五个数是类别。
一个图片可能否有多个目标,所有可能会有多个红框。
在这里插入图片描述

yoloData.py

encoder结果是7x7x30 = 7x7x(20+5+5)
20是这个数据集有20类,两个5是因为让这7x7个格子,每个格式产生两个候选框。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1027881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯云16核服务器配置大全_CVM和轻量服务器汇总

腾讯云16核CPU服务器有哪些配置可以选择&#xff1f;可以选择标准型S6、标准型SA3、计算型C6或标准型S5等&#xff0c;目前标准型S5云服务器有优惠活动&#xff0c;性价比高&#xff0c;计算型C6云服务器16核性能更高&#xff0c;轻量16核32G28M带宽优惠价3468元15个月&#xf…

go语言 最小堆 最大堆 堆排序

建堆 调整 删除 先根据数组构建完全二叉树 从第一个非叶结点开始 调整为大跟堆&#xff0c;这里就是图里面的1结点开始调整 代码如下&#xff1a; func findKthLargest(nums []int, k int) int {heapSize : len(nums)buildMaxHeap(nums,heapSize)for i : len(nums) - 1; i &…

无涯教程-JavaScript - BINOM.DIST函数

描述 BINOM.DIST函数返回单个项二项式分布概率。 在具有固定数量的测试或试验的问题中使用BINOM.DIST。 当任何试验的输出只是成功或失败时 试验是独立的,并且 在整个实验中成功的概率不变的情况 语法 BINOM.DIST (number_s,trials,probability_s,cumulative)争论 Argu…

选择护眼台灯的标准?专家推荐台灯好物分享

自从护眼台灯成为学生书桌上最常见的照明灯具后&#xff0c;就经常能看到关于护眼台灯伤眼的信息。从根源上说&#xff0c;是各种不专业产品混杂在市场中&#xff0c;这种产品技术较差&#xff0c;而且为减少成本选择品质差的材料&#xff0c;但由于低廉的价格仍然吸引了众多消…

【FAQ】以服务方式启动安防监控系统EasyNVR程序,出现播放异常的原因排查与解决

EasyNVR安防视频监控平台的特点是基于RTSP/Onvif协议&#xff0c;将前端设备统一接入&#xff0c;在平台进行转码、直播、处理及分发&#xff0c;在智慧安防视频监控场景中&#xff0c;EasyNVR可实现实时监控、云端录像、检索与回放、云存储、告警、级联等视频能力&#xff0c;…

Redis缓存设计与性能优化最佳实践

开发规范与性能优化 一、键值设计 1. key名设计 (1)【建议】: 可读性和可管理性 以业务名(或数据库名)为前缀(防止key冲突)&#xff0c;用冒号分隔&#xff0c;比如业务名:表名:id (2)【建议】&#xff1a;简洁性 保证语义的前提下&#xff0c;控制key的长度&#xff0c;…

备考新境界:考研竞争中的超级助推器,让AIGC点亮你的学术之路!

近年来&#xff0c;各院校毕业生逐年增长、就业压力提升&#xff0c;研究生学历在就业市场上占有明显优势。加上留学、考公、二战等多赛道的涌入&#xff0c;硕士研究生报名人数呈现快速上升趋势。根据调查显示&#xff0c;2023年考研报考人数达457万人&#xff0c;报录比甚至达…

面向组织分析的内容

声明 本文是学习GB-T 42859-2023 航天产品质量问题三个面向分析方法实施要求. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了航天产品质量问题三个面向分析方法实施的一般要求、程序和分析内容。 本文件适用于承担航天产品研制…

IntelliJ IDEA快速查询maven依赖关系

1.在Maven窗口中点击Dependencies->show Dependencies 2.得到依赖关系图 此时原有快捷键Ctrlf可以查询jar包&#xff0c;如果没有查询菜单出来则设置快捷键方式为 File->Settings->Keymap->搜索栏输入find->在Main Menu下Edit下Find下Find双击算则Add keyboard…

月木学途开发 2.前台用户模块

概述 效果展 数据库设计 会员表 DROP TABLE IF EXISTS user_type; CREATE TABLE user_type (userTypeId int(11) NOT NULL AUTO_INCREMENT,userTypeName varchar(255) DEFAULT NULL,userTypeDesc varchar(255) DEFAULT NULL,PRIMARY KEY (userTypeId) ) ENGINEInnoDB AUTO_I…

VLAN的配置实例

基于端口的vlan划分 以下配置为例&#xff1a; 注意选择copper线&#xff0c;可以任意选择端口 PC配置如下&#xff1a; LSW1配置如下 [LSW1]vlan 10 [LSW1-vlan10]qu [LSW1]interface g0/0/9 [LSW1-Gigabitethernet0/0/9] port link-type acces [LSW1-Gigabitethernet0/0/9]…

Python 公里与海里换算

""" 公里与海里换算知识点&#xff1a;1、换算公式&#xff1a;海里 公里 / 1.8522、input()、print()函数3、变量类型转换&#xff0c;整形int与字符串str转换&#xff0c;可以用type()函数验证4、字符串拼接&#xff0c;例如&#xff1a;123 456 1234565、…

盘点数字人源头厂商哪家公司OEM定制能力好!

在当今的科技盛世&#xff0c;我们与数字人的互动越来越频繁。无论是在工作中的智能助手&#xff0c;还是数字人播&#xff0c;数字员工&#xff0c;还是在生活中的个性化推荐&#xff0c;数字人都在为我们的生活增添色彩。然而&#xff0c;大家可能并未意识到&#xff0c;这些…

JavaWeb后端开发 JWT令牌解析 登录校验 通用模板/SpringBoot整合

目录 实现思路 相关技术的解析 ​编辑会话跟踪三个方案 JWT令牌技术 ​生成令牌 校验令牌 登录下发令牌 实现思路 通过登录成功的标记来检测,在每个接口前做一个标记判断是否登录,若没登录则返回错误信息,并使前端退出.但这样较为繁琐,因此我们可以通过一种统一拦截的技…

预处理代码

一、缺失值处理 删除缺失值&#xff1a; data1data.dropna()#丢弃缺失值 #dropna()删除缺失值所在行(axis0)或列(axis1)&#xff0c;默认为 axis0 补全 示例数据&#xff1a; import pandas as pd import numpy as npdata pd.DataFrame({name: [Bob, Mary, Peter, np.nan, L…

【python爬虫】—星巴克产品

文章目录 需求爬取星巴克产品以及图片&#xff0c;星巴克菜单 python爬虫爬取结果 需求 爬取星巴克产品以及图片&#xff0c;星巴克菜单 网页分析&#xff1a; 首先&#xff0c;需要分析星巴克官方网站的结构&#xff0c;了解菜单栏的位置、布局以及菜单项的标签或类名等信息…

计算最大回撤

计算最大回撤 1. 累积计算统计特征函数 PANDAS库中累积计算统计特征函数&#xff1a; 1、CUMSUM() 依次给出前1&#xff0c;2&#xff0c;…&#xff0c;n个数的和 2、CUMPROD() 依次给出前1&#xff0c;2&#xff0c;…&#xff0c;n个数的积 3、CUMMAX() 依次给出前1&#…

腾讯云16核服务器配置大全_16核CPU型号性能测评

腾讯云16核CPU服务器有哪些配置可以选择&#xff1f;可以选择标准型S6、标准型SA3、计算型C6或标准型S5等&#xff0c;目前标准型S5云服务器有优惠活动&#xff0c;性价比高&#xff0c;计算型C6云服务器16核性能更高&#xff0c;轻量16核32G28M带宽优惠价3468元15个月&#xf…

6.8-SpringIoC之循环依赖底层源码解析

解决靠&#xff0c;三级缓存 创建Map&#xff0c;存不完整的Bean 存在问题&#xff1a;属性存在但没有值

Redis——Java客户端配置

概要 由于Redis服务器在官网公开了RESP协议&#xff0c;因此第三方可以通过这个协议来实现和Redis服务器通信的客户端程序&#xff0c;而具体的通信逻辑也不需要我们去实现&#xff0c;只需要导入大佬的库即可 jedis就是封装了RESP协议&#xff0c;提供了一组api供我们使用 …