此博客为博主在复现模型时的记录,好处是问题比较全面,缺点是语言表述可能不够清晰。
最近需要用到实力分割模型,之前介于mask rcnn的运行速度过慢,所以这次为了练手,选择了这个实力分割的模型。
为了好好研究下训练集的结构,以便自己能够制作自己的训练集,我决定下载voc2012的进行研究,这也是此代码官方的测试文件。
2012年的Pascal VOC数据集:
http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
下载这个数据集非常的慢,等待了很长时间,等其下载下来继续研究。
这里我提供一个百度网盘链接:https://pan.baidu.com/s/1R1DcMhx-YmxSE5PzsaiJpQ
由于工程之间的共同性很大,因此可能有的模型是没有多少博客介绍复现的,但是我们可以通过其他类型的模型的复现过程来复现,例如此模型和mask rcnn都是实力分割的模型,因此可以参考mask rcnn的复现。
将下载好的数据集解压到该目录下(由于我之前跑yolov3模型就是这样的,因此这里也暂时是这样)
我所使用的环境是python3,tensorflow-gpu一个较新的版本。
目前我的系统是Windows10,因此先打开了train.py文件:
先看到第24行,写的是'/home/VOCdevkit',这明显是Ubuntu下的,因此需要修改一下,直接修改为'./VOCdevkit'
直接改成解压后文件VOCdevikit的绝对路径也是可以的。
batch_size由于我本人先是在自己的电脑上尝试的,我先改成2,防止电脑带不动()。
再看:
读了下面的我才知道这个是存放一个保存的训练模型的地方,那么先新建一个这样的文件夹吧。
最后的框图大概是这样的。
我开始尝试启动train.py先去训练一下VOCdevkit的数据集,因为官方代码针对这个数据集,可以直接使用,但是我发现报了如下的错误:
我去网上查阅了一下,isinstance(s, basestring)这个是python2才有的语句,python3里已经不用了。
我记得python给了一个从2转换为3的程序,叫2to3.py,因此我想尝试用他来改下这个地方看看能不能跑通,否则我就决定先用python2来实现。如果你们装了anaconda,那么这个2to3.py就在anaconda\Tools\scripts里面。
用法:
python 2to3.py -w to/your/path
-w后面就是你想转换的文件的路径。
我们选择kaffe/tensorflow里的network.py修改
然后我看到了这个程序把他变成了str。
还有在network里面需要修改:
在c_i前面加上int,保证类型一致
还有170行这里也在c_i前加上int
这时我看到虽然没有训练起来,但是已经没有报错了。(注:这里出现的一堆警告是由于某函数快要不再维护了)还是报错了,因为我忘记下载预权重文件了
下载地址:https://drive.google.com/drive/folders/0B_rootXHuswsZ0E4Mjh1ZU5xZVU
这个我认为应该没有限速,因此没有上传网盘,但是要翻墙。
下载好了两个文件直接放在根目录:
接下来继续尝试,结果报了如下错误:
这里说明他已经准备要训练了,只是没有找到这个路径,但是SegmentationClass我已后改成了SegmentationClassAug,因此我去图片库里看了,的确没有。
看来不能直接用别人的东西训练,不过我已经找到了自己训练的规律了。打开dataset文件夹:
train,test和val学过深度学习的小伙伴应该懂得意思,大致是我抽70%数据用于训练,15%用于测试,15%用于防止过拟合。想要了解的请看这篇文章:https://www.mobibrw.com/2017/7966
那么我得自己想办法了,大致思路就是把VOCdevkit里面的JPEGImages和SegmentationClass(我名字改回来了)抽取部分训练,部分测试等。我决定自己尝试写个脚本。
这里我默认这个VOCdevkit里面的就是自己的数据集,标注放置的我会记录,但是由于实力分割标注比较麻烦因此我这里不用自己标注的图。但是我会写明如何制作自己的数据集,怎么放,然后怎么操作。我先用标注好的训练,再最后我再写怎么做数据集。
我为此去找了一下随机数的函数random的用法,然后写了下面的脚本。先复制如下代码到VOC2012的目录下,我命名为random_sort.py
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 20 12:09:02 2018
@author: Ruoyu Chen
Randomly extract data, 70% as train, 15% as test, 15% as val.
"""
import os
import random
SegmentationClass = 'SegmentationClass'
dir_list = os.listdir(SegmentationClass)
num = len(dir_list)
num_train = sorted(random.sample(dir_list,int(num*0.7)))
least = list(set(dir_list).difference(set(num_train)))
num_test = sorted(random.sample(least,int(len(least)/2)))
num_val = list(set(least).difference(set(num_test)))
test = open('test.txt', 'w')
train = open('train.txt', 'w')
val = open('val.txt', 'w')
for name in dir_list:
if name in num_train:
train.write('/VOC2012/JPEGImages/'+ name.split('.')[0] +'.jpg /VOC2012/SegmentationClass/' + name + '\n')
elif name in num_test:
test.write('/JPEGImages/'+ name.split('.')[0] +'.jpg /SegmentationClass/' + name + '\n')
elif name in num_val:
val.write('/JPEGImages/'+ name.split('.')[0] +'.jpg /SegmentationClass/' + name + '\n')
train.close()
val.close()
test.close()
如图所示:
然后运行random_sort.py可以得到三个文件:train.txt,val.txt和test.txt
然后把这3个文件复制到根目录的dataset文件夹下:
(注:那个压缩包是我把原来5个文件给压缩放起来了)
好了,这个做好了,我要尝试一下训练了。
报了错,我觉得应该没有问题了,这个问题可能是电脑显存不足,我电脑的确跑不动这样的程序,我现在准备把这个代码放到我的老师的电脑上,是1080ti的显卡。
在一块1081ti上的训练情况:
好了,这样就成功地跑通了这个模型了。
测试用的是inference.py
这里在根目录新建一个文件夹output,放输出图片地址
打开inference.py文件,在img_path前加两个’-‘,方便在命令行中操作,下面的模型权重也是。
然后我们在snapshots文件夹中看到我们训练的一些模型,经过培训,我有多个看起来像的文件model.ckpt-xxxx.index
,model.ckpt-xxxx.dataxxxx
和model.ckpt-xxxx.meta
。我应该使用哪一个来恢复模型以进行推理?
必须提供,而不是提供其中一个文件的路径model.ckpt-xxxx
。它将获取其他文件。
比如我有model.ckpt-2000.index
,model.ckpt-2000.dataxxxx
和model.ckpt-2000.meta,我提供其路径中输入
model.ckpt-2000就可以了。
下面是执行命令,比如我在根目录放了一个图叫img.jpg,用model.ckpt-2000:
python inference --img_path img.jpg --model_weights snapshots/model.ckpt-2000
然后我就可以在output这个文件夹看到结果了,是掩码的结果。
先更新到这里,以后再说,1星期内会有进度