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