黄金时代 —— Retinanet

简介

在这里插入图片描述

  • ResNet + FPN(将不同维度的特征整合在一起,提高信息的丰富度) + SubNet(class/regression:对anchor做平移和伸缩变换) + focal-loss
  • 仔细观察Retinanet,我们不难发现,Retinanet是一个one-stage的网络,那么为什么它的精度竟然超过了two-stage呢?这就是focal loss的效果。

DataLoader, DataSet, Sampler

在这里插入图片描述

  • DataLoader:sampler作用是生成一系列的index,batch_sampler则是将sampler生成的indices打包分组,得到一个又一个batch的index
  • Pytorch中实现的Sampler:SequentialSampler / RandomSampler / WeightedSampler / SubsetRandomSampler
    在这里插入图片描述
  • 自定义Sampler和BatchSampler:__iter__(self)函数,不过要注意的是该函数的返回值需要是可迭代的
    在这里插入图片描述
  • Dataset:想对__getitem__方法进行调试,你可以写一个for循环遍历dataset来进行调试了,而不用构建dataloader等,建议学会使用ipdb这个库
    在这里插入图片描述
  • self.collate_fn:作用就是将一个batch的数据进行合并操作。默认的collate_fn是将img和label分别合并成imgs和labels,所以如果你的__getitem__方法只是返回 img, label那么你可以使用默认的collate_fn方法,但是如果你每次读取的数据有img, box, label等等,那么你就需要自定义collate_fn来将对应的数据合并成一个batch数据,这样方便后续的训练步骤

制作类似VOC格式的个人数据集

介绍VOC数据集

  • JPEGImages文件夹
    • 文件夹里包含了训练图片和测试图片,混放在一起
  • Annatations文件夹
    • 文件夹存放的是xml格式的标签文件,每个xml文件都对应于JPEGImages文件夹的一张图片
  • ImageSets文件夹
    • Action存放的是人的动作,暂时不用
    • Layout存放的人体部位的数据,暂时不用
    • Main存放的是图像物体识别的数据,Main里面有test.txt , train.txt, val.txt ,trainval.txt.这四个文件我们后面会生成
    • Segmentation存放的是可用于分割的数据
  • 其他的文件夹不解释了,其他任务用的(如语义风格个个人分割)
def make_voc_dir():
    os.makedirs('VOC2007/Annotations')
    os.makedirs('VOC2007/ImageSets')
    os.makedirs('VOC2007/ImageSets/Main')
    os.makedirs('VOC2007/ImageSets/Layout')
    os.makedirs('VOC2007/ImageSets/Segmentation')
    os.makedirs('VOC2007/JPEGImages')
    os.makedirs('VOC2007/SegmentationClass')
    os.makedirs('VOC2007/SegmentationObject')
if __name__ == '__main__':
    make_voc_dir()

