目标检测模型中的Bells and wisthles

news2024/11/17 7:29:01

目标检测模型中的Bells and wisthles

    • 目标检测模型中的Bells and wisthles
      • 1. Data augmentation 数据增强
      • 2. Multi-scale Training/Testing 多尺度训练/测试
      • 3. Global Context 全局语境
      • 4. Box Refinement/Voting 预测框微调/投票法
      • 5. OHEM 在线难例挖掘
      • 6. Soft NMS 软化非极大抑制
      • 7. RoIAlign RoI对齐
      • 拾遗
      • References

在这里插入图片描述

目标检测模型中的Bells and wisthles

介绍常见的提升检测模型性能的技巧,它们常作为trick在比赛中应用。其实,这样的名称有失公允,部分工作反映了作者对检测模型有启发意义的观察,有些具有成为检测模型标准组件的潜力(如果在早期的工作中即被应用则可能成为通用做法)。读者将它们都看作学术界对解决这一问题的努力即可。对研究者,诚实地报告所引用的其他工作并添加有说服力的消融实验(ablation expriments)以支撑自己工作的原创性和贡献之处,则是值得倡导的行为。

1. Data augmentation 数据增强

数据增强是增加深度模型鲁棒性和泛化性能的常用手段,随机翻转、随机裁剪、添加噪声等也被引入到检测任务的训练中来,其信念是通过数据的一般性来迫使模型学习到诸如对称不变性、旋转不变性等更一般的表示。通常需要注意标注的相应变换,并且会大幅增加训练的时间。个人认为数据(监督信息)的适时传入可能是更有潜力的方向。

    transform_train = transforms.Compose([
        transforms.RandomCrop(32, padding=4),
        transforms.RandomHorizontalFlip(),
        transforms.RandomRotation(15),  # 数据增强
        transforms.ToTensor(),
        transforms.Normalize(mean, std)
    ])


	# Augmenter()数据增强
    dataset_train = CocoDataset(parser.dataset['coco'], set_name='train2017',
                                transform=transforms.Compose([Normalizer(), Augmenter(), Resizer()]))
    dataset_val = CocoDataset(parser.dataset['coco'], set_name='val2017',
                                transform=transforms.Compose([Normalizer(), Resizer()]))

2. Multi-scale Training/Testing 多尺度训练/测试

输入图片的尺寸对检测模型的性能影响相当明显,事实上,多尺度是提升精度最明显的技巧之一。在基础网络部分常常会生成比原图小数十倍的特征图,导致小物体的特征描述不容易被检测网络捕捉。通过输入更大、更多尺寸的图片进行训练,能够在一定程度上提高检测模型对物体大小的鲁棒性,仅在测试阶段引入多尺度,也可享受大尺寸和多尺寸带来的增益。

Multi-scale Training/Testing最早见于[1],训练时,预先定义几个固定的尺度,每个epoch随机选择一个尺度进行训练。测试时,生成几个不同尺度的feature map,对每个Region Proposal,在不同的feature map上也有不同的尺度,我们选择最接近某一固定尺寸(即检测头部的输入尺寸)的Region Proposal作为后续的输入。在[2]中,选择单一尺度的方式被Maxout(element-wise max,逐元素取最大)取代:随机选两个相邻尺度,经过Pooling后使用Maxout进行合并,如下图所示。


使用Maxout合并feature vector

近期的工作如FPN等已经尝试在不同尺度的特征图上进行检测,但多尺度训练/测试仍作为一种提升性能的有效技巧被应用在MS COCO等比赛中。

import torch
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import DataLoader

# 定义多尺度训练的缩放因子列表
scale_factors = [0.5, 0.75, 1.0, 1.25, 1.5]

# 定义训练和测试函数
def train(model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = F.cross_entropy(output, target)
        loss.backward()
        optimizer.step()
        if batch_idx % 100 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))

def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += F.cross_entropy(output, target, reduction='sum').item()  # 将一批的损失相加
            pred = output.argmax(dim=1, keepdim=True)  # 找到概率最大的索引
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)

    print('Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

# 定义训练和测试数据集
train_dataset = MyDataset(train=True)
test_dataset = MyDataset(train=False)

# 定义训练和测试数据集的DataLoader
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=4)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers=4)

