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

 1 # -*- coding: utf-8 -*-
 2 # @Time    : 2018/12/9 0009 12:04
 3 # @Author  : sunjianbo
 4 # @Email   : 1871593109@qq.com
 5 # @Software: PyCharm
 6 import os
 7 #數據集根目錄所在路徑
 8 root_data_path = r"C:\Users\Administrator\Desktop\data_set"
 9 #輸出的TXT文件路徑
10 traintxt_path = root_data_path + "\\" + "train.txt"
11 valtxt_path = root_data_path + "\\" + "val.txt"
12 
13 #如果存在之前生成的TXT文件,先把它們刪除
14 if os.path.exists(traintxt_path):
15     os.remove(traintxt_path)
16 if os.path.exists(valtxt_path):
17     os.remove(valtxt_path)
18 #返回數據集文件夾下的子文件夾
19 filenames = os.listdir(root_data_path)    #["train", "val"]
20 
21 #打開要存儲的TXT文件
22 file_train = open(traintxt_path, "w")
23 file_val = open(valtxt_path, "w")
24 
25 if len(filenames) > 0:
26     for fn in filenames:
27         #數據集根目錄下的子文件夾路徑,train和val的絕對路徑
28         full_filename = os.path.join(root_data_path, fn)
29         
30         # 判斷是訓練集文件夾,還是驗證集文件夾
31         if fn == "train":
32             #找出訓練集文件夾下的子文件夾名字,是每個類別的文件夾,0表示狗,1表示貓
33             file = os.listdir(full_filename)   #["0", "1"]
34             for name in file:
35                 #獲得train文件夾下的子文件夾“0”和“1”的絕對路徑
36                 temp = os.path.join(full_filename, name)
37                 for img in os.listdir(temp):    #分別遍歷兩個文件夾["0", "1"]下的所有圖像
38                     #將圖像的信息寫入到train.txt文件
39                     file_train.write(name + "/" + img + " " + name + "\n")
40         elif fn == "val":        #當進入到val文件夾后
41             for img in os.listdir(full_filename):   #遍歷所有的圖像
42                 category = img.split('_')           #對圖像的名字進行分割,返回的是一個列表
43                 if category[0] == "dog":            #當分割的結果可以判斷是dog時,類別是“0”
44                     file_val.write(img + " " + "0" + "\n")
45                 elif category[0] == "cat":           #當分割的結果可以判斷是cat時,類別是“1”
46                     file_val.write(img + " " + "1" + "\n")
47                 else:
48                     print("驗證集中圖片名字有誤")
49         else:
50             print("存在錯誤文件夾")
51 else:
52     print("該文件夾下不存在子文件夾")
53 
54 file_train.close()
55 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文件

 

 1 #!/usr/bin/env sh
 2 # Create the imagenet lmdb inputs    #創建LMDB格式的文件輸入
 3 # N.B. set the path to the imagenet train + val data dirs    #為train和val數據目錄設置路徑
 4 
 5 EXAMPLE=examples/imagenet                     #生成模型訓練數據的文件夾,即create_imagenet.sh(這里名字可以修改)所在文件夾,也就是最終的LMDB數據存儲的位置。                 
 6 DATA=data/ilsvrc12                            #python腳本處理完的數據存儲路徑,也就是train.txt和val.txt的存儲路徑
 7 TOOLS=build/tools                             #caffe的工具庫,需要找到自己編譯過的convert_imageset.exe,具體位置在D:/program_files/caffe/caffe-windows/Build/x64/Release  8 
 9 TRAIN_DATA_ROOT=/path/to/imagenet/train/      #待處理的圖像訓練數據的路徑
10 VAL_DATA_ROOT=/path/to/imagenet/val/          #待處理的圖像驗證數據的路徑
11 
12 # Set RESIZE=true to resize the images to 256x256. Leave as false if images have
13 # already been resized using another tool.
14 RESIZE=false                                  #是否對圖片進行resize操作,如果是設置為True
15 if $RESIZE; then
16   RESIZE_HEIGHT=256                           #resize的尺寸是256*256
17   RESIZE_WIDTH=256
18 else
19   RESIZE_HEIGHT=0
20   RESIZE_WIDTH=0
21 fi
22 
23 if [ ! -d "$TRAIN_DATA_ROOT" ]; then
24   echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
25   echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
26        "where the ImageNet training data is stored."
27   exit 1
28 fi
29 
30 if [ ! -d "$VAL_DATA_ROOT" ]; then
31   echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
32   echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
33        "where the ImageNet validation data is stored."
34   exit 1
35 fi
36 
37 
38 echo "if train.txt and val.txt are exist in EXAMPLE dir. clear all"
39 #刪除已存在的lmdb格式文件,若在已存在lmdb格式的文件夾下再添加lmdb文件,會出現錯誤
40 rm -rf $EXAMPLE/train_lmdb  
41 rm -rf $EXAMPLE/val_lmdb      
42 
43 
44 echo "Creating train lmdb..."
45 
46 GLOG_logtostderr=1 $TOOLS/convert_imageset \     #調用convert_imageset進行格式轉換
47     --resize_height=$RESIZE_HEIGHT \             #將圖片調整到固定尺寸
48     --resize_width=$RESIZE_WIDTH \
49     --shuffle \                                  #打亂圖像的順序
50     $TRAIN_DATA_ROOT \
51     $DATA/train.txt \                           #這里的DATA是存放train.txt的路徑
52     $EXAMPLE/ilsvrc12_train_lmdb                #這里修改輸出的訓練集的LMDB的名稱
53 
54 echo "Creating val lmdb..."
55 
56 GLOG_logtostderr=1 $TOOLS/convert_imageset \     #調用convert_imageset進行格式轉換
57     --resize_height=$RESIZE_HEIGHT \             #將圖片調整到固定尺寸
58     --resize_width=$RESIZE_WIDTH \
59     --shuffle \                                  #打亂圖像的順序
60     $VAL_DATA_ROOT \
61     $DATA/val.txt \                             #這里的DATA是存放val.txt的路徑
62     $EXAMPLE/ilsvrc12_val_lmdb                  #這里修改輸出的驗證集的LMDB的名稱
63 
64 echo "Done."

