FCN制作自己的数据集、训练和测试 caffe
2017-10-05 10:12
483 查看
原文:http://blog.csdn.net/zoro_lov3/article/details/74550735
花了两三周的时间,在导师的催促下,把FCN的全部流程走了一遍,期间走了很多弯路,现在记录一下。系统环境:ubuntu 16.04LTS
一、数据集的制作
注:我的数据集是仿照VOC数据集进行制作的
1.resize 数据集
我的GPU显存4G,跑过大的图片带不动,需要resize图片大小,放几个修改图片大小的程序。
(1)单张图片resize
2
3
4
5
6
7
8
9
(2)resize整个文件夹里的图片
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(3)按比例resize
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2.制作索引图
(1)下载labelme
下载地址:https://github.com/wkentaro/labelme
下载后按提示打开软件,进行标注,保存会生成后缀为json的文件。
(2)生成dataset文件夹
在终端输入指令:
(3)为文件夹下的label.png着色
首先需要对照VOC分割的颜色进行着色,一定要保证颜色的准确性。Matlab代码:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
对应的VOC数据集中的颜色类别:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
然后使用Python的skimage库进行颜色填充,具体函数是skimage.color.label2rgb(),代码较长,有需要可私信。
————————-2017年9月26日 新增————————-
太多人和我私信要代码,前一段时间很忙都没有及时回复大家,所以这里放个链接,需要自取。
https://github.com/hitzoro/FCN-ColorLabel
3.将填充后的label.png转为灰度图
如果不转,在训练的时候回报错,转换matlab代码如下:
2
3
4
5
6
7
8
转化后,在python中检查一下图片的格式:
2
3
如果输出一致,则索引图制作正确。
二、FCN训练自己的数据集
1.前期准备
默认已经安装好显卡驱动,cuda,cudnn,opencv。
最新版caffe下载: https://github.com/BVLC/caffe
fcn源代码下载:https://github.com/shelhamer/fcn.berkeleyvision.org
caffe的配置安装可以参考我的另一篇博客:http://blog.csdn.net/zoro_lov3/article/details/60581174
2.数据集准备
这里我们需要两个数据集包,benchmark和VOC2012,进入fcn/data,新建sbdd文件夹(如果没有),将benchmark解压到sbdd中,将VOC2012解压到data下的pascal文件夹下。
这两个在网上都可以找得到。
这两个数据集有什么用呢?在FCN中VOC数据集的训练需要他俩,benchmark中的dataset用来存放训练时的数据,VOC2012存放测试时的数据。
先制作训练时的数据
进入dataset中的img文件夹,这里存放训练用的原图,把原来的原图替换为你自己的原图。接着修改train.txt ,写入你训练图片的名字,注意不要加后缀。如下即可:
2
3
4
5
6
7
8
9
10
进入cls文件夹,这里原本需要存放mat格式的文件,但是制作mat文件有点麻烦,参考了网上的资料,修改代码,使得这里也可以直接存放索引图。
方式如下:
修改fcn目录下的voc_layers.py
注释掉原本的load_label ,修改为新的
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
制作测试集数据
测试集的制作简单一写,进入VOC2012,进入JPEGImages文件夹,里面存放测试用的原图,然后进入SegmentationClass,里面存放测试用的索引图,最后进入ImageSets/Segmentation,有一个名为seg11valid.txt的文件,它和train.txt的性质一样,存放测试用的图片名。
到此,数据集就准备完成了。
3.修改网络参数
下载VGG16的预训练模型并放在FCN源码文件夹中的ilsvrc-nets文件夹下
https://pan.baidu.com/s/1qYJeFfQ
为了避免运行程序时候出现no module named caffe
在代码中包含import caffe的py文件(solve.py)的第一行加入
2
其中,/home/hitoia/caffe/python为你下载的caffe源码中python文件夹的路径
cd进入fcn源码路径
以个人路径为例:/home/hitoia/fcn.berkeleyvision.org/
将其中所有的py文件,例如surgery.py等等,全部复制到voc-fcn32s文件夹中
solver.prototxt文件修改
进入voc-fcn32s文件夹 打开solver.prototxt
其中snapshot:10000 表示训练10000次保存一次模型
snapshot_prefix:”/home/hitoia/fcn.berkeleyvision.org/voc-fcn32s/snapshot/train”
表示训练得到的模型,也就是model存放的路径
在此,我附上个人的solver.prototxt供大家参考
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
solve.py的修改
在这里郑重声明一下:如果训练fcn32s的网络模型,一定要修改solve.py利用transplant的方式获取vgg16的网络权重。
具体操作为:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
关于VGG_ILSVRC_16_layers_deploy.prototxt 可以在http://pan.baidu.com/s/1geLL6Sz下载。
如果训练fcn16s,则可以直接copy自己的fcn32s的model的权重,不需要transplant,也就是不需要修改solve.py
如果训练fcn8s,则可以直接copy自己的fcn16s的model的权重,不需要transplant,也就是不需要修改solve.py
只有如此,才能避免loss高居不下的情况
这里的:
2
3
奇怪的现象:修改solver.prototxt中的max_iter: 100000没有改变最大迭代次数,只有改变这个step里的数字才有用,这里最大迭代次数等于25*1000 = 25000次。
train.prototxt / val.prototxt 修改
所有num_output 为21 的地方都修改为自己分类数 + 1 (加的1是背景),最开始的param_str需要根据自己的情况修改,放一下我自己的
train.prototxt:
val.prototxt:
准备完成,在voc-fcn32s路径下输入
就可以开始训练
三、单张测试
在fcn源码文件夹,找到infer.py。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
其中,net = caffe.Net(‘voc-fcn32s/deploy.prototxt’, ‘voc-fcn32s/snapshot/train_iter_24000.caffemodel’, caffe.TEST),其中train_iter_24000.caffemodel’是我训练后得到的模型。
如果没有deploy文件,可以参考如下方法:
首先,根据你利用的模型,例如模型是voc-fcn32s的,那么你就去voc-fcn32s的文件夹,里面有train.prototxt文件,将文件打开,全选,复制,新建一个名为deploy.prototxt文件,粘贴进去,
然后ctrl+F 寻找所有名为loss的layer 只要有loss 无论是loss还是geo_loss 将这个layer统统删除,这就是此次的deploy.prototxt。
大功告成,至此整个流程全部完成。整个过程心酸不断,fcn的资料不多,求助了很多人,在此感谢
无奈的小心酸,深度学习思考者
对我的帮助。
参考博客:
http://blog.csdn.net/wangkun1340378/article/details/70238290
http://blog.csdn.net/u010402786/article/details/72883421
http://blog.csdn.net/supe_king/article/details/55657136
FCN制作自己的数据集、训练和测试全流程
花了两三周的时间,在导师的催促下,把FCN的全部流程走了一遍,期间走了很多弯路,现在记录一下。系统环境:ubuntu 16.04LTS一、数据集的制作
注:我的数据集是仿照VOC数据集进行制作的
1.resize 数据集
我的GPU显存4G,跑过大的图片带不动,需要resize图片大小,放几个修改图片大小的程序。
(1)单张图片resize
# coding = utf-8 import Image def convert(width,height): im = Image.open("C:\\xxx\\test.jpg") out = im.resize((width, height),Image.ANTIALIAS) out.save("C:\\xxx\\test.jpg") if __name__ == '__main__': convert(256,256)1
2
3
4
5
6
7
8
9
(2)resize整个文件夹里的图片
# coding = utf-8 import Image import os def convert(dir,width,height): file_list = os.listdir(dir) print(file_list) for filename in file_list: path = '' path = dir+filename im = Image.open(path) out = im.resize((256,256),Image.ANTIALIAS) print "%s has been resized!"%filename out.save(path) if __name__ == '__main__': dir = raw_input('please input the operate dir:') convert(dir,256,256)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(3)按比例resize
# coding = utf-8 import Image import os def convert(dir,width,height): file_list = os.listdir(dir) print(file_list) for filename in file_list: path = '' path = dir+filename im = Image.open(path) out = im.resize((256,256),Image.ANTIALIAS) print "%s has been resized!"%filename out.save(path) if __name__ == '__main__': dir = raw_input('please input the operate dir:') convert(dir,256,256)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2.制作索引图
(1)下载labelme
下载地址:https://github.com/wkentaro/labelme
下载后按提示打开软件,进行标注,保存会生成后缀为json的文件。
(2)生成dataset文件夹
在终端输入指令:
labelme_json_to_dataset _static/apc2016_obj3.json //这里的文件名根据自己的实际情况更改1
(3)为文件夹下的label.png着色
首先需要对照VOC分割的颜色进行着色,一定要保证颜色的准确性。Matlab代码:
function cmap = labelcolormap(N) if nargin==0 N=256 end cmap = zeros(N,3); for i=1:N id = i-1; r=0;g=0;b=0; for j=0:7 r = bitor(r, bitshift(bitget(id,1),7 - j)); g = bitor(g, bitshift(bitget(id,2),7 - j)); b = bitor(b, bitshift(bitget(id,3),7 - j)); id = bitshift(id,-3); end cmap(i,1)=r; cmap(i,2)=g; cmap(i,3)=b; end cmap = cmap / 255;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
对应的VOC数据集中的颜色类别:
类别名称 R G B background 0 0 0 背景 aeroplane 128 0 0 飞机 bicycle 0 128 0 bird 128 128 0 boat 0 0 128 bottle 128 0 128 瓶子 bus 0 128 128 大巴 car 128 128 128 cat 64 0 0 猫 chair 192 0 0 cow 64 128 0 diningtable 192 128 0 餐桌 dog 64 0 128 horse 192 0 128 motorbike 64 128 128 person 192 128 128 pottedplant 0 64 0 盆栽 sheep 128 64 0 sofa 0 192 0 train 128 192 0 tvmonitor 0 64 128 显示器1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
然后使用Python的skimage库进行颜色填充,具体函数是skimage.color.label2rgb(),代码较长,有需要可私信。
————————-2017年9月26日 新增————————-
太多人和我私信要代码,前一段时间很忙都没有及时回复大家,所以这里放个链接,需要自取。
https://github.com/hitzoro/FCN-ColorLabel
3.将填充后的label.png转为灰度图
如果不转,在训练的时候回报错,转换matlab代码如下:
dirs=dir('F:/xxx/*.png'); for n=1:numel(dirs) strname=strcat('F:/xxx/',dirs(n).name); img=imread(strname); [x,map]=rgb2ind(img,256); newname=strcat('F:/xxx/',dirs(n).name); imwrite(x,map,newname,'png'); end1
2
3
4
5
6
7
8
转化后,在python中检查一下图片的格式:
In [23]: img = PIL.Image.open('000001_json/label.png') In [24]: np.unique(img) Out[24]: array([0, 1, 2], dtype=uint8)1
2
3
如果输出一致,则索引图制作正确。
二、FCN训练自己的数据集
1.前期准备
默认已经安装好显卡驱动,cuda,cudnn,opencv。
最新版caffe下载: https://github.com/BVLC/caffe
fcn源代码下载:https://github.com/shelhamer/fcn.berkeleyvision.org
caffe的配置安装可以参考我的另一篇博客:http://blog.csdn.net/zoro_lov3/article/details/60581174
2.数据集准备
这里我们需要两个数据集包,benchmark和VOC2012,进入fcn/data,新建sbdd文件夹(如果没有),将benchmark解压到sbdd中,将VOC2012解压到data下的pascal文件夹下。
这两个在网上都可以找得到。
这两个数据集有什么用呢?在FCN中VOC数据集的训练需要他俩,benchmark中的dataset用来存放训练时的数据,VOC2012存放测试时的数据。
先制作训练时的数据
进入dataset中的img文件夹,这里存放训练用的原图,把原来的原图替换为你自己的原图。接着修改train.txt ,写入你训练图片的名字,注意不要加后缀。如下即可:
000001 000003 000005 000007 000009 000011 000013 000015 000017 0000191
2
3
4
5
6
7
8
9
10
进入cls文件夹,这里原本需要存放mat格式的文件,但是制作mat文件有点麻烦,参考了网上的资料,修改代码,使得这里也可以直接存放索引图。
方式如下:
修改fcn目录下的voc_layers.py
注释掉原本的load_label ,修改为新的
# def load_label(self, idx): # """ # Load label image as 1 x height x width integer array of label indices. # The leading singleton dimension is required by the loss. # """ # import scipy.io # mat = scipy.io.loadmat('{}/cls/{}.mat'.format(self.sbdd_dir, idx)) # label = mat['GTcls'][0]['Segmentation'][0].astype(np.uint8) # label = label[np.newaxis, ...] # return label def load_label(self, idx): """ Load label image as 1 x height x width integer array of label indices. The leading singleton dimension is required by the loss. """ im = Image.open('{}/cls/{}.png'.format(self.sbdd_dir, idx)) label = np.array(im, dtype=np.uint8) label = label[np.newaxis, ...] return label1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
制作测试集数据
测试集的制作简单一写,进入VOC2012,进入JPEGImages文件夹,里面存放测试用的原图,然后进入SegmentationClass,里面存放测试用的索引图,最后进入ImageSets/Segmentation,有一个名为seg11valid.txt的文件,它和train.txt的性质一样,存放测试用的图片名。
到此,数据集就准备完成了。
3.修改网络参数
下载VGG16的预训练模型并放在FCN源码文件夹中的ilsvrc-nets文件夹下
https://pan.baidu.com/s/1qYJeFfQ
为了避免运行程序时候出现no module named caffe
在代码中包含import caffe的py文件(solve.py)的第一行加入
import sys sys.path.append('/home/hitoia/caffe/python')1
2
其中,/home/hitoia/caffe/python为你下载的caffe源码中python文件夹的路径
cd进入fcn源码路径
以个人路径为例:/home/hitoia/fcn.berkeleyvision.org/
将其中所有的py文件,例如surgery.py等等,全部复制到voc-fcn32s文件夹中
solver.prototxt文件修改
进入voc-fcn32s文件夹 打开solver.prototxt
其中snapshot:10000 表示训练10000次保存一次模型
snapshot_prefix:”/home/hitoia/fcn.berkeleyvision.org/voc-fcn32s/snapshot/train”
表示训练得到的模型,也就是model存放的路径
在此,我附上个人的solver.prototxt供大家参考
train_net: "/home/hitoia/fcn.berkeleyvision.org/voc-fcn32s/train.prototxt" test_net: "/home/hitoia/fcn.berkeleyvision.org/voc-fcn32s/val.prototxt" test_iter: 736 # make test net, but don't invoke it from the solver itself test_interval: 999999999 display: 20 average_loss: 20 lr_policy: "fixed" # lr for unnormalized softmax base_lr: 1e-10 # high momentum momentum: 0.99 # no gradient accumulation iter_size: 1 max_iter: 100000 weight_decay: 0.0005 snapshot: 4000 snapshot_prefix: "/home/hitoia/fcn.berkeleyvision.org/voc-fcn32s/snapshot/train" test_initialization: false1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
solve.py的修改
在这里郑重声明一下:如果训练fcn32s的网络模型,一定要修改solve.py利用transplant的方式获取vgg16的网络权重。
具体操作为:
import sys sys.path.append('/home/hitoia/caffe/python')1
import caffe
import surgery, score
import numpy as np
import os
import sys
try:
import setproctitle
setproctitle.setproctitle(os.path.basename(os.getcwd()))
except:
pass
vgg_weights = '../ilsvrc-nets/vgg16-fcn.caffemodel'
vgg_proto = '../ilsvrc-nets/VGG_ILSVRC_16_layers_deploy.prototxt'
weights = '../ilsvrc-nets/vgg16-fcn.caffemodel'
#weights = '../ilsvrc-nets/vgg16-fcn.caffemodel'
# init
#caffe.set_device(int(sys.argv[1]))
caffe.set_mode_gpu()
caffe.set_device(0)
#solver = caffe.SGDSolver('solver.prototxt')
#solver.net.copy_from(weights)
solver = caffe.SGDSolver('solver.prototxt')
vgg_net=caffe.Net(vgg_proto,vgg_weights,caffe.TRAIN)
surgery.transplant(solver.net,vgg_net)
del vgg_net
# surgeries
interp_layers = [k for k in solver.net.params.keys() if 'up' in k]
surgery.interp(solver.net, interp_layers)
# scoring
val = np.loadtxt('/home/hitoia/fcn.berkeleyvision.org/data/pascal/VOCdevkit/VOC2012/ImageSets/Segmentation/seg11valid.txt', dtype=str)
for _ in range(25):
solver.step(1000)
score.seg_tests(solver, False, val, layer='score')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
关于VGG_ILSVRC_16_layers_deploy.prototxt 可以在http://pan.baidu.com/s/1geLL6Sz下载。
如果训练fcn16s,则可以直接copy自己的fcn32s的model的权重,不需要transplant,也就是不需要修改solve.py
如果训练fcn8s,则可以直接copy自己的fcn16s的model的权重,不需要transplant,也就是不需要修改solve.py
只有如此,才能避免loss高居不下的情况
这里的:
for _ in range(25): solver.step(1000) score.seg_tests(solver, False, val, layer='score')1
2
3
奇怪的现象:修改solver.prototxt中的max_iter: 100000没有改变最大迭代次数,只有改变这个step里的数字才有用,这里最大迭代次数等于25*1000 = 25000次。
train.prototxt / val.prototxt 修改
所有num_output 为21 的地方都修改为自己分类数 + 1 (加的1是背景),最开始的param_str需要根据自己的情况修改,放一下我自己的
train.prototxt:
param_str: "{\'sbdd_dir\': \'/home/hitoia/fcn.berkeleyvision.org/data/sbdd/benchmark/benchmark_RELEASE/dataset\', \'seed\': 1337, \'split\': \'train\', \'mean\': (104.00699, 116.66877, 122.67892)}"1
val.prototxt:
param_str: "{\'voc_dir\': \'/home/hitoia/fcn.berkeleyvision.org/data/pascal/VOCdevkit/VOC2012\', \'seed\': 1337, \'split\': \'seg11valid\', \'mean\': (104.00699, 116.66877, 122.67892)}"1
准备完成,在voc-fcn32s路径下输入
python solve.py1
就可以开始训练
三、单张测试
在fcn源码文件夹,找到infer.py。
import numpy as np1
from PIL import Image
import matplotlib.pyplot as plt
import sys sys.path.append('/home/hitoia/caffe/python')
import caffe
# load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe
im = Image.open('000030.jpg')
in_ = np.array(im, dtype=np.float32)
in_ = in_[:,:,::-1]
in_ -= np.array((104.00698793,116.66876762,122.67891434))
in_ = in_.transpose((2,0,1))
# load net
#net = caffe.Net('voc-fcn8s/deploy.prototxt', 'voc-fcn8s/fcn8s-heavy-pascal.caffemodel', caffe.TEST)
net = caffe.Net('voc-fcn32s/deploy.prototxt', 'voc-fcn32s/snapshot/train_iter_24000.caffemodel', caffe.TEST)
#net = caffe.Net('voc-fcn8s/deploy.prototxt', 'siftflow-fcn32s/train_iter_100000.caffemodel', caffe.TEST)
# shape for input (data blob is N x C x H x W), set data
net.blobs['data'].reshape(1, *in_.shape)
net.blobs['data'].data[...] = in_
# run net and take argmax for prediction
net.forward()
out = net.blobs['score'].data[0].argmax(axis=0)
#plt.imshow(out,cmap='gray');
plt.imshow(out);
plt.axis('off')
plt.savefig('000030_out32.png')
#plt.show()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
其中,net = caffe.Net(‘voc-fcn32s/deploy.prototxt’, ‘voc-fcn32s/snapshot/train_iter_24000.caffemodel’, caffe.TEST),其中train_iter_24000.caffemodel’是我训练后得到的模型。
如果没有deploy文件,可以参考如下方法:
首先,根据你利用的模型,例如模型是voc-fcn32s的,那么你就去voc-fcn32s的文件夹,里面有train.prototxt文件,将文件打开,全选,复制,新建一个名为deploy.prototxt文件,粘贴进去,
然后ctrl+F 寻找所有名为loss的layer 只要有loss 无论是loss还是geo_loss 将这个layer统统删除,这就是此次的deploy.prototxt。
大功告成,至此整个流程全部完成。整个过程心酸不断,fcn的资料不多,求助了很多人,在此感谢
无奈的小心酸,深度学习思考者
对我的帮助。
参考博客:
http://blog.csdn.net/wangkun1340378/article/details/70238290
http://blog.csdn.net/u010402786/article/details/72883421
http://blog.csdn.net/supe_king/article/details/55657136
相关文章推荐
- FCN制作自己的数据集、训练和测试全流程
- FCN制作自己的数据集、训练和测试全流程
- FCN制作自己的数据集、训练和测试全流程
- caffe示例实现之5用CaffeNet训练与测试自己的数据集
- FCN训练自己的数据集及测试
- 在纯净的linux中配置安装caffe直到可以训练和测试自己的数据集(1/2)
- caffe 训练测试自己的数据集
- windows10+GPU下caffe数据集Lmdb格式制作+训练自己数据集
- 4000 windows-caffe 训练和测试自己的数据集
- Caffe训练和测试自己的数据集
- FCN训练自己的数据集及测试
- 仿照VOC2007制作自己的数据集,并在Caffe上训练Faster-RCNN
- Caffe学习笔记3——制作并训练自己的数据集
- windows 下的caffe- 生成自己的数据集,并训练测试
- caffe训练测试自己的数据集
- mnist数据集在caffe(windows)上的训练与测试及对自己手写数字的分类
- caffe示例实现之5用CaffeNet训练与测试自己的数据集
- Caffe 用自己的数据集在ImageNet网络结构上训练测试
- FCN训练自己的数据集及测试
- Caffe中文件参数设置(九-2):训练和测试自己的数据集-windows10版本