原文:http://blog.csdn.net/zoro_lov3/article/details/74550735

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 osdef convert(dir,width,height):file_list = os.listdir(dir)print(file_list)for filename in file_list:path = ''path = dir+filenameim = Image.open(path)out = im.resize((256,256),Image.ANTIALIAS)print "%s has been resized!"%filenameout.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 osdef convert(dir,width,height):file_list = os.listdir(dir)print(file_list)for filename in file_list:path = ''path = dir+filenameim = Image.open(path)out = im.resize((256,256),Image.ANTIALIAS)print "%s has been resized!"%filenameout.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==0N=256
end
cmap = zeros(N,3);
for i=1:Nid = i-1; r=0;g=0;b=0;for j=0:7r = 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);endcmap(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');
end
  • 1
  • 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
000019
  • 1
  • 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 labeldef 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 label
  • 1
  • 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: false
  • 1
  • 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')
import caffe
import surgery, scoreimport numpy as np
import os
import systry:import setproctitlesetproctitle.setproctitle(os.path.basename(os.getcwd()))
except:passvgg_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')
  • 1
  • 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.py
  • 1

就可以开始训练

三、单张测试 
在fcn源码文件夹,找到infer.py。

import numpy as np
from PIL import Image
import matplotlib.pyplot as pltimport 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()
  • 1
  • 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制作自己的数据集、训练和测试 caffe相关推荐

  1. pytorch用FCN语义分割手提包数据集(训练+预测单张输入图片代码)

    一,手提包数据集 数据集下载:用pytorch写FCN进行手提包的语义分割. training data(https://github.com/yunlongdong/FCN-pytorch-easi ...

  2. caffe学习(五):cifar-10数据集训练及测试(Ubuntu)

    简介 网站链接:CIFAR-10 CIFAR-10数据集包括由10个类别的事物,每个事物各有6000张彩色图像,每张图片的大小是32*32. 整个数据集被分成了5个训练集和1个测试集,各有10000张 ...

  3. yolo-v2 自己的数据集训练以及测试流程(仅供内部使用!)

    warning 该流程仅供内部使用,外部人士使用可能会报很多很多错误! 步骤 先清除backup文件夹中老的权重文件: 将标定好图片以及annotation .txt文件拷贝到obj文件夹,一一对应, ...

  4. 深度学习入门 FashionMNIST数据集训练和测试(30层神经网路)

    使用pytorch框架.模型包含13层卷积层.2层池化层.15层全连接层.为什么叠这么多层?就是玩. FashionMNIST数据集包含训练集6w张图片,测试集1w张图片,每张图片是单通道.大小28× ...

  5. CIFAR10数据集训练及测试

    一.数据集介绍 该数据集共有60000张彩色图像,这些图像是32*32,分为10个类,每类6000张图.这里面有50000张用于训练,构成了5个训练批,每一批10000张图:另外10000用于测试,单 ...

  6. 批量下载百度搜索图片+labelimg制作自己的数据集+转换至Yolo-v5训练数据集

    由于课题需要,需要自己制作数据集进行训练,目前是自己制作的第二个数据集,发现有某些细节已经忘记,记录备忘,同时为后来者提供借鉴.文章以car-tank数据集做为例子介绍 整体流程: 1.准备数据:从各 ...

  7. 【数据挖掘】分类任务简介 ( 分类概念 | 分类和预测 | 分类过程 | 训练集 | 测试集 | 数据预处理 | 有监督学习 )

    文章目录 I . 分类概念 II . 分类 ( 离散值 ) 和 预测 ( 连续值 ) III . 分类过程 IV . 分类过程中使用的数据集 ( 训练集 | 测试集 | 新数据 ) V . 数据预处理 ...

  8. python制作训练集_利用Tensorflow简单实现VGGNet,从数据集制作到训练完成测试

    VGGNet_TF 利用Tensorflow简单实现VGGNet,从数据集制作到训练完成测试 参考:<Tensorflow实战><Tensorflow 实战Google深度学习框架& ...

  9. 自定义ava数据集及训练与测试 完整版 时空动作/行为 视频数据集制作 yolov5, deep sort, VIA MMAction, SlowFast

    前言 这一篇博客应该是我花时间最多的一次了,从2022年1月底至2022年4月底. 我已经将这篇博客的内容写为论文,上传至arxiv:https://arxiv.org/pdf/2204.10160. ...

最新文章

  1. Oracle Client安装
  2. lisp压盖处理_一种压盖的制造方法
  3. Android10.0 Binder通信原理(二)-Binder入门篇
  4. Java9新功能之HTTP2和REPL
  5. android 处理鼠标滚轮事件 【转】
  6. 面试官:什么是JDK什么是JRE?服务器可以只安装JRE吗?
  7. mysql中in和between_MySQL的WHERE语句中BETWEEN与IN的用法和他们的区别
  8. Codeforces 839B - Game of the Rows
  9. moore 数据集_可计算存储:数据压缩和数据库计算下推
  10. WPF之DatePicker使其只能选择日期,不能输入日期
  11. cannon linux驱动下载
  12. c语言编程基础实验结果与分析,C语言实验指导1--C语言编程基础.doc
  13. FreeSWITCH折腾笔记9——使用FS做一个i-SBC
  14. 别说理科男不懂撩妹,这个老司机一生只爱两样:物理和18岁的少女
  15. 小程序码 踩坑记录(buffer转成图片显示问题)
  16. python二分查找时间复杂度_时间复杂度 二分查找
  17. 随机波动率微笑模型及套利
  18. JavaScript 小数转分数
  19. 用Facebook做广告和营销,你需要注意哪些问题?
  20. PHP中strtotime函数的坑

热门文章

  1. mysql中所有时间类型_MySQL 中的日期时间类型
  2. mockito_Mockito – JAXB的RETURNS_DEEP_STUBS
  3. 如何生成表_SPSS简单操作 | 如何生成交叉表?
  4. admm算法_「优化」交替方向乘子法(ADMM)的基本原理
  5. ssh mysql 警告_ssh 对数据表查询出错。警告: SQL Error: 1064, SQLState: 42000
  6. Linux空间过满无法登录,linux下磁盘空间不足导致oracle无法登录的解决方案
  7. 尽快卸载这两款恶意浏览器插件!已有近50万用户安装
  8. MySQL 中的反斜杠 \\,真是太坑了!!
  9. 字节又莫名其妙发奖金了!网友:突然到账五万,吓得我差点报警...
  10. 程序员都讨厌写文档?这4个工具让你事半功倍