Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

时间:2022-01-11 16:20:49

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文件。鉴于这一步是格式转换的基础,我将整个目录详细结构用图展示如下:

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

(1)数据集根目录所在路径:C:\Users\Administrator\Desktop

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

(2)data_set的子文件夹:C:\Users\Administrator\Desktop\data_set

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

(3)train的子文件夹:C:\Users\Administrator\Desktop\data_set\train

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

  (a)“0”文件夹下的文件:C:\Users\Administrator\Desktop\data_set\train\0

    这里图片文件的名字其实可以随意,因为文件夹就指出了它所属的类别。

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

  (b)“1”文件夹下的文件:C:\Users\Administrator\Desktop\data_set\train\1

    这里图片文件的名字其实可以随意,因为文件夹就指出了它所属的类别。

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

(4)val的子文件夹:C:\Users\Administrator\Desktop\data_set\val

    这里的图像文件的名字必须可以判断它所属的类别,我们使用python中的split()函数可以将文件名以“_”分隔开来获取图像所属类别,具体见程序。

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

  至此,我已经详细介绍了整个数据集的详细目录结构,我相信这已经足够详细啦!接下来,我们开始更至关重要的一步操作。

 2. 如何制作train.txt和val.txt

  如果想要将图像数据转换为LMDB数据格式,不仅要使用上述的数据集文件目录,还需要这些图片存放的路径以及该图片的标签(属于哪个类);一般情况下,标签文件有两个,一个是描述训练集合的train.txt,另一个是描述验证集的val.txt,这两个文件的格式稍微有点差别,具体格式如下:

  (1)train.txt的文件格式

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

  注意:该文件中分别存储了图像的路径和所属的类别,“0”表示dog,“1”表示cat。这里也没有打乱图像的顺序,可以在制作LMDB的时候打乱。

  (2)val.txt的文件格式

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

  注意:这里的验证集的标签文件无需分类存储(像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文件。生成之后的目录结构如下:

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

  其中,两条黄色线连接的部分就是运行上面的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格式转换可执行程序),文件的目录结构图如下所示:

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

  至此,我们的LMDB的数据格式就真正做完了,是不是并不是很难!

4. 另一种制作LMDB数据格式的方法(windows下不需要安装Git)

  首先,我们看一下转换数据之前的文件目录结构(和之前一样):

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作LMDB)

  在以上四个文件的基础上进行转换,首先在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格式数据,结果如下所示:

Caffe系列2——Windows10制作LMDB数据详细过程(手把手教你制作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