2023年11月29日发(作者:)

CenterNet训练⾃⼰的数据集

重点!

⾸先说⼀下具体的代码能运⾏成功所需要的条件:

cuda9.0

与cuda9.0相匹配的cudnn

pytorch0.4.0版本

然后就是⾃⼰遇到的⼀系列问题了:

1. 安装cocoapi

⾃⼰去下载⼀个cocoapi,github上有很多:

下载完,放在CenterNet⽬录下就可以了,然后进⼊到⽬录./cocoapi/PythonAPI 运⾏

make

然后在运⾏:

python install --user

2. 安装需要⽤到的依赖库:

来到CenterNet的⽬录下,打开终端执⾏下载需要⽤到的依赖库。

pip install -r

3. 编译 Compile deformable convolutional (from DCNv2).

进⼊到指定路径下,运⾏⽂件即可。

CenterNet_ROOT/src/lib/models/networks/DCNv2

4. 编译⼀下NMS,来到external⽂件下,打开终端,环境切换到CenterNet下,编译⼀下,

make

5. 下载预训练的模型放置到models⽂件夹下,这⾥下载的是⽬标检测,选了⼀个最⾼分的。在,我下载了第⼀个model。下载完了,放

在models下。

6. 然后开始可以测试demo,来到src⽂件下,打开终端,输⼊:

python ctdet --demo /home/dlut/⽹络/CenterNet-master/images/ --load_model /home/dlut/⽹络/CenterNet-

master/models/ctdet_coco_dla_

注意这个路径要改成⾃⼰的绝对路径。就可以看到测试的结果了。

我在运⾏的时候遇到了问题:RuntimeError: cuda runtime error (11) : invalid argument at

/pytorch/aten/src/THC/:663

解决办法是:在中加了:

import torch

mean = np.array([1.816706, 1.856168, 1.751525],

dtype=np.float32).reshape(1, 1, 3)

std = np.array([2.632229, 2.685731, 2.541777],

dtype=np.float32).reshape(1, 1, 3)

(5)修改数据和图⽚路径,data_dir 输⼊的是咱们之前建⽴的数据集⽂件夹的名字,img_dir 输⼊的是 images 图⽚⽂件夹。

def __init__(self, opt, split):

super(InsulatorBolt, self).__init__()

self.data_dir = os.path.join(opt.data_dir, 'insulator_bolt')

self.img_dir = os.path.join(self.data_dir, 'images')

(6)修改json⽂件路径如下:

if split == 'val': ##################################valtest

或者

self.annot_path = os.path.join(

self.data_dir, 'annotations',

'').format(split) ##################################valtest

或者

#

⾃⼰加的

elif split == 'test':

self.annot_path = os.path.join(

self.data_dir, 'annotations',

'').format(split) # testjson

修改⽂件位置

else:

if opt.task == 'exdet':

self.annot_path = os.path.join(

self.data_dir, 'annotations',

'').format(split)

else:

self.annot_path = os.path.join(

self.data_dir, 'annotations',

'').format(split)

(7)类别名字和类别id改成⾃⼰,

self.class_name = [

'__background__', 'normal', 'defect', 'norbolt', 'debolt']

self._valid_ids = [

0,1, 2, 3, 4]

我就改了以上七点内容。

4. 将数据集加⼊src/lib/datasets/dataset_factory⾥⾯

在dataset_facto字典⾥加⼊⾃⼰的数据集名字 (格式为 '你之前创建的,因为要从你创建的

Python⽂件的名字':你⾃⼰数据集类的名字

py⽂件⾥找到你的数据类,名字必须对应上)

(1)先导包,否则会报错:导包:

from .torBolt import InsulatorBolt #⾃⼰添加的

(2)在dataset_facto字典⾥加⼊⾃⼰的数据集名字

dataset_factory = {

'coco': COCO,

'pascal': PascalVOC,

'kitti': KITTI,

'coco_hp': COCOHP,

'insulatorBolt':InsulatorBolt #

⾃⼰添加的

}

5. 修改/src/lib/

(1)将⾃⼰的数据集设为默认数据集,加⼊到help⾥⾯,15⾏左右

self.parser.add_argument('--dataset', default='insulatorBolt', ###################################

修改

help='coco | kitti | coco_hp | pascal | insulatorBolt')

(2)修改ctdet任务使⽤的默认数据集为新添加的数据集,如下(修改分辨率,类别数,均值,⽅差,数据集名字):336⾏左右

def init(self, args=''):

