Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)
Windows10制作LMDB详细教程
原创不易,转载请注明出处:https://www.cnblogs.com/xiaoboge/p/10678658.html
摘要:
当我们在使用Caffe做深度学习项目时,经常需要制作Caffe常用的数据类型lmdb、leveldb以及hdf5等(尽管可以使用原始图片,效率低),而不是我们常见的JPG、PNG、TIF。因此,我们需要对我们采集的数据进行格式转换,即通过输入我们自己的图片目录(包含有训练集和验证集的大量图片)转换成一个lmdb库文件的输出;这个过程一般是有Caffe工具中的convert_imageset.exe,该工具在编译过的Caffe中,具体位置是:D:\你的根目录\caffe\caffe-windows\Build\x64\Release\convert_imageset.exe。
开始正文:
格式转换的4个必要条件:
(1)编译好Caffe,而且convert_imageset.exe存在;
(2)需要被转换的图像和目录,注意它们是有要求的(请看稍后的文件目录架构);
(3)在将图像转换为lmdb格式之前,首先生成两个标签文件train.txt和val.txt(具体格式见下文);
(4)运行编辑修改好的create_imagenet.sh(最好将其制到你的项目文件夹下,不修改原始文件)生成lmdb文件。
所在位置:D:\你的caffe根目录\caffe\caffe-windows\examples\imagenet
1. 数据集的组织架构(文件目录结构)
接下来,我将会使用一个例子详细介绍即将要使用的数据集的目录结构。这里制作的是一个分类数据集,主要包括两个类别:dog和cat,我们用数字0表示dog的类别,数字1来表示cat类别。在总目录data_set文件夹下,包括两个子文件夹分别是train和val,它们分别存储着训练集和验证集的所有图片。在train文件夹下 也包含两个子文件夹,它们分别是“0”和“1”,里面分别存储的是dog和cat的所有图像。在val的文件夹下没有子文件夹(其实也可以像train一样),直接是将要用于验证的图像数据,我们可以根据图像的名字知道它所属的类别,便于写出val.txt文件。鉴于这一步是格式转换的基础,我将整个目录详细结构用图展示如下:
(1)数据集根目录所在路径:C:\Users\Administrator\Desktop
(2)data_set的子文件夹:C:\Users\Administrator\Desktop\data_set
(3)train的子文件夹:C:\Users\Administrator\Desktop\data_set\train
(a)“0”文件夹下的文件:C:\Users\Administrator\Desktop\data_set\train\0
这里图片文件的名字其实可以随意,因为文件夹就指出了它所属的类别。
(b)“1”文件夹下的文件:C:\Users\Administrator\Desktop\data_set\train\1
这里图片文件的名字其实可以随意,因为文件夹就指出了它所属的类别。
(4)val的子文件夹:C:\Users\Administrator\Desktop\data_set\val
这里的图像文件的名字必须可以判断它所属的类别,我们使用python中的split()函数可以将文件名以“_”分隔开来获取图像所属类别,具体见程序。
至此,我已经详细介绍了整个数据集的详细目录结构,我相信这已经足够详细啦!接下来,我们开始更至关重要的一步操作。
2. 如何制作train.txt和val.txt
如果想要将图像数据转换为LMDB数据格式,不仅要使用上述的数据集文件目录,还需要这些图片存放的路径以及该图片的标签(属于哪个类);一般情况下,标签文件有两个,一个是描述训练集合的train.txt,另一个是描述验证集的val.txt,这两个文件的格式稍微有点差别,具体格式如下:
(1)train.txt的文件格式
注意:该文件中分别存储了图像的路径和所属的类别,“0”表示dog,“1”表示cat。这里也没有打乱图像的顺序,可以在制作LMDB的时候打乱。
(2)val.txt的文件格式
注意:这里的验证集的标签文件无需分类存储(像train一样分成两个文件夹),但是我们必须可以判断每张图片的所属类别。
到目前为止,我们已经知道了所要制作的train.txt和val.txt的格式要求了;接下来就是怎样从我们的数据集出发,制作属于自己数据集的train.txt和val.txt,这个制作的过程并不是固定的,每个人可以根据自己的习惯使用熟悉的语言(例如,python、c++)去完成这一步骤。还有根据项目的实际不同需求,可能要写的程序也是不完全一样的,但是我想这一编程实现输出train.txt和val.txt对于一个程序员来说是非常基础操作。我在这里针对这个例子写一段python代码来实现这个操作,虽然写的不是很好,但是能够实现我们的需求,我也对它进行了详细的注释。代码展示如下(python语言所示),程序的名称是:generate_txt.py
# -*- coding: utf-8 -*-
# @Time : 2018/12/9 0009 12:04
# @Author : sunjianbo
# @Email : 1871593109@qq.com
# @Software: PyCharm
import os
#数据集根目录所在路径
root_data_path = r"C:\Users\Administrator\Desktop\data_set"
#输出的TXT文件路径
traintxt_path = root_data_path + "\\" + "train.txt"
valtxt_path = root_data_path + "\\" + "val.txt" #如果存在之前生成的TXT文件,先把它们删除
if os.path.exists(traintxt_path):
os.remove(traintxt_path)
if os.path.exists(valtxt_path):
os.remove(valtxt_path)
#返回数据集文件夹下的子文件夹
filenames = os.listdir(root_data_path) #["train", "val"] #打开要存储的TXT文件
file_train = open(traintxt_path, "w")
file_val = open(valtxt_path, "w") if len(filenames) > 0:
for fn in filenames:
#数据集根目录下的子文件夹路径,train和val的绝对路径
full_filename = os.path.join(root_data_path, fn) # 判断是训练集文件夹,还是验证集文件夹
if fn == "train":
#找出训练集文件夹下的子文件夹名字,是每个类别的文件夹,0表示狗,1表示猫
file = os.listdir(full_filename) #["0", "1"]
for name in file:
#获得train文件夹下的子文件夹“0”和“1”的绝对路径
temp = os.path.join(full_filename, name)
for img in os.listdir(temp): #分别遍历两个文件夹["0", "1"]下的所有图像
#将图像的信息写入到train.txt文件
file_train.write(name + "/" + img + " " + name + "\n")
elif fn == "val": #当进入到val文件夹后
for img in os.listdir(full_filename): #遍历所有的图像
category = img.split('_') #对图像的名字进行分割,返回的是一个列表
if category[0] == "dog": #当分割的结果可以判断是dog时,类别是“0”
file_val.write(img + " " + "" + "\n")
elif category[0] == "cat": #当分割的结果可以判断是cat时,类别是“1”
file_val.write(img + " " + "" + "\n")
else:
print("验证集中图片名字有误")
else:
print("存在错误文件夹")
else:
print("该文件夹下不存在子文件夹") file_train.close()
file_val.close()
运行上面的程序:generate_txt.py,可以在数据集所在目录(data_set文件夹下面)生成两个train.txt和val.txt文件。生成之后的目录结构如下:
其中,两条黄色线连接的部分就是运行上面的generate_txt.py生成的。
现在,我们已经完成了转换LMDB数据格式最重要的一步了。接下来的步骤将很简单,我们继续往下走。
3. 开始制作LMDB格式的数据
在完成以上的工作的基础上,我们通过上面的4个文件(两个train和val的图像库,两个train.txt和val.txt标签列表),把图像的数据和其对应的标签打包起来,生成我们需要的LMDB格式的数据。
首先,我们需要找到制作LMDB格式的create_imagenet.sh,它的原始地址在D:\program_files\caffe\caffe-windows\examples\imagenet,找到该文件之后将其复制到自己的项目文件夹(可以修改名称),我这里把它放在了data_set的文件夹下,然后进行相应的路径设置就可以运行create_imagenet.sh(或者是修改后的名称)。下面展示了原始的create_imagenet.sh文件,但是我对参数进行了注释和说明,并且添加了关于判断是否已经生成过LMDB文件的一步,如果存在删除它生成最新的。
(1)原始的create_imagenet.sh文件
#!/usr/bin/env sh
# Create the imagenet lmdb inputs #创建LMDB格式的文件输入
# N.B. set the path to the imagenet train + val data dirs #为train和val数据目录设置路径 EXAMPLE=examples/imagenet #生成模型训练数据的文件夹,即create_imagenet.sh(这里名字可以修改)所在文件夹,也就是最终的LMDB数据存储的位置。
DATA=data/ilsvrc12 #python脚本处理完的数据存储路径,也就是train.txt和val.txt的存储路径
TOOLS=build/tools #caffe的工具库,需要找到自己编译过的convert_imageset.exe,具体位置在D:/program_files/caffe/caffe-windows/Build/x64/Release
TRAIN_DATA_ROOT=/path/to/imagenet/train/ #待处理的图像训练数据的路径
VAL_DATA_ROOT=/path/to/imagenet/val/ #待处理的图像验证数据的路径 # Set RESIZE=true to resize the images to 256x256. Leave as false if images have
# already been resized using another tool.
RESIZE=false #是否对图片进行resize操作,如果是设置为True
if $RESIZE; then
RESIZE_HEIGHT= #resize的尺寸是256*
RESIZE_WIDTH=
else
RESIZE_HEIGHT=
RESIZE_WIDTH=
fi if [ ! -d "$TRAIN_DATA_ROOT" ]; then
echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
"where the ImageNet training data is stored."
exit
fi if [ ! -d "$VAL_DATA_ROOT" ]; then
echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
"where the ImageNet validation data is stored."
exit
fi echo "if train.txt and val.txt are exist in EXAMPLE dir. clear all"
#删除已存在的lmdb格式文件,若在已存在lmdb格式的文件夹下再添加lmdb文件,会出现错误
rm -rf $EXAMPLE/train_lmdb
rm -rf $EXAMPLE/val_lmdb echo "Creating train lmdb..." GLOG_logtostderr= $TOOLS/convert_imageset \ #调用convert_imageset进行格式转换
--resize_height=$RESIZE_HEIGHT \ #将图片调整到固定尺寸
--resize_width=$RESIZE_WIDTH \
--shuffle \ #打乱图像的顺序
$TRAIN_DATA_ROOT \
$DATA/train.txt \ #这里的DATA是存放train.txt的路径
$EXAMPLE/ilsvrc12_train_lmdb #这里修改输出的训练集的LMDB的名称 echo "Creating val lmdb..." GLOG_logtostderr= $TOOLS/convert_imageset \ #调用convert_imageset进行格式转换
--resize_height=$RESIZE_HEIGHT \ #将图片调整到固定尺寸
--resize_width=$RESIZE_WIDTH \
--shuffle \ #打乱图像的顺序
$VAL_DATA_ROOT \
$DATA/val.txt \ #这里的DATA是存放val.txt的路径
$EXAMPLE/ilsvrc12_val_lmdb #这里修改输出的验证集的LMDB的名称 echo "Done."
(2)基于本例子的修改后的create_imagenet.sh文件如下,名称改为:convert_my_LMDB.sh
#!/usr/bin/env sh
# Create the imagenet lmdb inputs #创建LMDB格式的文件输入
# N.B. set the path to the imagenet train + val data dirs #为train和val数据目录设置路径 EXAMPLE=C:/Users/Administrator/Desktop/data_set #生成模型训练数据的文件夹,即create_imagenet.sh(这里名字可以修改)所在文件夹。
DATA=C:/Users/Administrator/Desktop/data_set #python脚本处理完的数据存储路径,也就是train.txt和val.txt的存储路径
TOOLS=D:/program_files/caffe/caffe-windows/Build/x64/Release #caffe的工具库,找到自己的编译过的convert_imageset.exe所在的位置
TRAIN_DATA_ROOT=C:/Users/Administrator/Desktop/data_set/train/ #待处理的训练数据的路径
VAL_DATA_ROOT=C:/Users/Administrator/Desktop/data_set/val/ #待处理的验证数据的路径 # Set RESIZE=true to resize the images to 256x256. Leave as false if images have
# already been resized using another tool.
RESIZE=true #是否对图片进行resize操作,如果是设置为True
if $RESIZE; then
RESIZE_HEIGHT= #resize的尺寸是256*
RESIZE_WIDTH=
else
RESIZE_HEIGHT=
RESIZE_WIDTH=
fi if [ ! -d "$TRAIN_DATA_ROOT" ]; then
echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
"where the ImageNet training data is stored."
exit
fi if [ ! -d "$VAL_DATA_ROOT" ]; then
echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
"where the ImageNet validation data is stored."
exit
fi echo "if train.txt and val.txt are exist in EXAMPLE dir. clear all"
#删除已存在的lmdb格式文件,若在已存在lmdb格式的文件夹下再添加lmdb文件,会出现错误
rm -rf $EXAMPLE/train_lmdb
rm -rf $EXAMPLE/val_lmdb
echo "Creating train lmdb..." GLOG_logtostderr= $TOOLS/convert_imageset \ #调用convert_imageset进行格式转换
--resize_height=$RESIZE_HEIGHT \ #将图片调整到固定尺寸
--resize_width=$RESIZE_WIDTH \
--shuffle \ #打乱图像的顺序
$TRAIN_DATA_ROOT \
$DATA/train.txt \ #这里的DATA是存放train.txt的路径
$EXAMPLE/train_lmdb #这里修改输出的训练集的LMDB的名称 echo "Creating val lmdb..." GLOG_logtostderr= $TOOLS/convert_imageset \ #调用convert_imageset进行格式转换
--resize_height=$RESIZE_HEIGHT \ #将图片调整到固定尺寸
--resize_width=$RESIZE_WIDTH \
--shuffle \ #打乱图像的顺序
$VAL_DATA_ROOT \
$DATA/val.txt \ #这里的DATA是存放val.txt的路径
$EXAMPLE/val_lmdb #这里修改输出的验证集的LMDB的名称 echo "Done."
read #最后加一行read,可以让窗口暂停等待,相当于pause。
这里修改的位置有:第5行、第6行、第9行、第10行、第14行、第52行、第62行。最终,在data_set文件夹下面生成了两个文件夹train_lmdb和val_lmdb,它们分别存储了训练集和测试集的转换数据和标签。在windows系统上不可以直接运行sh文件,因此我们需要去安装一下Git,并将安装好的Git的bin文件路径加入到环境变量,就可以双击执行sh文件啦。当sh文件运行完成之后(这里的运行其实是调用了D:\program_files\caffe\caffe-windows\Build\x64\Release\convert_imageset.exe格式转换可执行程序),文件的目录结构图如下所示:
至此,我们的LMDB的数据格式就真正做完了,是不是并不是很难!
4. 另一种制作LMDB数据格式的方法(windows下不需要安装Git)
首先,我们看一下转换数据之前的文件目录结构(和之前一样):
在以上四个文件的基础上进行转换,首先在data_set文件夹下创建一个convert_my_lmdb.txt文件,在该文件中写入一段批处理文件(详细内容如下),然后将文件格式修改为批处理文件即convert_my_lmdb.bat,他可以在windows环境下双击直接运行。
D:\program_files\caffe\caffe-windows\Build\x64\Release\convert_imageset.exe --gray --resize_width=144 --resize_height=144 ./train/ train.txt train_lmdb -backend=lmdb
D:\program_files\caffe\caffe-windows\Build\x64\Release\convert_imageset.exe --gray --resize_width=144 --resize_height=144 ./val/ val.txt val_lmdb -backend=lmdb
pause
其中,D:\program_files\caffe\caffe-windows\Build\x64\Release\convert_imageset.exe,表示编译好之后的转换程序,及其所在的位置;
--gray,表示灰度化处理;
--resize_width=144 ,--resize_height=144,表示图像的resize处理;
./train/ train.txt,表示使用相对路径来获得train.txt位置,还有val.txt位置;
train_lmd,bval_lmdb,分别表示生成的训练集和验证集的LMDB格式文件夹的名称;
-backend=lmdb,表示转换的格式是LMDB
运行上述编辑好的convert_my_lmdb.bat,可以在data_set文件夹下生成我们想要的LMDB格式数据,结果如下所示:
OK,基本上结束了!接下来我会写一下注意事项!
5. 注意事项
(1)注意windows系统中路径问题,复制的路径是“\”,在程序中需要的是“/”,注意对其修改,生成的train.txt和val.txt中的路径也是“/”。
(2)必须保证你的caffe编译成功
(3)修改convert_imageset.sh时,一定要注意路径问题,这里就是配置路径的很容易出错(具体请看上面的详细过程)。
(4)图像的名字中不要出现空格,否则会有问题(深刻的痛)。
(5)生成的train.txt文件中的图像路径问题:路径从train文件夹之后开始写,不包括train文件夹名称。
(6)如果之前生成过文件(不管是train.txt和val.txt,还是train_lmdb和val_lmdb),想重新生成,最好先删除之前的,有可能会有错误。
(7)请严格按照上述步骤一步一步进行,否则也可能会报错。
转载请注明:https://www.cnblogs.com/xiaoboge/p/10678658.html
Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)的更多相关文章
- 第一部分:使用iReport制作报表的详细过程(Windows环境下)
提示:在有些板块,文中的图片看不到,建议到我的blog浏览文章:http://blog.csdn.net/jemlee2002/文章将会涉及3个方面的内容: 第一部分:使用iReport制作报表的详细 ...
- PWA入门:手把手教你制作一个PWA应用
摘要: PWA图文教程 原文:PWA入门:手把手教你制作一个PWA应用 作者:MudOnTire Fundebug经授权转载,版权归原作者所有. 简介 Web前端的同学是否想过学习app开发,以弥补自 ...
- 手把手教你制作AppPreview视频并上传到appStore进行审核
手把手教你制作AppPreview视频并上传到appStore进行审核 注意,你需要使用iMovie才能够制作AppPreview视频文件,用QuickTime录制的无效! 最终效果 1. 新建一个事 ...
- Caffe系列3——制作Hdf5数据源详细教程(手把手教你制作Hdf5数据源)
制作Hdf5数据源详细教程
- 通过busybox制作根文件系统详细过程
我在之前的uboot通过NFS挂载ubuntu根文件系统中也有实现过根文件系统的制作,那只是在ubuntu官网已经做好的根文件基础上安装一些自己所需的软解而已.而使用busybox制作根文件系统可以自 ...
- Caffe使用:如何将一维数据或其他非图像数据转换成lmdb
caffe事儿真多,数据必须得lmdb或者leveldb什么的才行,如果数据是图片的话,那用caffe自带的convert_image.cpp就行,但如果不是图片,就得自己写程序了.我也不是计算机专业 ...
- 手把手教你制作微信小程序,开源、免费、快速搞定
最近做了个"罗孚传车"的小程序 一时兴起,做了一个小程序,将个人收集的同汽车相关的行业资讯和学习资料,分享到小程序中,既作为历史资料保存,又提供给更多的人学习和了解,还能装一下:) ...
- 首发 手把手教你制作 Windows8 应用程序内部的 hubtile (动态瓷砖控件) MetroStyle(转)
http://blog.csdn.net/wangrenzhu2011/article/details/8175492 (转) 在metro 风格中 动态磁贴是他的精髓 在wp7 的开发中 我们可以使 ...
- 【openstack N版】——手把手教你制作生产环境镜像
一.CentOS7镜像制作 1.1创建CentOS7虚拟机 1.1.1创建虚拟磁盘 #注:尽量将虚拟机创建在控制节点,以便于将镜像上传至glance [root@linux-node1 ~]# qem ...
随机推荐
- BZOJ 3669: [Noi2014]魔法森林(lct+最小生成树)
传送门 解题思路 \(lct\)维护最小生成树.我们首先按照\(a\)排序,然后每次加入一条边,在图中维护一棵最小生成树.用并查集判断一下\(1\)与\(n\)是否联通,如果联通的话就尝试更新答案. ...
- Java io简单总结
IO 字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的 字符流在操作时使用了缓冲区,通过缓冲区再操作文件 缓冲:一段特殊的内存.如果一个程序频繁地操作一个资源(如文件或数据库),则性能会 ...
- KdPrint/DbgPrint and UNICODE_STRING/ANSI_STRING
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING ...
- scrapy-redis分布式爬取tencent社招信息
scrapy-redis分布式爬取tencent社招信息 什么是scrapy-redis 目标任务 安装爬虫 创建爬虫 编写 items.py 编写 spiders/tencent.py 编写 pip ...
- scrt 关闭退格键声音
options-> session Options -> Terminal -> audio bell (删除勾选) 这样就可以在secureCRT 在出错时不‘滴滴’的响了.
- kafka 批量添加topic 副本数
shell 脚本: 1)列出只有一个副本的topic,保存到一个文件中: [root@hdp05 src]# cat fush.sh #!/bin/bash # topics=`/usr/hdp//k ...
- 可读性 vs 效率
哪个重要. 应用层代码来说,实际上说任意一个重要都不为过, 但是到了内核里面之后,哪个重要. 肯定是效率阿,内核跑得慢,上面还有得玩么.
- D3.js坐标轴的绘制方法、添加坐标轴的刻度和各比例尺的坐标轴(V3版本)
坐标轴(Axis) 坐标轴(Axis)在很多图表中都可见到,例如柱形图.折线图.散点图等.坐标轴由一组线段和文字组成,坐标轴上的点由一个坐标值确定.但是,如果使用SVG的直线和文字一笔一画的绘制坐 ...
- 4、Docker网络访问
现在我们已经可以熟练的使用docker命令操作镜像和容器,并学会了如何进入到容器中去,那么实际的工作中,我们通常是在Docker中部署服务,我们需要在外部通过IP和端口进行访问的,那么如何访问到Doc ...
- 解决Keep-Alive 和 Close 不能使用此属性设置
http://www.hejingzong.cn/blog/viewblog_86.aspx Keep-Alive 和 Close 不能使用此属性设置 public static void SetHe ...