RCNN网络源码解读(Ⅱ) --- 使用IOU计算正负样本用于finetune训练

news2024/11/18 9:35:41

目录

1.预训练二分类器Alexnet

1.1 code(finetune.py)

2.二分类数据集处理 

2.1 code(cerate_classifier_data.py)


1.预训练二分类器Alexnet

1.1 code(finetune.py)

1.引入头文件

import os
import copy
import time
import torch
import torch.nn as nn
import torch.optim as optin
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
import torchvision.models as models
from utils.data.custom_finetune_dataset import customFinetuneDataset
from utils.data.custom_batch_sampler import CustomBatchSampler
from utils.util import check_dir

        在torchvision.models里面存放了Alexnet的模型。

2.主函数

from image_handler import show_images
impont numpy as np

if __name__ == ' __main__':
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    data_loaders,data_sizes = load_data('./data/classifier_car')
    #加载alexnet神经网洛
    model = models.alexnet(pretraine = True)

    print(model)
    data_loader = data_loaders["train"]

    print("一次迭代取得所有的正负数据,如果是多个类则取得多类数据集合")
    """
    index: 323 inage_id: 200 target: 1 image.shape: (254,342,3)[xmin,ymin,xnax,ymax]: [80,39,422,293]
    """

    inputs,targets = next(data_loader.__iter__())
    print(inputs[0].size(),type(inputs[0]))
    trans = transforms.ToPILImage()
    print(type(trans(inputs[0])))
    print(targets)
    print(inputs.shape)
    titles = ["TRUE" if i.item() else "False" for i in targets[0:60]]
    images = [np.array(trans(i))for i in inputs[0:60]]
    show_images(images,titles=titles,num_cols=12)


    #
    #把alexnet变成二分类模型,在最后一行改为2分类。
    num_features = model.classifier[6].in_features
    model.classifier[6] = nn.Linear(num_features,2)
    
    print("记alexnet变成二分类模型,在最后一行改为2分类",model)
    model = model.to(device)


    criterion = nn.CrossEntroyLoss()
    optimizer = optim.SGD(model.parameters(),lr=1e-3, momentum=0.9)
    lr_scheduler = optim.lr_scheduler.StepLR(optimizer,step_size=7,gamma=0.1)
    
    best_model = train_model(data_loaders,model,criterion,optimizer,lr_scheduler,device=device
num_epachs=10)
    
    check_dir('./models')
    torch.save(best_model.state_dict(),'models/alexnet_car.pth ')

         这里需要指出,pretrain参数是指是否要进行迁移学习,为true则表示将先人训练好的参数我们拿来使用,我们无需重新训练。即数据集处理完之后,我们使用finetune方法alexnet的网络模型和参数做二分类,因此我们要对二分类的数据集进行训练。   

        因此我们第一步处理完数据集后,还要对二分类的数据集进行处理!

        这个函数下节说!

2.二分类数据集处理 

2.1 code(cerate_classifier_data.py)

1.主函数如下

if __namne__== '__main__':
    
    car_root_dir = '../../data/voc_car/'
    classifier_root_dir = '../../data/classifier_car/'
    check_dir(classifier_root_dir)

    gs = selectivesearch.get_selective_search()
    for name in ['train'  , 'val' ]:
        #以voc_car目录下的文件为源头
        src_root_dir = os.path.join(car_root_dir,name)
        src_annotation_dir = os.path.join(src_root_dir,'Annotations')
        src_jpeg_dir = os.path.join(src_root_dir,'JPEGImages')
    
        #以classifier_car目录下的文件为目的
        #dst_root_dir = data/classifier_car/(train/val)
        #dst_annotation_dir = data/classifier_car/(train/val)/Annotations
        #dst_jpeg_dir = data/classifier_car/(train/val)/JPEGImages
        dst_root_dir = os.path.join(classifier_root_dir,name)
        dst_annotation_dir = os.path.join(dst_root_dir,'Annotations')
        dst_jpeg_dir = os.path.join(dst_root_dir,'JPEGImages')
        
        #创建 classifier_car目录下的目录结构
        check_dir(dst_root_dir)
        check_dir(dst_annotation_dir)
        check_dir(dst_jpeg_dir)

        total_num_positive = 0
        total_numn_negative = 0
    
        #每个samples就是一条图片信息  voc_car/train(val)/car.csv
        samples = parse_car_csv(src_root_dir)

        #将源目录中的csv文件复制到classifier_car下面
        src_csv_path = os.path.join(src_root_dir, 'car.csv')
        dst_csv_path = os.path.join(dst_root_dir,'car.csv')

        #data/voc_car/train(val)/car.csv
        #data/classifier_root_dir/train(val)/car.csv
        shutil.copyfile(src_csv_path, dst_csv_path)

        for sample_name in samples:
            #开始处理每一张图片
            try:
                since = time.time()
                #将csv文件中的文件名补0得到正式的文件名
                sample_name =  sample_name.zfill(6)

                #取得源标注信息
                #data/voc_car/(train/val)/Annotations/xxxxxx.xml
                src_annotation_path = os.path.join(src_annotation_dir,sample_name + '.xml')
                #取得源图片
                #data/voc_car/(train/val)/JPEGImages/xxxxxx.img
                src_jpeg_path = os.path.join(src_jpeg_dir,sample_name+'.jpg')

                ##获取正负样本,正样本就是voc标识框,因此无需在进行加和处理
                #返回的是一个rect的列表
                positive_list,negative_list =parse_annotation_jpeg(src_annotation_path,src_jpeg_path,gs)

                total_num_positive = len(positive_list)
                total_num_negative = len(negative_list)

                # data/classifier_car/(train/val)/Annotations/xxxxxx_1.csv
                # data/classifier_car/(train/val)/Annotations/xxxxxx_0.csv
                dst_annotation_positive_path = os.path.join(dst_annotation_dir,sample_name + '_1' + '.csv')
                dst_annotation_negative_path = os.path.join(dst_annotation_dir,sample_name + '_0'+ '.csv")
                
                #data/classifier_car/(train/val)/JPEGImages/xxxxxx.jpg
                dst_jpeg_path = os.path.join(dst_jpeg_dir,sample_name+'.jpg')

                #保存图片
                #data/voc_car/(train/val)/JPEGImages/xxxxxx.img
                #data/classifier_car/(train/val)/JPEGImages/xxxxxx.jpg
                shutil.copyfile(src_jpeg_path, dst_jpeg_path)

                #保存正负样本标注
                np.savetxt(dst_annotation_positive_path,np.array(positive_list),fmt= '%d',delimiter=' ')
                np.savetxt(dst_annotation_negative_path,np.array(negative_list),fmt= '%d',delimiter=' ')    
                
                time_elapsed = time.time()-since
                print('parse {}.png in {:.Of}m {:.0f)s'.format(sample_name,time_elapsed //60,time_elapsed % 60))

            except Exception as err:
                print(err)
                continue
        print('%s positive num:%d' % (name,total_num_positive))
        print("%s negative num:%d' % (name,total_num_negative))
    print( " done ' )


        我们来看这段代码,car_root_dir 是我们上一篇博客说的从VOC数据集中抽取car数据集的目录,classifier_root_dir 是我们这步想要对二分类的数据集进行处理的目录,然后我们创建这个目录。

 

        这个函数的目的是改变标注形式,原来我们在car_root_dir 中的标注形式是这样的:

car_root_dir 中的标注形式

         在这一步中我们要将数据格式处理成这种:

classifier_root_dir 中的标注形式(1)

         每一个文件是这样的,这里的东西就是我们通过区域候选建议生成的一个个的候选框。

classifier_root_dir 中的标注形式(2)

         _0表示是一个负例,即候选框里面没有汽车。_1表示一个正例,即候选框里面有汽车。.        

        那如何确认正例负例呢:因为我们的标注文件里面有bndbox选项(即标注好的框大小),我们拿每一个经过区域候选建议生成的框和标注框体计算IOU并满足一定条件,则将候选框体标注为正例,否则标注为负例。

        selectivesearch是一个.py文件我们上一讲说过,get_selective_search是里面的一个函数,最终返回给gs获取候选框。

        其他的细节见标注。

2.get_selective_search

def get_selective_search():
    gs = cv2.ximgproc.segmentation.createselectiveSearchSegmentation()
    return gs

         返回候选框。

3.parse_car_csv

def parse_car_csv(csv_dir):
    csv_path = os.path.join(csv_dir, 'car.csv')
    samples = np.loadtxt(csv_path, dtype=np.str)
    return samples

         获取csv内容,每个samples就是一条图片信息。

4.parse_annotation_jpeg

# train
# positive num: 625
# negative num: 366028
# val
# positive num: 624
# negative num: 321474

@data/voc_car/(train/val)/Annotations/xxxxxx.xml
@data/voc_car/(train/val)/JEPGImage/xxxxxx.jpg
def parse_annotation_jpeg(annotation_path,jpeg_path,gs):
    """
    获取正负样本(注:忽略属性difficult = True的标注边界框)
    正样本:标注边界框
    负杆本:IoU大于0,小于等于0.3。为了进一步限制负样本数目,其大小必须大于标注框的1/5
    """

    print("jpeg_path",jpeg_path)
    #打开该文件
    img = cv2.imread(jpeg_path)
    selectivesearch.config(gs,img,strategy='q')
    #计算候选建议
    nects = selectivesearch.get_rects(gs)
    print("rects",len(rects))

    #获取标注边界框
    bndboxs = parse_xml(annotation_path)
    print("bndboxs", bndboxs)
    
    #标注框大小,如果有多个边界框,则叹得最大的边界框大小
    maximum_bndbox_size = 0
    for bndbox in bndboxs:
        xmin, ymin , xmax , ymax = bndbox
        bndbox_size = (ymax - ymin)*(xmax - xmin)
        if bndbox_size > maximum_bndbox_size:
            maximum_bndbox_size = bndbox_size

    #获取候选建该和标注边界框的IoU,输入为
    iou_list = compute_ious(rects,bndboxs)
    print("计算预选框和实框的iou列表",len(iou_list))

    positive_list = list()
    negative_list = list()

    #iou_list和 rect 列表长度应该一致
    for i in range(len(iou_list)):
        xmin,ymin,xmax,ymax = rects[i]
        rect_size = (ymax - ymin) * (xmax - xmin)

        iou_score = iou_list[i]
        #如果某个框体的iou值在0-0.3之间且框体大少低于真实框体的五分之一
        if 0 < iou_score <= 0.3 and rect_size > maximum_bndbox_size / 5.0:
            #负样本
            negative_list.append(rects[i])
        else:
            pass
    #返回预测框体和负样本框体列表
    retunn bndboxs,negative_list

         ①compute_ious(rects,bndboxs):这里调用函数计算IOU,输入是利用区域候选建议计算出来的很多框,bandbox是该图片的真实的框体。

        ②此函数返回给上层函数什么:正样本 and 负样本列表

        正样本只返回了标注框(即)@data/voc_car/(train/val)/Annotations/xxxxxx.xml中的框

        负样本返回了满足iou以及框体大小条件的框。

        !要记得还有没在负列表和正列表的框呢

5.iou 计算交并比

         简单来说,交并比就是交集/并集的比值,即蓝色区域/(绿色区域+橙色区域)的比值。

def compute_ious(rects,bndboxs):
    iou_list = list()
    for rect in rects:
        # iou计算一个rect和指定的多个框的iou值,如果bndboxs是多个,则得到的结果也是多个值的列表。                
        scores = iou(rect,bndboxs)
        #取得预选桩和最终判定框体之间iou最大的那个值。组成iou列表。
        iou_list.append(max(scores))
    return iou_list
def iou(pred_box, target_box):
    """
    计算候选建议框和标注框的IoU
    :param pred_box:大小为[4]
    :param target_box:大小为[N,4]
    :return: [N]
    """

    if len(target_box.shape) == 1:
        target_box = tanget_box[np.newaxis,:]

    xA = np.maximum(pred_box[0],target_box[:,0])
    yA = np.maximum(pred_box[1],target_box[:,1])
    xB = np.minimum(pred_box[2],target_box[:,2])
    yB = np.minimum(pred_box[3],target_box[:,3])
    
    #计算交集面积
    intersection = np.maximum(0.0,xB - xA) * np.maximum(0.0,yB - yA)
    #计算两个边界框面积
    boxAArea = (pred_box[2] - pred_box[0]) * (pred_box[3] - pred_box[1])
    boxBArea = (target_box[:,2] - target_box[:,0])* (target_box[:,3]- target_boxt:,1])
    scores = intersection / (boxAArea + boxBArea - intersection)
    return scores

        为了更好的理解,看下列代码;

import numpy as np  
  
X = np.array([[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[16,17],[18,19]])  
print X[:,0]  

        x[n,:]表示在n个数组(维)中取全部数据,直观来说,x[n,:]就是取第n集合的所有数据, 

        iou函数中targetbox的形式是N个框,每个框是4维的。那么这里xA,xB,yB,yB都是N维的,score也是N维的。记录N个标注框和区域候选框的IoU分数。

        compute_ious只返回分数最高的iou值。compute_ious最终返回是一张图片的每个区域建议候选框与标注文件中rect的IoU值的列表。即有多少个预选框,我们就有多少个IoU值。

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

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

相关文章

阿里是如何使用分布式架构的,阿里内部学习手册分享

为什么要使用分布式架构&#xff1f;分布式架构解决了互联网应用的两大难题&#xff1a;高并发和高可用。高并发指服务器并发处理客户端请求的数量大&#xff0c;而高可用指后端服务能始终处于可用状态。 提高系统容量 随着业务越来越复杂&#xff0c;服务也会变得越来越复杂…

CS61A Proj 2

更好的阅读体验 Project 2: CS 61A Autocorrected Typing Software cats.zip Programmers dream of Abstraction, recursion, and Typing really fast. Introduction Important submission note: For full credit: Submit with Phase 1 complete by Thursday, February 17, wo…

ADI Blackfin DSP处理器-BF533的开发详解55:CVBS输入-DSP和ADV7180的应用详解(含源码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 CVBS IN 视频输入 硬件实现原理 CVBS_IN 子卡板连接在 ADSP-EDU-BF53x 开发板的扩展端口 PORT3 和 PORT4 上&#xff0c;板卡插入时&#xff0c;…

[内网渗透]—域外向域内信息收集、密码喷洒

前言 当我们与目标内网建立了socks5隧道后,就可以从域外对域内机器进行信息搜集了,很多工具不用上传到目标机器,也就不易被AV检测到,但是有可能会被一些流量检测设备发现有大量socks5流量。 接下来介绍下如何通过域外对域内进⾏更深的信息搜集:枚举域⽤户、查看域内⽤户…

【大数据技术Hadoop+Spark】HBase数据模型、Shell操作、Java API示例程序讲解(附源码 超详细)

一、HBase数据模型 HBase分布式数据库的数据存储在行列式的表格中&#xff0c;它是一个多维度的映射模型&#xff0c;其数据模型如下所示。表的索引是行键&#xff0c;列族&#xff0c;列限定符和时间戳&#xff0c;表在水平方向由一个或者多个列族组成&#xff0c;一个列族中…

[附源码]Python计算机毕业设计红色景点自驾游网站管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

[附源码]Node.js计算机毕业设计古诗词知识学习系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

计算机毕设Python+Vue心理咨询预约系统(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

医院、诊所看这里,一个分诊屏+叫号系统,实现门诊高效排队叫号

为维系患者候诊秩序&#xff0c;减少插队混乱的情况&#xff0c;医院、诊所等医疗机构会考虑采购智能排队叫号系统。 依照系统预定规则&#xff0c;对门诊患者进行数据排列&#xff0c;医生快捷呼叫&#xff0c;打造现代化有序的绿色门诊。 排队叫号系统&#xff0c;是将软件…

「C#」异步编程玩法笔记-WinForm中的常见问题

目录 1、异步更新界面 1.1、问题 1.2、解决问题 1.3、AsyncOperationManager和AsyncOperation 1.4、Invoke、BeginInvoke、EndInvoke及InvokeRequired Invoke InvokeRequired BeginInvoke EndInvoke 2、死锁 2.1、问题 2.2、 解决方法 2.2.1、不要await 2.2.2、用…

Jmeter(十八):硬件性能监控指标

硬件性能监控指标 一、性能监控初步介绍 性能测试的主要目标 1.在当前的服务器配置情况&#xff0c;最大的用户数 2.平均响应时间ART&#xff0c;找出时间较长的业务 3.每秒事务数TPS&#xff0c;服务器的处理能力 性能测试涉及的内容 1.客户端性能测试&#xff1a;web前…

【Redis】主从复制和哨兵模式

主从复制 主从复制&#xff1a;主机数据更新后根据配置和策略&#xff0c; 自动同步到备机的master/slaver机制&#xff0c;Master以写为主&#xff0c;Slave以读为主 作用&#xff1a; 读写分离&#xff0c;性能扩展容灾快速恢复 主从复制的配置 在我的/myredis目录中&…

第17章 前端之全局存储:Vuex=Store

17章 前端之全局存储&#xff1a;VuexStore Store用于对数据进行存储&#xff0c;并共享以为所有需要的Vue页面中的调用提供数据及其方法支撑&#xff1b;Vuex是Store的内置引用包&#xff0c;即如果想要前端Vue程序支撑Store必须在新建Vue程序&#xff1b;如果Vue程序没有引用…

【python】一文带你理解并解决conda activate虚拟环境后,pip安装的包没放在虚拟环境

太长不看版 环境变量有问题&#xff0c;查看环境变量&#xff0c;应该会发现&#xff0c;在你虚拟环境的地址之前&#xff0c;有其他的地址&#xff0c;比如/home/xxx/.local/bin:等&#xff0c;而且这个地址里面刚好有pip,python这些程序。 最简单的办法&#xff1a;去把/hom…

第十五章 Golang单元测试

1. 先看一个需求 在我们工作中&#xff0c;我们会遇到这样的情况&#xff0c;就是去确认一个函数&#xff0c;或者一个模块的结果是否正确。 func addUpper(n int) int{res : 0for i : 1;i<n;i{res i}return res }2.传统方法的优缺点 不方便&#xff0c;我们需要在main函…

java基于微信小程序的二手交易系统-计算机毕业设计

项目介绍 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&a…

QCC51XX---RAM资源查看

QCC51XX---系统学习目录_嵌入式学习_force的博客-CSDN博客 想必大家有时会遇到一些memory的panic,就像下图的提示 这主要是内存溢出引起的。而内存溢出主要有内存池(memory pool)和RAM溢出两种,不管哪种溢出都是不规范使用内存或过度使用造成的。那具体有多少能用或怎么正确…

SpringCloud 学习笔记

❤ 作者主页&#xff1a;Java技术一点通的博客 ❀ 个人介绍&#xff1a;大家好&#xff0c;我是Java技术一点通&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 记得关注、点赞、收藏、评论⭐️⭐️⭐️ &#x1f4e3; 认真学习&#xff0c;共同进步&#xff01;&am…

SpringBoot 优雅地实现文件的上传和下载

2.技术栈mavenspringbootmybatis-plusmysqlthymeleafbootstrap3.数据库表 CREATE TABLE t_upload_file (id bigint(11) NOT NULL AUTO_INCREMENT,old_name varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,new_Name varchar(100) CHARACTER SET utf8 CO…

async和await随谈

以下只是个人观点&#xff0c;如果有出入或者错误之处&#xff0c;欢迎提出&#xff0c;你不需要纠结我的说法是否有一些小瑕疵&#xff0c;把其中你认为对的地方融入到自己的知识里去就好了&#xff0c;你学到的才是自己的。 在说async和await之前&#xff0c;先讲另一个东西迭…