第一步:搞定JPEGSImages文件夹(改名

  • 把你的图片放到JPEGSImages里面,在VOC2007里面,人家的图片文件名都是000001.jpg类似这样的,我们也统一格式,把我们的图片名字重命名成这样的
# -*- coding:utf8 -*-

import os

class BatchRename():

    def __init__(self):
        self.path = 'C:/Users/leeha/Desktop/VOC/JPEGImages/'
    def rename(self):
        filelist = os.listdir(self.path)
        total_num = len(filelist)
        i = 0#设置标号
        for item in filelist:
            if item.endswith('.jpg'):
                src = os.path.join(os.path.abspath(self.path), item)
                dst = os.path.join(os.path.abspath(self.path), 'LJ'+str(i+1).rjust(9,'0')+ '.jpg')
                try:
                    os.rename(src, dst)
                    print('converting {} to {} ...'.format(src, dst))
                    i = i + 1
                except:
                    continue
                print('total {} to rename & converted {} jpgs'.format(total_num, i))

if __name__ == '__main__':
    demo = BatchRename()
    demo.rename()
    

第二步:搞定Annatations文件夹

  • 使用 labelImg 软件

第三步:搞定ImageSet/Main/*.txt文件

  • get_mian_txt.py
  • 数据集划分:test / train / val
  • 如下代码要求:0.7 train,0.3x0.9 test,0.3x0.1 val
import os
import random
from tqdm import tqdm

def _main():
    trainval_percent = 0.3 # test+val rate
    train_percent = 0.9 # test rate
    xmlfilepath = 'Annotations'
    total_xml = os.listdir(xmlfilepath)

    num = len(total_xml)
    list = range(num)
    tv = int(num * trainval_percent)
    tr = int(tv * train_percent)
    trainval = random.sample(list, tv)
    train = random.sample(trainval, tr)

    ftrainval = open('ImageSets/Main/trainval.txt', 'w')
    ftest = open('ImageSets/Main/test.txt', 'w')
    ftrain = open('ImageSets/Main/train.txt', 'w')
    fval = open('ImageSets/Main/val.txt', 'w')

    for i in tqdm(list):
        name = total_xml[i][:-4] + '\n'
        if i in trainval:
            ftrainval.write(name)
            if i in train:
                ftest.write(name)
            else:
                fval.write(name)
        else:
            ftrain.write(name)

    ftrainval.close()
    ftrain.close()
    fval.close()
    ftest.close()

if __name__ == '__main__':
    _main()

第四步:生成相关CSV文件

  • get_anno_txt.py
  • 生成的csv文件格式是:path / x1 / y2 / x2/ y2;如果一个图像上有多个目标,会分成多行!
├── csv
│   ├── Annotations  #上文步骤1中的自己的vOC2007数据集中的Annotations
│   │   ├── 0095.xml
│   │   ├── 0096.xml
│   │   ├── 0312.xml
│   │   ├── 0313.xml
│   │   ├── 0588.xml
│   │   ├── 0589.xml
│   │   ├── 0590.xml
│   │   ├── 0800.xml
│   │   ├── 0801.xml
│   │   ├── 0802.xml
│   │   ├── 0803.xml
│   │   ├── 0804.xml
│   │   └── 0805.xml
│   ├── test_anno.csv # 测试集路径+bbox
│   ├── test_cls.csv # 测试集类别
│   ├── train_anno.csv # 训练集路径+bbox
│   ├── train_cls.csv # 训练集类别
│   ├── val_anno.csv # 验证集路径+bbox
│   ├── val_cls.csv # 验证集类别
│   ├── ImageSets  #上文步骤1中的自己的VOC2007数据集中的ImageSets
│   │   └── Main
│   │       ├── test.txt # 测试集
│   │       ├── train.txt # 训练集
│   │       ├── trainval.txt # 测试+验证集合
│   │       └── val.txt # 验证集
│   ├── JPEGImages  #上文步骤1中的自己的vOC2007数据集中的JPEGImages
│   │   ├── 0095.png
│   │   ├── 0096.png
│   │   ├── 0312.png
│   │   ├── 0313.png
│   │   ├── 0588.png
│   │   ├── 0589.png
│   │   ├── 0590.png
│   │   ├── 0800.png
│   │   ├── 0801.png
│   │   ├── 0802.png
│   │   ├── 0803.png
│   │   ├── 0804.png
│   │   └── 0805.png
│   └── pascal2csv.py #下文将要说的转换函数
  • 代码:
import csv
import os
import glob
import sys

sets = [('train'),('test'),('val')]
path = '/home/idip/lijian/pytorch/Dataset/VOC2007/JPEGImages'

class PascalVOC2CSV(object):
    def __init__(self,xml=[], ann_path='./annotations.csv',classes_path='./classes.csv', pre='./Annotations/'):
        '''
        :param xml: image list
        :param ann_path: ann_path
        :param classes_path: classes_path
        '''
        self.pre = pre
        self.xml = xml
        self.ann_path = ann_path
        self.classes_path=classes_path
        self.label=[]
        self.annotations=[]
        self.data_transfer()
        self.write_file()
        
    def data_transfer(self):
        for num, xml_file in enumerate(self.xml):
            xml_file = self.pre + xml_file + '.xml' # xml's path
            try:
                # print(xml_file)
                sys.stdout.write('\r>> Converting image %d/%d' % (
                    num + 1, len(self.xml)))
                sys.stdout.flush()
                with open(xml_file, 'r') as fp:
                    for p in fp:
                        if '<filename>' in p:
                            self.filen_ame = p.split('>')[1].split('<')[0] # 00001.jpg

                        if '<object>' in p:
                            # class name
                            d = [next(fp).split('>')[1].split('<')[0] for _ in range(9)] 
                            self.supercategory = d[0]
                            if self.supercategory not in self.label:
                                self.label.append(self.supercategory)
                            # bbox
                            x1 = int(d[-4]);
                            y1 = int(d[-3]);
                            x2 = int(d[-2]);
                            y2 = int(d[-1])
                            # Record
                            self.annotations.append([os.path.join(path, self.filen_ame),
                                x1, y1, x2, y2, self.supercategory])
            except:
                continue
 
        sys.stdout.write('\n')
        sys.stdout.flush()
 
    def write_file(self,):
        with open(self.ann_path, 'w', newline='') as fp:
            csv_writer = csv.writer(fp, dialect='excel')
            csv_writer.writerows(self.annotations)
        class_name=sorted(self.label)
        class_=[]
        for num,name in enumerate(class_name):
            class_.append([name,num])
        with open(self.classes_path, 'w', newline='') as fp:
            csv_writer = csv.writer(fp, dialect='excel')
            csv_writer.writerows(class_)
 
# xml_file = glob.glob('./Annotations/*.xml')
# PascalVOC2CSV(xml_file)

if __name__ == '__main__':
    for txt_name in sets:
        image_ids = open('./ImageSets/Main/%s.txt'%(txt_name)).read().strip().split()
        PascalVOC2CSV(image_ids, txt_name + '_anno.csv', txt_name + '_cls.csv')

代码

  • Anchors:处理先验框之类的,34567, image_shapes, generate_anchors
  • data_loader: CSV_Dataset, Collater, AspectRatioSampler, Resizer, Normalizer
  • others: generator_predict_boxes, Adjust_boxes, _compute_ap, compute_overlap, nms
  • FPN: FeaturePyramidNet
  • resnet
  • SubNet
  • losses
  • Build_Network
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值