Manjaro 环境 faster-rcnn训练Wider_Face数据

上一篇中演示了从0 部署 faster-rcnn 的整个过程,并且以及跑通demo以及train训练过程。https://blog.csdn.net/qq_35306993/article/details/89885671

VOC数据说明

VOCDevkit2007 文件夹为当前项目使用到的数据
Annotations中的xml为每张图片的标记数据,分类名,检测框坐标。文件名对于图片名。
JPEGImages 为所有图片原数据
ImageSets\Main\trainval.txt 为图片名 索引文件。数据加载 图片名从这个文件中读取。
目前只关注这三个文件夹

下载Wider_Face数据

WIDER FACE 图片库,下载地址http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/
解压数据整理成以下路径形式:
在这里插入图片描述
在这里插入图片描述
数据转换文件代码在本文最后提供
命令行执行widerface_to_voc.py文件,缺包自行安装。
提示安装skimage 时:pip install scikit-image
运行脚本widerface_to_voc.py需要等待一段时间,复制图片,制作标签等。
脚本运行完毕Wider_face 文件夹下得到三个文件夹就是voc格式
data\VOCDevkit2007\Wider_face 文件夹下得到三个文件夹就是vo
将三个文件夹移动到 VOC2007文件夹下如果这个文件夹下之前有数据需要全部删除
进入到dVOC2007\ImageSets\Main下
var.txt 文件中的内容复制到train.txt中 。创建文件trainval.txt,将train.txt 和var.txt的内容先后复制到trainval.txt中
到此数据已完全符合训练数据格式。

修改data数据源快捷指向:进入项目/目录下

cd data
ln -s /home/dashuai/PycharmProjects/Wider_face_data/ VOCdevkit2007

创建文件夹:(不然test会报错找不到路径)
/home/dashuai/PycharmProjects/wider_face_rcnn/data/VOCdevkit2007/results/VOC2007/Main/ # 做相应修改

开始训练

首先,在tf-faster-rcnn/lib/datasets目录下的pascal_voc.py里第36行更改自己的类别,'background’切记不可删掉,把后面的原来的20个label换成自己的,不用更改类别数目,也没有地方可以更改。

在开始训练之前,还需要把之前训练产生的模型以及cache删除掉,分别在tf-faster-rcnn/output/vgg16/voc_2007_trainval/default路径下和tf-faster-rcnn/data/cache路径下,然后就可以开始训练了:
根目录下执行:

./experiments/scripts/train_faster_rcnn.sh 0 pascal_voc vgg16   # 训练
./experiments/scripts/test_faster_rcnn.sh 0 pascal_voc vgg16   # 利用test数据集进行模型评估,train之后会自动运行test
# 运行脚本指定参数格式
python ./tools/test_net.py --imdb voc_2007_test --model output/vgg16/voc_2007_trainval/default/vgg16_faster_rcnn_iter_300.ckpt --cfg experiments/cfgs/vgg16.yml --net vgg16 --set ANCHOR_SCALES '[8,16,32]' ANCHOR_RATIOS '[0.5,1,2]'

训练阶段NAN的解决:
https://blog.csdn.net/XZZPPP/article/details/52036794

数据清洗

如果上面方法解决不了,请继续使用下面方法,数据清洗:
在VOCdevkit2007/VOC2007/ 目录下建立脚本cl.py文件,代码附在文章最后,运行脚本,会检查Annotations文件夹下面的所有xml文件,检查边界信息,xmin<xmax 等等,影响模型训练的数据,将之标记,会生成file.txt文件。 打开file文件即可看到哪一张图片异常。下一步 将/data/VOCdevkit2007/VOC2007/ImageSets/Main/ 文件夹下的所有txt文件把file.txt中的图片删除。可自行写脚本删除,博主当时异常数据不多,手动删除的。

常用操作文件以及功能介绍:

experiments/cfgs 不同模型的配置文件 batchsize 在这里设置
experiments/logs 日志文件夹,
experiments/scripts 运行脚本sh文件,
lib/model/config 通用配置文件
模型保存和加载:同一个命令运行train 训练时候 会自动加载当前命令以及训练的模型,继续训练。无需其他操作。
修改训练步数
/home/dashuai/PycharmProjects/wider_face_rcnn/experiments/scripts/train_faster_rcnn.sh
/home/dashuai/PycharmProjects/wider_face_rcnn/experiments/scripts/test_faster_rcnn.sh
找到相关数据的ITERS 参数。train_faster_rcnn 用于训练 test_faster_rcnn用于模型评估 ,test_faster_rcnn中的ITERS用于根据这个步数找到模型,(模型的命名根据步数)。关于评估需要的步数,一般是给的test数据集,一张图片一个步数。
运行test模型评估指定模型:
自己训练了一个模型,但是还没有训练完成,根据out文件夹中保存的模型,看步数。修改test_faster_rcnn.sh中的ITERS参数
./experiments/scripts/test_faster_rcnn.sh 0 pascal_voc vgg16
运行demo文件
自己训练的模型,运行demo输出需要配置和修改:/tools/demo.py

CLASSES 参数留下__background__ 和自己的类比如face
NETS ,修改使用的模型文件,比如vgg的res101的模型,修改根据步数迭代的模型
net.create_architecture  修改类目数量 类目+1 背景
CUDA_VISIBLE_DEVICES=0 ./tools/demo.py --net 'vgg16' --dataset 'pascal_voc'  #指定数据和网络

