caffe lmdb数据集的制作

我也参考了别人的文章,其实也算不上原创,只是自我感觉能从头到尾的走一遍挺好的。

lmdb数据集的制作

以imagenet数据集为例,我们只制作label范围为[0-10)的数据集,这个只是为了演示如何制作数据集。

数据准备

  • 新建一个名为train的目录及子目录和一个val的目录及子目录

train文件存放训练数据,val文件存放验证数据。然后我们在train文件下面,把训练数据按分类放在一个子目录下面, 目录名分别为0,1,2, ... , 9, 一共有10个子目录,这些子目录分别存放label [0-10)的图像。

同样的我们在val文件下面也创建相应的子目录。

  • 获取train数据,并放入对应的子目录下:

从imagenet数据集中获取图像和对应的label,基于label,把图片放入对应的目录下;

代码实现如下:

#!/usr/bin/env python

 

import caffe

from caffe.proto import caffe_pb2

import lmdb

import cv2 

import numpy as np

 

lmdb_env = lmdb.open('/data_4/songqing/caffe_official/caffe/imagenet_dataset/ilsvrc12_train_lmdb', readonly=True)

lmdb_txn = lmdb_env.begin()

lmdb_cursor = lmdb_txn.cursor()

datum = caffe_pb2.Datum()

index = 0 

 

for key, value in lmdb_cursor:

    datum.ParseFromString(value)

    label = datum.label  

    print label

    data = caffe.io.datum_to_array(datum)  

    print data.shape  

    print datum.channels 

    image = data.transpose(1, 2, 0)

    #cv2.imshow('cv2.png', image)

    #cv2.waitKey(0)

    print key 

    if label < 10: 

    #in_txn.put(key, value)

        FilePath = "/data_4/songqing/caffe_official/caffe/imagenet_dataset/train/%d/%d.jpg" % (label, index)

        index = index + 1 

        cv2.imwrite( FilePath , image)

#cv2.destroyAllWindows()  

lmdb_env.close() 

  • 获取validation数据,并放入对应的子目录下:

类似于train数据,放入相应的子目录下。

 

标签文件.txt文件制作.

接着我们需要制作一个train.txt、val.txt文件,这两个文件分别包含了我们上面的训练数据的图片路径,以及其对应的标签,如下所示。

/data_4/songqing/caffe_official/caffe/imagenet_dataset/train/9/988.jpg  9

/data_4/songqing/caffe_official/caffe/imagenet_dataset/train/9/9918.jpg 9

基于子目录的目录名设置标签。标签数据文件txt的生成可以通过如下代码,通过各个子目录下面的图片,得到标签文件train.txt和val.txt:

  • 制作train的标签文件

Python脚本实现如下:

  #!/usr/bin/env python

 

import os

import numpy as np

from matplotlib import pyplot as plt

import cv2

import shutil

 

#scan files in FindPath, if FlagStr not null, get  this file  only

def GetFileList(FindPath,FlagStr=[]):    

    import os  

    FileList=[]  

    FileNames=os.listdir(FindPath) #get files in the FindPath

    if len(FileNames)>0:  

        for fn in FileNames: #scan subdirs 

            if len(FlagStr)>0:  

                if IsSubString(FlagStr,fn):  

                    fullfilename=os.path.join(FindPath,fn)  

                    FileList.append(fullfilename)  

            else:  

                fullfilename=os.path.join(FindPath,fn)  

                FileList.append(fullfilename)  

    if len(FileList)>0:  

        FileList.sort() #sort the FileList  

    return FileList  

 

def IsSubString(SubStrList,Str):    

    flag=True  

    for substr in SubStrList:  

        if not(substr in Str):  

            flag=False  

    return flag

 

txtFile=open('/data_4/songqing/caffe_official/caffe/imagenet_dataset/train.txt','w')  

subdirList = GetFileList("/data_4/songqing/caffe_official/caffe/imagenet_dataset/train/");

print subdirList

for dirName in subdirList:

    tmpList = dirName.split('/')#获取子目录的文件名

    print tmpList

    print tmpList[7]#子目录的文件名

    print dirName

    imgFileList=GetFileList(dirName)

    for imgFile in imgFileList:

        tmpFileList = imgFile.split("/")

        print tmpFileList[7] #这是个比较蠢笨的办法,因为Python水平有限就先这个搞吧

        print tmpFileList[8] 

        strImageAndTag= tmpFileList[7]+'/'+tmpFileList[8] +' '+tmpList[7]+'\n'#\t -> ' '

        print strImageAndTag

        txtFile.writelines(strImageAndTag)

 

txtFile.close()

 

把生成的标签文件,和train\val文件夹放在同一个目录下面:

  • 制作val的标签文件

同train标签文件制作相同,只是路径不同。

需要注意,我们标签数据文件里的文件路径和图片的路径要对应的起来,比如val.txt文件的某一行的图片路径,是否在val目录下面:

 

生成lmdb数据并读取验证

接着我们的目的就是要通过上面的四个文件,把图片的数据和其对应的标签打包起来,打包成lmdb数据格式。

  • 打包train数据到lmdb格式

