Matterport版Mask RCNN——训练自己的数据集——踩坑小记
前言
一、基本配置
系统配置
Matterport环境配置
Conda 虚拟环境
Pycharm的安装和使用上述环境
二、制作自己的数据集
实现默认程序测试结果
制作labelme数据集
安装labelme
改进的json_to_dataset.py
准备好的数据目录结构
三、自定义数据集训练
增加头文件include
确认yaml读取函数
代码修改内容总结
前言
最近基于一台新机器,配置了深度学习工作站,并跑起了matterport版的Detectron。中间各种坑,现在记录如下,有后来者看到诸坑,按照我说的方案解决即可。
一、基本配置
系统配置
操作系统:Ubuntu 16.04
CUDA:Version 9.0.176
CUDNN:7.0.5
Anaconda: 3.6
查看自己电脑的CUDA和CUDNN版本的命令:
cuda 版本
cat /usr/local/cuda/version.txt
cudnn 版本
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
Matterport环境配置
Conda 虚拟环境
这里主要指的是:基于Anaconda为Mask RCNN创造一个conda的虚拟环境。
方法大体可参照:
https://blog.csdn.net/wc781708249/article/details/79438972
使用Keras和Tensorflow设置和安装Mask RCNN
注意:一定要为Mask RCNN单独创造一个虚拟环境,因为后续调试要用到Pycharm,Pycharm直接加载这个环境就可以运行程序了。
Pycharm的安装和使用上述环境
为何要使用Pycharm,因为相比于matterport提供的ipynb格式的代码,这个更方便调试。
安装大体可以参考:
https://blog.csdn.net/anjingshen/article/details/80038316
Pycharm 2018.1.1 使用anaconda 3中已创建的环境
略有不同的是,最后一步,
按照里面的步骤从pycharm链接虚拟环境中的python3.exe。
(因为我用的是anaconda3.6,对应python3)
请注意上文以及下文的“大体可参考”中的“大体”表示:
我当初不是依靠着这篇博文解决的问题,但是我暂时没从历史记录里找到当时的网页,因此我临时给大家找了另一篇但是和我方法相同的博文(如果有时间我会再寻找)
二、制作自己的数据集
这一块,网上诸多大神都搞出来了自己的版本,我也是博览群雄,然后实现出来了。因此,下面,我不打算做重复的黏贴工作,我会把我用到的链接贴过来(也是尊者每个作者的辛劳),然后把我遇到的问题写出来,你可以避免这个坑。
实现默认程序测试结果
首先,ipynb转py这个用jupyter来另存为转化的流程也不多说了,网上都有教程。
也就是你会获得:
/Mask_RCNN/samples/demo.py
/Mask_RCNN/samples/shapes/train_shape.py
两个函数,首先要跑通这两个函数,表示matterport程序安装、运行成功。
额外说一句,稳妥起见,你可以刚装好matterport之后,直接在官方默认的jupyter notebook下测试上述两个文件,即demo.ipynb和train_shape.ipynb,如果有问题能早发现。毕竟,更好的调试环境和程序能否跑通这两个是并行而不是串行的工作。
下面是网上随便找的一张图的测试结果,以及matterport训练自己数据集(三角、圆、方块)的跑通结果图。
两只兔子表示被无视了。
制作labelme数据集
安装labelme
这个部分不多说了吧,网上教程一大把,
大体应该有这两个步骤吧,不详细说了。
pip install pyqt5
pip install labelme
安装完了,在命令行端,输入labelme可以打开该软件。
改进的json_to_dataset.py
为何要改进,目的有二:
我们需要批处理而不是一个一个json文件来转化。
默认labelme程序生成的是16位mask,我们需要8位,还要转化。
这个网上版本很多,但是很多都有错误或者功能不全。
我现在选了一个最优的版本也是我用的版本,然后说怎么改。
https://blog.csdn.net/u014513323/article/details/81166997
改进json_to_dataset.py,使得能够批量处理多张图片并一步建好所需目录及相关mask文件,运行后,在json文件夹中会出现mask_png、labelme_json文件夹,mask_png中存放的是所有8位掩码文件!
按照文中所述,操作步骤有两步:
将本程序替换掉labelme/cli中的相应文件—json_to_dataset.py
编者注:在前面的matterport安装中,你安装了labelme,这个labelme/cli是说的anaconda中的labelme,在你自己的ubuntu系统中,这个文件所在位置应该是类似如下地址:
/home/你的名字/anaconda3/envs/MaskRCNN/lib/python3.6/site-packages/labelme/cli
在cmd中输入python json_to_dateset.py /path/你的json文件夹的路径
编者注:我是不用加python,你也可以不加,直接这样搞:
labelme_json_to_dataset /home/你的名字/Downloads/jsonfiles
Downloads/jsonfiles是你存放json文件的位置,这个位置随意。
然后,是原文中有两个错误需要修改:
文中有几行包含“mkdir”和“\”符号,比如第53行:
os.mkdir(json_file + '\\' + 'labelme_json')
错误一:mkdir无法生成多级目录,需要makedirs。
错误二:“\”似乎有问题,生成了一堆文件名中含有“\”的文件,我改成了“/”
所以,包含包含“mkdir”和“\”符号的这几行都要改,类似这样:
os.makedirs(json_file + '/' + 'labelme_json')
然后就运行成功了。
准备好的数据目录结构
自定义数据集训练和检测,基本上是参考着一篇高访问量的牛文来实现的,因此数据格式也是参考他的。
先直接列出来数据结构和文件命名,牛文自己以及其他博文语焉不详,我这里给你写清楚。
注意,以下命名并非强制,而是与牛文代码相一致,看着不爽,调通后自己改名字也可以。但是调通之前,请严格按照下图设置。
多少年不画图,画个图耗掉半条命。
mask表示8位掩膜,里面文件命名如1.png,2.png。
rgb表示原图,就是你自己的数据集原图,但是这是labelme生成出来的,文件命名如rgb_1.png,rgb_2.png。
total是yaml等文件的根目录文件夹名,没有什么道理叫这个名字,不爽可以后续删改。但是暂时可以照搬。而且我打赌你调通以后也就懒得再改了。total下面有形如rgb_x_json等文件夹,每个里面有info.yaml和label_names.txt。
上述labelme_json_to_dataset命令生成的文件名未必与图示要求的一样,暂时来说,你可以先标记几个样本,手动修改名称,按照上述图示放置到正确的目录中,先把程序跑通再说。程序没问题了,你也制作了很多样本的json文件后,必然面对着大批量的json文件转化工作,一个个修改命名不现实,届时可以再度完善json_to_dataset.py文件,使它生成的数据直接就是图示的名称。
三、自定义数据集训练
牛文:
https://blog.csdn.net/l297969586/article/details/79140840
Mask RCNN训练自己的数据集
以下用牛文代指该文。
请首先参照此文添加新的DrugDataset类、修改代码。别怕麻烦。
然后再添加或者注意以下三点:
增加头文件include
from PIL import Image
import yaml
import skimage.io
确认yaml读取函数
当初忘了是哪里拷贝过来的,一开始from_yaml_get_class函数有问题,就是序号和名称位置反了。又找了个正确版本改好了。总之,一定确认yaml函数如下,我拷贝过来的版本似乎漏了这句话labels = list(labels.keys())。
def from_yaml_get_class(self, image_id):
info = self.image_info[image_id]
with open(info['yaml_path']) as f:
temp = yaml.load(f.read())
labels = temp['label_names']
labels = list(labels.keys())
del labels[0]
return labels
这个版本是对的。也是现在牛文中的版本。
代码修改内容总结
最后的修改后的train_shape.py的代码内容应该是:
新的更全的头文件
根据你自己的需求,轻微调参修改的class ShapesConfig(Config)类
被注释掉的class ShapesDataset(utils.Dataset)及其诸函数。
新添加的class DrugDataset(utils.Dataset)类及其函数。
代码主体修改添加了dataset_root_path,img_floder,mask_floder,yaml_floder的位置和修改图像大小那一段。(注:应为folder,原作者笔误。)
添加train与val数据集准备 dataset_train = DrugDataset()和 dataset_val = DrugDataset()那几段。
后续# Which weights to start with?那一段不动。
注释掉model.train(dataset_train,dataset_val,learning_rate=config.LEARNING_RATE/10,epochs=50,layers=“all”)之后的代码就好了。
至此,训练部分就应该可以进行了。测试部分比着葫芦画瓢改改也就行了。之前的train_shape代码最后本身就有测试代码,按照自己的数据稍作改动即可。
大家先看着,有问题我再修改补充。(待续)