(2)基於本例子的修改后的create_imagenet.sh文件如下,名稱改為:convert_my_LMDB.sh

 1 #!/usr/bin/env sh
 2 # Create the imagenet lmdb inputs    #創建LMDB格式的文件輸入
 3 # N.B. set the path to the imagenet train + val data dirs    #為train和val數據目錄設置路徑
 4 
 5 EXAMPLE=C:/Users/Administrator/Desktop/data_set                   #生成模型訓練數據的文件夾,即create_imagenet.sh(這里名字可以修改)所在文件夾。                 
 6 DATA=C:/Users/Administrator/Desktop/data_set                #python腳本處理完的數據存儲路徑,也就是train.txt和val.txt的存儲路徑
 7 TOOLS=D:/program_files/caffe/caffe-windows/Build/x64/Release #caffe的工具庫,找到自己的編譯過的convert_imageset.exe所在的位置  8 
 9 TRAIN_DATA_ROOT=C:/Users/Administrator/Desktop/data_set/train/      #待處理的訓練數據的路徑
10 VAL_DATA_ROOT=C:/Users/Administrator/Desktop/data_set/val/          #待處理的驗證數據的路徑
11 
12 # Set RESIZE=true to resize the images to 256x256. Leave as false if images have
13 # already been resized using another tool.
14 RESIZE=true                                 #是否對圖片進行resize操作,如果是設置為True
15 if $RESIZE; then
16   RESIZE_HEIGHT=256                           #resize的尺寸是256*256
17   RESIZE_WIDTH=256
18 else
19   RESIZE_HEIGHT=0
20   RESIZE_WIDTH=0
21 fi
22 
23 if [ ! -d "$TRAIN_DATA_ROOT" ]; then
24   echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
25   echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
26        "where the ImageNet training data is stored."
27   exit 1
28 fi
29 
30 if [ ! -d "$VAL_DATA_ROOT" ]; then
31   echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
32   echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
33        "where the ImageNet validation data is stored."
34   exit 1
35 fi
36 
37 
38 echo "if train.txt and val.txt are exist in EXAMPLE dir. clear all"
39 #刪除已存在的lmdb格式文件,若在已存在lmdb格式的文件夾下再添加lmdb文件,會出現錯誤 40 rm -rf $EXAMPLE/train_lmdb  41 rm -rf $EXAMPLE/val_lmdb  42 
43 
44 echo "Creating train lmdb..."
45 
46 GLOG_logtostderr=1 $TOOLS/convert_imageset \     #調用convert_imageset進行格式轉換
47     --resize_height=$RESIZE_HEIGHT \             #將圖片調整到固定尺寸
48     --resize_width=$RESIZE_WIDTH \
49     --shuffle \                                  #打亂圖像的順序
50     $TRAIN_DATA_ROOT \
51     $DATA/train.txt \                           #這里的DATA是存放train.txt的路徑
52     $EXAMPLE/train_lmdb                      #這里修改輸出的訓練集的LMDB的名稱
53 
54 echo "Creating val lmdb..."
55 
56 GLOG_logtostderr=1 $TOOLS/convert_imageset \     #調用convert_imageset進行格式轉換
57     --resize_height=$RESIZE_HEIGHT \             #將圖片調整到固定尺寸
58     --resize_width=$RESIZE_WIDTH \
59     --shuffle \                                  #打亂圖像的順序
60     $VAL_DATA_ROOT \
61     $DATA/val.txt \                             #這里的DATA是存放val.txt的路徑
62     $EXAMPLE/val_lmdb                        #這里修改輸出的驗證集的LMDB的名稱
63 
64 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環境下雙擊直接運行。

1 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
2 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
3 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM