首先说一下具体的代码能运行成功所需要的条件:
cuda9.0
与cuda9.0相匹配的cudnn
pytorch0.4.0版本
然后就是自己遇到的一系列问题了:
Q1
首先我是想在自己原来的cuda10.0和cudnn下运行的,但是出现了很多问题,尤其是在编译DCNv2的时候,于是我参考了这篇博客,发现问题并没有解决,主要问题是想要和cuda10.0匹配,那么pytorch就不能是0.4.1版本的,就一定会高于这个版本,那么出现的ImportError: torch.utils.ffi is deprecated. Please use cpp extensions instead.问题和TypeError: dist must be a Distribution instance问题就不可避免,想要解决就只能自己重写DCNv2的代码,所以我放弃了。
选择重新安装cuda9.0
自己的电脑是2080Ti的,已经有的环境是cuda10.0+与cuda10.0匹配的cudnn7.6.5。
由于代码在cuda10.0下会出现很多错误,所以我先把cuda10.0换成了cuda9.0。详细请参考另一篇博客:安装另一个版本cuda和cudnn
cuda和cudnn已经安装好了,开始利用Anaconda搭建一个新的环境,来运行CenterNet网络。
conda create --name CenterNet python=3.6
conda activate CenterNet
pip install torch==0.4.1
pip install torchvision==0.2.2
一定一定!!!记住就是打开终端的时候记得切换环境!后面的很多操作,我没有强调切换环境,但是只要你是重新开启了新的终端就一定要切换环境!切换到CenterNet。
这样暂时算环境搭建完毕,现在想试试demo能不能跑起来。
make
python setup.py install --user
pip install -r requirements.txt
下载需要用到的依赖库。CenterNet_ROOT/src/lib/models/networks/DCNv2
下,运行make.sh
文件即可。make
python demo.py ctdet --demo /home/dlut/网络/CenterNet-master/images/ --load_model /home/dlut/网络/CenterNet-master/models/ctdet_coco_dla_2x.pth
我在运行的时候遇到了问题:RuntimeError: cuda runtime error (11) : invalid argument at /pytorch/aten/src/THC/THCGeneral.cpp:663
解决办法是:在demo.py中加了:
import torch
torch.backends.cudnn.enabled = False #加上这两句就可以跑通代码
一般,我们自己的数据集都是VOC格式的,这个需要转换成coco格式的数据集,参考另一篇博客。
“insulatorBolt.py”
,文件内容照着文件夹下coco.py改成自己的。class InsulatorBolt(data.Dataset):
num_classes=80
改成自己的类别数,我的是四类,所以改为了num_classes=4
default_resolution = [512, 512]
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': ##################################val或者test
self.annot_path = os.path.join(
self.data_dir, 'annotations',
'val.json').format(split) ##################################val或者test
#自己加的
elif split == 'test':
self.annot_path = os.path.join(
self.data_dir, 'annotations',
'test.json').format(split) # 修改test的json文件位置
else:
if opt.task == 'exdet':
self.annot_path = os.path.join(
self.data_dir, 'annotations',
'train.json').format(split)
else:
self.annot_path = os.path.join(
self.data_dir, 'annotations',
'train.json').format(split)
(7)类别名字和类别id改成自己,
self.class_name = [
'__background__', 'normal', 'defect', 'norbolt', 'debolt']
self._valid_ids = [
0,1, 2, 3, 4]
我就改了以上七点内容。
Python文件的名字':你自己数据集类的名字
,因为要从你创建的py文件里找到你的数据类,名字必须对应上)from .dataset.insulatorBolt import InsulatorBolt #自己添加的
dataset_factory = {
'coco': COCO,
'pascal': PascalVOC,
'kitti': KITTI,
'coco_hp': COCOHP,
'insulatorBolt':InsulatorBolt #自己添加的
}
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'}, ############################################修改
elif num_classes == 4 or dataset == 'insulatorBolt':
self.names = insulatorBolt_class_name
(2)460行左右添加自己的类别:
insulatorBolt_class_name=[
'normal', 'defect', 'norbolt', 'debolt'
]
到这里,准备数据集的工作就算完成了!
来到main.py的文件下:/home/dlut/网络/CenterNet-master/src
切换环境。
python main.py ctdet --exp_id coco_dla --batch_size 8 --master_batch 1 --lr 1.25e-4 --gpus 0
因为我只有一块gpu,所以gpus 设置为0,学习率,batch_size这些都可以自己进行修改。
想要修改参数可以去opts.py中取修改。(如果显示显存不够之类的那种错误,需要在opts.py文件中将–num_workers改成0,batch_size改成16或者更小。
我在运行的时候遇到了问题:RuntimeError: cuda runtime error (11) : invalid argument at /pytorch/aten/src/THC/THCGeneral.cpp:663
解决办法是:在main.py中加了:
import torch
torch.backends.cudnn.enabled = False #加上这两句就可以跑通代码
没什么意外的话,应该开始训练了。
当训练完之后,在./exp/ctdet/coco_dla/文件夹下会出现如下文件
其中,model_last是最后一次epoch的模型;model_best是val最好的模型,我选的是model_best模型;
将test.py中两处的 split = 'val' if not opt.trainval else 'test'
替换为split = 'test
在63行和100行左右。
然后终端输入:python test.py --exp_id coco_dla --not_prefetch_test ctdet --load_model /home/dlut/网络/CenterNet-master/exp/ctdet/coco_dla/model_best.pth
开始评价。
不出意外的话会出现下面的画面(出现一系列AP值),其中,一般使用的是第二行,也就是IOU=0.5,全区域的AP值,其他的分别是不同IOU以及不同目标尺寸区域的结果。
这回运行demo.py来查看自己的结果。
##########################某一个txt文本中的数字存的是图片的名字,要把这些名字的图片保存到另一个文件夹中########################
#修改两处,注意自己建立文件
from PIL import Image
import os
f3 = open("/home/dlut/网络/CenterNet-master/VOC2018/ImageSets/Main/test.txt",'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目录下面,然后在开始测试。
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')
#debugger.show_all_imgs(pause=self.pause)
debugger.save_all_imgs(path='/home/dlut/网络/CenterNet-master/output/', genID=True)
加上一行代码,就是最后一行debugger.save_all_imgs(path='/home/dlut/网络/CenterNet-master/output/', genID=True)
,path是输出路径,需要在CenterNet文件夹下新建一个文件夹output,然后再运行一遍发现检测后的图片就会保存在这个文件夹里面了。当然,去掉倒数第二行show_all_imgs
,那么运行的时候就不会弹出照片了。
参考:
(绝对详细)CenterNet训练自己的数据(pytorch0.4.1)
感谢博主写的那么详细,但是自己在运行的时候,还是遇到了一些问题,所以自己重新总结谢了一份。