# 定义设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 定义网络模型和优化器
model = MyModel().to(device)
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

# 多尺度训练循环
for epoch in range(10):
    for scale_factor in scale_factors:
        # 对训练和测试数据集进行缩放
        train_dataset.set_scale_factor(scale_factor)
        test_dataset.set_scale_factor(scale_factor)

        # 训练和测试
        train(model, device, train_loader, optimizer, epoch)
        test(model, device, test_loader)
"""
在上面的代码中,MyDataset和MyModel是用户定义的训练和测试数据集类和神经网络模型类。
train和test函数分别用于执行训练和测试。
scale_factors是一个缩放因子列表,用于对数据集进行多尺度训练和测试。
在多尺度训练循环中,对于每个缩放因子,都会对训练和测试数据集进行缩放,并执行训练和测试操作。
"""

3. Global Context 全局语境

把整张图片作为一个RoI,对其进行RoI Pooling并将得到的feature vector拼接于每个RoI的feature vector上,作为一种辅助信息传入之后的R-CNN子网络[3]。目前,也有把相邻尺度上的RoI互相作为context共同传入的做法。

4. Box Refinement/Voting 预测框微调/投票法

微调法和投票法由工作[4]提出,前者也被称为Iterative Localization。微调法最初是在SS算法得到的Region Proposal基础上用检测头部进行多次迭代得到一系列box,在ResNet的工作中,作者将输入R-CNN子网络的Region Proposal和R-CNN子网络得到的预测框共同进行NMS(见下面小节)后处理,最后,把跟NMS筛选所得预测框的IoU超过一定阈值的预测框进行按其分数加权的平均,得到最后的预测结果。投票法可以理解为以顶尖筛选出一流,再用一流的结果进行加权投票决策。

5. OHEM 在线难例挖掘

OHEM(Online Hard negative Example Mining,在线难例挖掘)见于[5]。两阶段检测模型中,提出的RoI Proposal在输入R-CNN子网络前,我们有机会对正负样本(背景类和前景类)的比例进行调整。通常,背景类的RoI Proposal个数要远远多于前景类,Fast R-CNN的处理方式是随机对两种样本进行上采样和下采样,以使每一batch的正负样本比例保持在1:3,这一做法缓解了类别比例不均衡的问题,是两阶段方法相比单阶段方法具有优势的地方,也被后来的大多数工作沿用。


OHEM图解

但在OHEM的工作中,作者提出用R-CNN子网络对RoI Proposal预测的分数来决定每个batch选用的样本,这样,输入R-CNN子网络的RoI Proposal总为其表现不好的样本,提高了监督学习的效率。实际操作中,维护两个完全相同的R-CNN子网络,其中一个只进行前向传播来为RoI Proposal的选择提供指导,另一个则为正常的R-CNN,参与损失的计算并更新权重,并且将权重复制到前者以使两个分支权重同步。

OHEM以额外的R-CNN子网络的开销来改善RoI Proposal的质量,更有效地利用数据的监督信息,成为两阶段模型提升性能的常用部件之一。

6. Soft NMS 软化非极大抑制


NMS后处理图示

NMS(Non-Maximum Suppression,非极大抑制)是检测模型的标准后处理操作,用于去除重合度(IoU)较高的预测框,只保留预测分数最高的预测框作为检测输出。Soft NMS由[6]提出。在传统的NMS中,跟最高预测分数预测框重合度超出一定阈值的预测框会被直接舍弃,作者认为这样不利于相邻物体的检测。提出的改进方法是根据IoU将预测框的预测分数进行惩罚,最后再按分数过滤。配合Deformable Convnets,Soft NMS在MS COCO上取得了当时最佳的表现。算法改进如下:


Soft-NMS算法改进

上图中的 f f f 即为软化函数,通常取线性或高斯函数,后者效果稍好一些。当然,在享受这一增益的同时,Soft-NMS也引入了一些超参,对不同的数据集需要试探以确定最佳配置。