使用sh实现打包脚本如下:

#!/usr/bin/env sh

# Create the imagenet lmdb inputs

# N.B. set the path to the imagenet train + val data dirs

 

EXAMPLE=/data_4/songqing/caffe_official/caffe/imagenet_dataset  # 生成模型训练数据  

DATA=/data_4/songqing/caffe_official/caffe/imagenet_dataset  # python脚步处理后数据路径  

TOOLS=/data_4/songqing/caffe_official/caffe/.build_release/tools # caffe的工具库  

 

TRAIN_DATA_ROOT=/data_4/songqing/caffe_official/caffe/imagenet_dataset/train/ #待处理的训练数据  

 

# Set RESIZE=true to resize the images to 256x256. Leave as false if images have

# already been resized using another tool.

RESIZE=false

if $RESIZE; then

  RESIZE_HEIGHT=256

  RESIZE_WIDTH=256

else

  RESIZE_HEIGHT=0

  RESIZE_WIDTH=0

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 1

fi

 

 

echo "Creating train lmdb..."

 

GLOG_logtostderr=1 $TOOLS/convert_imageset \

    --resize_height=$RESIZE_HEIGHT \

    --resize_width=$RESIZE_WIDTH \

    --shuffle \

    $TRAIN_DATA_ROOT \

    $DATA/train.txt \

    $EXAMPLE/train_lmdb

 

echo "Done."

通过运行上面的脚本,我们即将得到文件夹train_lmdb。

  • 验证该数据集是否正确

我们打开train_lmdb文件目录,并查看一下文件data.mdb数据的大小,如果这个数据包好了我们所有的训练图片数据,查一下这个文件的大小是否符合预期大小,如果文件的大小才几k而 已,那么就代表你没有打包成功,估计是因为路径设置错误。

我们也可以通过如下的代码读取上面打包好的数据,把图片、和标签打印出来,查看一下,查看 lmdb数据请参考下面的代码:

python lmdb数据验证:

#!/usr/bin/env python

 

import caffe

from caffe.proto import caffe_pb2

import lmdb

import cv2 

import numpy as np

 

lmdb_env = lmdb.open('/data_4/songqing/caffe_official/caffe/imagenet_dataset/train_lmdb', readonly=True)

lmdb_txn = lmdb_env.begin()

lmdb_cursor = lmdb_txn.cursor()

datum = caffe_pb2.Datum()

 

for key, value in lmdb_cursor:

    datum.ParseFromString(value)

    label = datum.label  

    print label

    data = caffe.io.datum_to_array(datum)  

    print data.shape  

    print datum.channels  

    image = data.transpose(1, 2, 0)

    cv2.imshow('cv2.png', image)

    cv2.waitKey(0)

    print key 

    #if label < 10:

    #    in_txn.put(key, value)

 

#cv2.destroyAllWindows()  

lmdb_env.close()  

通过上面的函数,我们可以是读取相关的lmdb数据文件。

 

使用已有的lmdb生成新的lmdb

某些情况下,我们可能只训练一个数据集中的一小部分,例如,我们只训练imagenet数据集中的标签为[0,10)的数据。那么,我们就要把这些标签的数据读取并生成新的数据集。

实现代码如下:

#!/usr/bin/env python

 

import caffe

from caffe.proto import caffe_pb2

import lmdb

import cv2 

import numpy as np

 

lmdb_env = lmdb.open('/data_4/songqing/caffe_official/caffe/examples/imagenet_songqing/ilsvrc12_train_lmdb', readonly=True)

lmdb_txn = lmdb_env.begin()

lmdb_cursor = lmdb_txn.cursor()

datum = caffe_pb2.Datum()

 

in_db = lmdb.Environment("/data_4/songqing/caffe_official/caffe/examples/imagenet_songqing/sub10_train_lmdb/", map_size=int(1e12))

 

with in_db.begin(write=True) as in_txn:

    for key, value in lmdb_cursor:

        datum.ParseFromString(value)

        label = datum.label  

        print label

        data = caffe.io.datum_to_array(datum)  

        print data.shape  

        print datum.channels  

        image = data.transpose(1, 2, 0)

        #cv2.imshow('cv2.png', image)

        #cv2.waitKey(0)

        print key 

        if label < 10: 

            in_txn.put(key, value)

 

in_db.close()

#cv2.destroyAllWindows()  

lmdb_env.close() 

 

制作均值文件

这个是为了图片归一化而生成的图片平均值文件,把所有的图片相加起来,做平均,具体的sh脚本如下:

#!/usr/bin/env sh  

# Compute the mean image from the imagenet training lmdb  

# N.B. this is available in data/ilsvrc12  

  

EXAMPLE=/data_4/songqing/caffe_official/caffe/imagenet_dataset

DATA=/data_4/songqing/caffe_official/caffe/imagenet_dataset

TOOLS=/data_4/songqing/caffe_official/caffe/.build_release/tools

  

$TOOLS/compute_image_mean $EXAMPLE/train_lmdb \

   $DATA/train_mean.binaryproto

 

echo "Done."

验证集的制作同训练集的制作是相同的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值