default_dataset_info = {

'ctdet': {'default_resolution': [512, 512], 'num_classes': 4,

'mean': [1.816706, 1.856168, 1.751525], 'std': [2.632229, 2.685731, 2.541777],

'dataset': 'insulatorBolt'}, ############################################

修改

6. 修改src/lib/utils/⽂件(变成⾃⼰数据的类别和名字,前后数据集名字⼀定保持⼀致)

(1)添加⾃⼰的数据集:47⾏左右,添加:

elif num_classes == 4 or dataset == 'insulatorBolt':

self.names = insulatorBolt_class_name

(2)460⾏左右添加⾃⼰的类别:

insulatorBolt_class_name=[

'normal', 'defect', 'norbolt', 'debolt'

]

到这⾥,准备数据集的⼯作就算完成了!

训练⾃⼰的数据吧

来到的⽂件下:/home/dlut/⽹络/CenterNet-master/src

切换环境。

python ctdet --exp_id coco_dla --batch_size 8 --master_batch 1 --lr 1.25e-4 --gpus 0

因为我只有⼀块gpu,所以gpus 设置为0,学习率,batch_size这些都可以⾃⼰进⾏修改。

想要修改参数可以去中取修改。(如果显⽰显存不够之类的那种错误,需要在⽂件中将–num_workers改成

0,batch_size改成16或者更⼩。

我在运⾏的时候遇到了问题:RuntimeError: cuda runtime error (11) : invalid argument at

/pytorch/aten/src/THC/:663

解决办法是:在中加了:

import torch

d = False #加上这两句就可以跑通代码

没什么意外的话,应该开始训练了。

评价结果

当训练完之后,在./exp/ctdet/coco_dla/⽂件夹下会出现如下⽂件

其中,model_last是最后⼀次epoch的模型;model_best是val最好的模型,我选的是model_best模型;

将中两处的 替换为在63⾏和100⾏左右。

split = 'val' if not al else 'test'split = 'test

然后终端输⼊:

python --exp_id coco_dla --not_prefetch_test ctdet --load_model /home/dlut/⽹络/CenterNet-

master/exp/ctdet/coco_dla/model_

开始评价。

不出意外的话会出现下⾯的画⾯(出现⼀系列AP值),其中,⼀般使⽤的是第⼆⾏,也就是IOU=0.5,全区域的AP值,其他的分别是不同

IOU以及不同⽬标尺⼨区域的结果。

测试结果

##########################txt########################

某⼀个⽂本中的数字存的是图⽚的名字,要把这些名字的图⽚保存到另⼀个⽂件夹中

#

修改两处,注意⾃⼰建⽴⽂件

from PIL import Image

import os

f3 = open("/home/dlut/⽹络/CenterNet-master/VOC2018/ImageSets/Main/",'r') #test

⽂件所在路径

for line2 in f3.readlines():

line3=line2[:-1] # 000000

读取所有数字

im = Image.open('/home/dlut/⽹络/CenterNet-master/VOC2018/JPEGImages/{}.jpg'.format(line3))#line3

打开改路径下的记录的的⽂件名

im.save('/home/dlut/⽹络/CenterNet-master/VOC2018/testImg/{}.jpg'.format(line3)) # #

把⽂件夹中指定的⽂件名称的图⽚另存到该路径下⾃⼰需要新建⼀

个新的⽂件夹

f3.close()

然后我把所有需要测试的图⽚存放在了testImg下,把testImg⽂件放在CenterNet-master⽬录下⾯,然后在开始测试。

2. 要注意的是,当弹出第⼀站图⽚的时候,按esc除外的任意键可以继续检测下⼀张图,想要保存检测结果的话,只需要在

src/lib/detectors/⽂件中:

def show_results(self, debugger, image, results):

debugger.add_img(image, img_id='ctdet')

for j in range(1, self.num_classes + 1):

for bbox in results[j]:

if bbox[4] > self.opt.vis_thresh:

debugger.add_coco_bbox(bbox[:4], j - 1, bbox[4], img_id='ctdet')

#_all_imgs(pause=)

debugger.save_all_imgs(path='/home/dlut/⽹络/CenterNet-master/output/', genID=True)

加上⼀⾏代码,就是最后⼀⾏,path是输出路径,需要在

_all_imgs(path='/home/dlut/⽹络/CenterNet-master/output/', genID=True)

CenterNet⽂件夹下新建⼀个⽂件夹output,然后再运⾏⼀遍发现检测后的图⽚就会保存在这个⽂件夹⾥⾯了。当然,去掉倒数第⼆

,那么运⾏的时候就不会弹出照⽚了。

show_all_imgs

参考:

感谢博主写的那么详细,但是⾃⼰在运⾏的时候,还是遇到了⼀些问题,所以⾃⼰重新总结谢了⼀份。