7. RoIAlign RoI对齐

RoIAlign是Mask R-CNN([7])的工作中提出的,针对的问题是 R o I RoI RoI 在进行 P o o l i n g Pooling Pooling 时有不同程度的取整,这影响了实例分割中 mask 损失的计算。文章采用双线性插值的方法将 R o I RoI RoI 的表示精细化,并带来了较为明显的性能提升。这一技巧也被后来的一些工作(如light-head R-CNN)沿用。

拾遗

除去上面所列的技巧外,还有一些做法也值得注意:

  • 更好的先验(YOLOv2):使用聚类方法统计数据中box标注的大小和长宽比,以更好的设置anchor box的生成配置
  • 更好的pre-train模型:检测模型的基础网络通常使用ImageNet(通常是ImageNet-1k)上训练好的模型进行初始化,使用更大的数据集(ImageNet-5k)预训练基础网络对精度的提升亦有帮助
  • 超参数的调整:部分工作也发现如NMS中IoU阈值的调整(从0.3到0.5)也有利于精度的提升,但这一方面尚无最佳配置参照

最后,集成(Ensemble)作为通用的手段也被应用在比赛中。

References

  • [1]: Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition
    [2]: Object Detection Networks on Convolutional Feature Maps
    [3]: Deep Residual Learning for Image Classification
    [4]: Object Detection via a Multi-region & Semantic Segmentatio-aware CNN Model
    [5]: Training Region-based Object Detectors with Online Hard Example Mining
    [6]: Improving Object Detection With One Line of Code
    [7]: Mask R-CNN

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

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

相关文章

云原生——云平台操作

❄️作者介绍:奇妙的大歪❄️ 🎀个人名言:但行前路,不负韶华!🎀 🐽个人简介:云计算网络运维专业人员🐽 前言 云:云是网络、互联网的一种比喻说法。 平台&am…

【爬虫】5.2 Selenium编写爬虫程序

1. Selenium 框架介绍 Selenium自动化测试框架是实现自动化测试的一个软件结构和功能组件集合。Selenium自动化测试框架是一个半成品,能够帮助用户实现自动化测试。Selenium是模仿浏览器行为的,当你运行测试类(爬虫)的时候&…

【AIGC】Chatglm2-lora微调

ChatGLM2介绍 ChatGLM2-6B源码地址:https://github.com/THUDM/ChatGLM2-6B ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本,在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上,ChatGLM2-6B 引入了如下新特性&…

【Java】Java中的异常

文章目录 一、什么是异常1.1 异常的概念1.2 异常的分类 二、异常的体系结构三、异常的处理3.1 异常的抛出3.2 异常的捕获与处理3.3 异常的处理流程 四、自定义异常类4.1 自定义异常类的规则4.2 自定义异常案例 一、什么是异常 1.1 异常的概念 在Java中,异常&#…

《Linux操作系统编程》第八章 Shell程序设计: shell 语言结构,包括测试、分支、循环、跳转、函数、语句组

🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1f33…

C++ DAY3

1.思维导图 2.有以下类定义&#xff0c;按要求实现剩余功能 #include <iostream> using namespace std;class Person { private:int age;int *p; public://无参构造Person():p(new int(89)){age 18;}//有参构造Person(int age,int num){this->age age;this->pne…

基于Java实验室开放管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

Servlet实现留言墙

目录 1.创建工程 2.构建目录工程结构 3.设置编码格式尾utf-8 4.查看Maven配置 5.一些其他配置​编辑 6.导入依赖 7.导入HTML和JS、配置tomcat 8.测试网站是否可以正常访问 9.编写业务代码 开发环境&#xff1a;idea2022.2社区版 1.创建工程 2.构建目录工程结构 web.xml中的…

《程序员的AI书_从代码开始》第一章 机器学习的Hello World

文章目录 1.3 从代码开始1.3.2 一段简单的代码 1.3 从代码开始 1.3.2 一段简单的代码 python导入tensflow.keras报错解决方法 import tensorflow as tf from tensorflow.python.keras.models import Sequential from tensorflow.python.keras.layers import DensemodelSeque…

