前言
- 如何在anconda创建Faster-RCNN虚拟环境和用pycham为项目配置环境见(linux)Faster-RCNN pytorch目标检测1:环境配置gpu+anaconda+pycham+ RTX2080ti 笔记,确认你已经编译完成
- 部分参考: Faster-RCNN.pytorch的搭建、使用过程详解(适配PyTorch 1.0以上版本\使用Faster RCNN训练自己的数据集_fasterrcnn训练自己的数据集\用自己的数据集训练Faster RCNN的详细全过程\ 解决faster-rcnn中训练时assert(boxes[:,2]>=boxes[:,0]).all()
- Faster-RCNN pytorch1.0链接https://github.com/jwyang/faster-rcnn.pytorch/tree/pytorch-1.0,建议直接下载后提取
- 预训练模型下载
VGG16: https://filebox.ece.vt.edu/~jw2yang/faster-rcnn/pretrained-base-models/vgg16_caffe.pth
ResNet101:https://filebox.ece.vt.edu/~jw2yang/faster-rcnn/pretrained-base-models/resnet101_caffe.pth
- 如果无法上github。百度云盘链接:https://pan.baidu.com/s/1mde9g4FN68TTPamRMl_kBw?pwd=s5sb 提取码:s5sb,或者Faster-RCNNpytorch1.0,vgg16-caffe.pth和resnet101-caffe.pth-CSDN文库。包含Faster-RCNN pytorch1.0源码和要用到的预训练模型vgg16_caffe.pth、resnet101_caffe.pth
- pycharm汉化Pycharm汉化简单图文教程
- 报错ImportError: cannot import name '_mask '、 assert (boxes[:, 2] >= boxes[:, 0]).all()AssertionError 和RuntimeError: CUDA out of memory 解决在最后
数据集准备
- 在Faster-RCNN根目录下新建data文件夹
- 在data文件夹中新建VOCdevkit2007文件夹,VOCdevkit2007中新建VOC2007
- VOC2007文件夹下新建 JPEGImages 存放jpg图像文件,和Annotations文件夹存放xml标注文件
- 新建ImageSets/Main文件夹,划分数据集,split_train_val.py代码如下
import os
import random
import argparse
parser = argparse.ArgumentParser()
# ***为该数据集的绝对路径
parser.add_argument('--xml_path', default='***/Annotations', type=str, help='input xml label path')
parser.add_argument('--txt_path', default='***/ImageSets/Main', type=str, help='output txt label path')
opt = parser.parse_args()
trainval_percent = 0.9 # 训练集和验证集所占比例。
train_percent = 0.7 # 训练集所占比例,可自己进行调整
xmlfilepath = opt.xml_path
txtsavepath = opt.txt_path
total_xml = os.listdir(xmlfilepath)
if not os.path.exists(txtsavepath):
os.makedirs(txtsavepath)
num = len(total_xml)
list_index = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)
file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_test = open(txtsavepath + '/test.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/val.txt', 'w')
for i in list_index:
name = total_xml[i][:-4] + '\n'
if i in trainval:
file_trainval.write(name)
if i in train:
file_train.write(name)
else:
file_val.write(name)
else:
file_test.write(name)
file_trainval.close()
file_train.close()
file_val.close()
file_test.close()
运行结果如下
- 如果你的数据集目标种类名称含大写字母,需要修改为小写格式,否则可能会报错,修改代码如下
# coding:utf-8
import os
import os.path
import xml.dom.minidom
path = r'\你的xml路径(最好备份一下)'
files = os.listdir(path) # 得到文件夹下所有文件名称
for xmlFile in files: # 遍历文件夹
if xmlFile[-4:] in ['.xml']:
dom = xml.dom.minidom.parse(os.path.join(path, xmlFile))
root = dom.documentElement
# 获取xml中name对应节点
name = root.getElementsByTagName('name')
for i in range(len(name)):
if name[i].firstChild.data == 'ABC': #修改为你的classname
name[i].firstChild.data = 'abc'
# 保存修改到xml文件中
with open(os.path.join(path, xmlFile), 'w', encoding='UTF-8') as fh:
dom.writexml(fh, encoding='UTF-8')
jcsjj xmin xmax
训练
将预训练模型放在data文件夹下的pretrained_model里
修改pascal_voc.py
根目录/lib/datasets/pascal_voc.py
找到class_name ,保留__background__,其余改为你自己的种类。种类名不能含大写字母,xml修改方法见上面。
训练指令
在终端运行:
CUDA_VISIBLE_DEVICES=0,1 python trainval_net.py --dataset pascal_voc --net res101 --bs 4 --nw 4 --lr 0.005 --lr_decay_step 5 --cuda --epochs 50
CUDA_VISIBLE_DEVICES GPU ID,即使用哪块GPU进行训练,这里0,1为双显卡,单显卡0
–dataset:指训练数据集名称,此处以pascal-voc为例。
–net:所使用的backbone网络,即你要使用的预训练模型,可以换为vgg16。
–bs:指的batch size,显存不够就调小bs。
–nw:指的是worker number,取决于你的Gpu能力
–lr:指学习率
–cuda:指的是使用gpu。
–epoch:指要训练的轮数。
训好的model会存到models文件夹中
出现报错RuntimeError: CUDA out of memory时将bs和nw改小
测试
test_net.py测试
训练完成后,首先进入文件夹model/res101/pascal_voc,查看训练完成之后保存的模型
在文件夹主目录中输入指令进行测试
python test_net.py --dataset pascal_voc --net res101 --checksession 1 --checkepoch 50 --checkpoint 1288 --cuda
运行完成可以看结果
报错 ImportError: cannot import name '_mask '
参考
需要安装CoCO API:
在FasterRCNN pytorch文件夹打开终端,激活farcnn虚拟环境,依次执行
conda activate farcnn
cd data
git clone https://github.com/pdollar/coco.git
cd coco/PythonAPI
make
完成即可关闭终端
重新运行指令,顺利进行
报错assert(boxes[:,2]>=boxes[:,0]).all()
参考解决faster-rcnn中训练时assert(boxes[:,2]>=boxes[:,0]).all()的问题略有修改
(1) 修改lib/datasets/pascal_voc.py,_load_pascal_annotation(,)函数
将Xmin,Ymin,Xmax,Ymax 后的-1全部去掉
(2) 修改lib/datasets/imdb.py,append_flipped_images()函数
数据整理,在一行代码为 boxes[:, 2] = widths[i] - oldx1 - 1下加入代码:
aboxes = boxes
for b in range(len(boxes)):
if boxes[b][2] < boxes[b][0]:
boxes[b][0] = boxes[b][2]
boxes[b][2] = aboxes[b][0]
原因是数据集中可能有标注框的xmin>xmax,造成报错,这里借助aboxes实现xmin与xmax数据互调
报错RuntimeError: CUDA out of memory
显存不够或Gpu能力不够,将指令中bs和nw改小
CUDA_VISIBLE_DEVICES=0,1 python trainval_net.py --dataset pascal_voc --net res101 --bs 4 --nw 4
报错KeyError: 'difficult'
difficult = np.array([x['difficult'] for x in R]).astype(np.bool)
KeyError: 'difficult'
difficult = np.array([x['difficult'] for x in R]).astype(np.bool)