文件代码

cl.py

from xml.dom.minidom import parse
import xml.dom.minidom
import os

if os.path.exists('file'):
    os.remove('file')
list_dir = os.listdir('Annotations')
for i in list_dir:
    try:
        path = "Annotations/"+i
        DOMTree = parse(path)
        collection = DOMTree.documentElement
        width = int(collection.getElementsByTagName("width")[0].childNodes[0].data)
        height = int(collection.getElementsByTagName("height")[0].childNodes[0].data)
        boxs = collection.getElementsByTagName('bndbox')
        for x in range(len(boxs)): # 检测每一个盒子
            xmin = int(boxs[x].getElementsByTagName("xmin")[0].childNodes[0].data)
            ymin = int(boxs[x].getElementsByTagName("ymin")[0].childNodes[0].data)
            xmax = int(boxs[x].getElementsByTagName("xmax")[0].childNodes[0].data)
            ymax = int(boxs[x].getElementsByTagName("ymax")[0].childNodes[0].data)
            assert width >0 and height >0 # 长宽大于0
            assert xmin >=0 and xmax >=0 and ymax >=0 and ymin >=0  #坐标大于0
            assert xmin < xmax and ymin < ymax # 左坐标小于右坐标
            assert xmax <= width and ymax <= height # 右边坐标不越界
    except:
        with open('file', 'a') as f:
            f.write(i+'----'+ str(x)+'\r\n')

widerface_to_voc.py

# -*- coding: utf-8 -*-
"""
Created on 19-5-6

@author: 段大帅
"""
from skimage import io
import shutil
import random
import os
import string

headstr = """\
<annotation>
    <folder>VOC2007</folder>
    <filename>%06d.jpg</filename>
    <source>
        <database>My Database</database>
        <annotation>PASCAL VOC2007</annotation>
        <image>flickr</image>
        <flickrid>NULL</flickrid>
    </source>
    <owner>
        <flickrid>NULL</flickrid>
        <name>company</name>
    </owner>
    <size>
        <width>%d</width>
        <height>%d</height>
        <depth>%d</depth>
    </size>
    <segmented>0</segmented>
"""
objstr = """\
    <object>
        <name>%s</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>%d</xmin>
            <ymin>%d</ymin>
            <xmax>%d</xmax>
            <ymax>%d</ymax>
        </bndbox>
    </object>
"""

tailstr = '''\
</annotation>
'''

def all_path(filename):
    return os.path.join('Wider_face', filename)

def writexml(idx, head, bbxes, tail):
    filename = all_path("Annotations/%06d.xml" % (idx))
    f = open(filename, "w")
    f.write(head)
    for bbx in bbxes:
        f.write(objstr % ('face', bbx[0], bbx[1], bbx[0] + bbx[2], bbx[1] + bbx[3]))
    f.write(tail)
    f.close()


def clear_dir():
    if shutil.os.path.exists(all_path('Annotations')):
        shutil.rmtree(all_path('Annotations'))
    if shutil.os.path.exists(all_path('ImageSets')):
        shutil.rmtree(all_path('ImageSets'))
    if shutil.os.path.exists(all_path('JPEGImages')):
        shutil.rmtree(all_path('JPEGImages'))

    shutil.os.mkdir(all_path('Annotations'))
    shutil.os.makedirs(all_path('ImageSets/Main'))
    shutil.os.mkdir(all_path('JPEGImages'))


def excute_datasets(idx, datatype):
    f = open(all_path('ImageSets/Main/' + datatype + '.txt'), 'a')
    f_bbx = open(all_path('wider_face_split/wider_face_' + datatype + '_bbx_gt.txt'), 'r')

    while True:
        filename = f_bbx.readline().strip('\n')
        if not filename:
            break
        try:
            im = io.imread(all_path('WIDER_' + datatype + '/images/'+filename))
        except IOError:
            print('错误文件名已跳过,',filename)
            continue
        head = headstr % (idx, im.shape[1], im.shape[0], im.shape[2])
        nums = f_bbx.readline().strip('\n')
        bbxes = []
        for ind in range(int(nums)):
            bbx_info = f_bbx.readline().strip(' \n').split(' ')
            bbx = [int(bbx_info[i]) for i in range(len(bbx_info))]
            #x1, y1, w, h, blur, expression, illumination, invalid, occlusion, pose
            if bbx[7]==0:
                bbxes.append(bbx)
        writexml(idx, head, bbxes, tailstr)
        shutil.copyfile(all_path('WIDER_' + datatype + '/images/'+filename), all_path('JPEGImages/%06d.jpg' % (idx)))
        f.write('%06d\n' % (idx))
        idx +=1
    f.close()
    f_bbx.close()
    return idx


# 打乱样本
def shuffle_file(filename):
    f = open(filename, 'r+')
    lines = f.readlines()
    random.shuffle(lines)
    f.seek(0)
    f.truncate()
    f.writelines(lines)
    f.close()


if __name__ == '__main__':
    clear_dir()
    idx = 1
    idx = excute_datasets(idx, 'train')
    idx = excute_datasets(idx, 'val')
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值