为什么网络攻击绝大多数发生在游戏行业

近年来&#xff0c;游戏行业欣欣向荣&#xff0c;游戏玩家也呈指数级增长&#xff0c;全球数以亿计的游戏玩家享受着网络游戏广泛的互动体验&#xff0c;然而&#xff0c;由于游戏的崛起和受欢迎程度也使其成为网络黑客寻求利用其漏洞的首选目标。 出于多种原因&#xff0c;游…

MybatisPlus的分页插件自动优化LeftJoin语句导致参数不匹配

所报的错误&#xff1a; java.sql.SQLException: Parameter index out of range (3 &#xff1e; number of parameters, which is 2). 首先会去检查自己传了哪些参数&#xff1f;是否都用上了&#xff1f;反复检查&#xff0c;发现并没有多余的参数&#xff1a; controller…

目前主流的软件开发模型:瀑布模型,增量模型(渐增模型,快速原型模型),螺旋模型,喷泉模型,敏捷模型。

目录 前言&#xff1a; 一、瀑布模型&#xff1a; 二、增量模型&#xff1a; 三、螺旋模型&#xff1a; 四、喷泉模型&#xff1a; 五、敏捷开发模型&#xff1a; 前言&#xff1a; 软件开发模型是用来指导和组织软件开发过程的模式或方法。随着软件行业的发展和不断变化…

Hue 后台编辑器 远程命令执行漏洞

描述 Hue 后台编辑器存在命令执行漏洞&#xff0c;攻击者通过编辑上传 xxx.sh 文件即可达到命令执行的目的。 FOFA title"Hue - 欢迎使用 Hue" "/hue/accounts/login?next/"复现过程 默认密码&#xff1a;admin:admin 上传并编辑文件为执行的命令

5、DataX(DataX简介、DataX架构原理、DataX部署、使用、同步MySQL数据到HDFS、同步HDFS数据到MySQL)

1、DataX简介 1.1 DataX概述 DataX 是阿里巴巴开源的一个异构数据源离线同步工具&#xff0c;致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。源码地址&#xff1a;https://github.com/alibaba/Dat…

SpringBoot3.0整合RocketMQ时出现未能加载bean文件

SpringBoot3.0整合RocketMQ时出现未能加载bean文件 问题 APPLICATION FAILED TO START Description: Field rocketMQTemplate in com.spt.message.service.MqProducerService required a bean of type ‘org.apache.rocketmq.spring.core.RocketMQTemplate’ that could not …

Scala里的WordCount 案例

7.7.5 普通 WordCount 案例 package chapter07object TestWordCount__简单版 {def main(args: Array[String]): Unit {//单词计数&#xff1a;将集合中出现的相同单词计数&#xff0c;进行计数&#xff0c;取计数排名的前三的结果val stringList List("Hello Scala Hbas…

2023年前端面试汇总-React

1. 组件基础 1.1. React事件机制 <div onClick{this.handleClick.bind(this)}>点我</div> React并不是将click事件绑定到了div的真实DOM上&#xff0c;而是在document处监听了所有的事件&#xff0c;当事件发生并且冒泡到document处的时候&#xff0c;React将事…

C语言进阶--动态内存管理

目录 一.为什么使用动态内存分配&#xff1f; 二.动态内存函数 2.1.malloc和free malloc函数 free函数 2.2.calloc和realloc calloc函数 realloc函数 三.常见的动态内存错误 对NULL指针的解引用 对动态开辟空间的越界访问 对非动态开辟内存使用free释放 使用free释…

新型进网许可标志规格样式及申请使用流程说明

新型进网许可标志规格样式及申请使用流程说明 一、新型进网许可标志规格样式 (一)标志样式 新型进网许可标志分为彩色样式和黑白样式&#xff0c;如图1所示&#xff0c;生产企业可以自行选择使用。 (二)标志要素 新型进网许可标志由许可标识、设备型号、数字编码等要素组成…

13年测试老鸟,web性能测试-测试用例总结 (全覆盖),卷起来...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试用例主要…