Caffe學習筆記(二):使用Python生成caffe所需的lmdb檔案和txt列表清單檔案
轉載請註明作者和出處: http://blog.csdn.net/c406495762
Python版本:Python2.7
執行平臺:Ubuntu14.04
最後修改時間:2017.4.20
在上個筆記中,已經學會了如何使用Caffe利用作者給的指令碼訓練CIFAR-10資料集,得到訓練好的CNN模型。但是在上個筆記中,使用的都是作者提供好的指令碼檔案,完全就是按照教程跑了一下提供的demo。對於自己手裡的一些圖片資料集,如何轉換圖片格式、如何計算圖片資料的均值、如何編寫prototxt配置檔案是接下來筆記的主要內容。本篇筆記主要記錄如何將圖片資料轉換成db檔案,圖片均值的計算、prototxt配置檔案的編寫會後續進行講解。
一、Caffe訓練學習步驟回顧
1.準備資料集(訓練集和測試集)
2.圖片資料轉換成db(leveldb/lmdb)檔案
3.計算圖片資料的均值
4.prototxt配置檔案
5.訓練模型
注意:還有一種不需要db檔案和計算圖片資料的均值的訓練方法,而是隻需要一個txt列表清單,另一種訓練步驟在講完此種學習方法後進行講解。
二、圖片資料轉換成db(leveldb/lmdb)檔案
1.概述
在深度學習的實際應用中,我們經常用到的原始資料是圖片檔案,如jpg,jpeg,png,tif等格式的,而且有可能圖片的大小還不一致。而在caffe中經常使用的資料型別是lmdb或leveldb,因此就產生了這樣的一個問題:如何從原始圖片檔案轉換成caffe中能夠執行的db(leveldb/lmdb)檔案?
在caffe中,作者為我們提供了這樣一個檔案:convert_imageset.cpp,存放在caffe根目錄下的tools目錄下。編譯好caffe之後,會生成對應的可執行檔案放在 build/tools/目錄下,這個可執行檔案convert_imageset的作用就是用於將圖片檔案轉換成caffe框架中能直接使用的db檔案。
該檔案的使用格式如下所示:
convert_imageset [FLAGS] ROOTFOLDER/ LISTFILE DB_NAME
需要帶四個引數:
- FLAGS: 圖片引數組,後面詳細介紹
- ROOTFOLDER/: 圖片存放的絕對路徑,從linux系統根目錄開始
- LISTFILE: 圖片檔案列表清單,一般為一個txt檔案,一行一張圖片
- DB_NAME: 最終生成的db檔案存放目錄
因此如果想使用convert_imageset這個工具生成我們需要的db檔案,就需要先得到圖片檔案列表清單txt檔案。
在caffe根目錄的/examples/image目錄下,有兩張共我們測試的圖片,它們是cat.jpg和fish-bike.jpg。我們可以使用eog命令在終端檢視這兩個圖片(遠端登入ssh不行,vnc可以,當然不是遠端登入是可以使用的),它們分別如下:
我們可以使用這兩圖片學習如何製作圖片檔案列表清單txt檔案。這個圖片列表清單txt檔案 格式如下:
圖片檔名 標籤
以cat.jpg和fish-bike.jpg為例,那麼這兩個圖片的列表清單txt檔案即為:
cat.jpg 1
fish-bike.jpg 2
依此類推,一行一張圖片標籤。我們定義1標籤是貓的標籤,2標籤是自行車的標籤。很顯然,如果就這麼兩個圖片我們手寫一個圖片列表清單txt檔案即可,但是如果是很多圖片,我們又該如何處理呢?
顯然,我們可以使用指令碼,有很多方法可供選擇shell指令碼,python指令碼等。而我採用的方式是使用python指令碼處理這些檔案,生成最終的圖片列表清單txt檔案。
2.利用python指令碼編寫圖片列表清單txt檔案
(1)在caffe根目錄下建立一個我們的工程目錄my-caffe-project,使用如下指令:
cd /home/Jack-Cui/caffe-master && mkdir my-caffe-project
(2)建立並編輯create_db.py檔案,使用如下指令:
vim create_db.py
檔案編輯內容如下:
# -*- coding: UTF-8 -*-
import os
import re
"""
函式說明:生成圖片列表清單txt檔案
Parameters:
images_path - 圖片存放目錄
txt_save_path - 圖片列表清單txt檔案的儲存目錄
Returns:
無
Author:
Jack Cui
Modify:
2017-03-29
"""
def createFileList(images_path, txt_save_path):
#開啟圖片列表清單txt檔案
fw = open(txt_save_path,"w")
#檢視圖片目錄下的檔案,相當於shell指令ls
images_name = os.listdir(images_path)
#遍歷所有檔名
for eachname in images_name:
#正則表示式這裡可以根據情況進行更改
#正則表示式規則:找以cat開頭,緊跟0到10個數字,並以jpg結尾的圖片檔案
pattern_cat = r'(^cat\d{0,10}.jpg$)'
#正則表示式規則:找以fish-bike開頭,緊跟0到10個數字,以jpg結尾的圖片檔案
pattern_bike = r'(^fish-bike\d{0,10}.jpg$)'
#正則表示式匹配
cat_name = re.search(pattern_cat, eachname)
bike_name = re.search(pattern_bike, eachname)
#按照規則將內容寫入txt檔案中
if cat_name != None:
fw.write(cat_name.group(0) + ' 1\n')
if bike_name != None:
fw.write(bike_name.group(0) + ' 2\n')
#列印成功資訊
print "生成txt檔案成功"
#關閉fw
fw.close()
if __name__ == '__main__':
#caffe_root目錄
caffe_root = '/home/Jack-Cui/caffe-master/'
#my-caffe-project目錄
my_caffe_project = caffe_root + 'my-caffe-project/'
#圖片存放目錄
images_path = caffe_root + 'examples/images/'
#生成的圖片列表清單txt檔名
txt_name = 'filelist.txt'
#生成的圖片列表清單txt檔案的儲存目錄
txt_save_path = my_caffe_project + txt_name
#生成txt檔案
createFileList(images_path, txt_save_path)
(3)執行create_db.py指令碼檔案,使用如下指令:
python create_db.py
(4)使用指令cat create_filelist.py,檢視結果如下:
!=
3.利用python指令碼執行convert_imageset檔案生成db檔案
生成的這個filelist.txt檔案,就可以作為第三個引數,直接使用了。
接下來,我們來了解一下FLAGS這個引數組,有些什麼內容:
gray: 是否以灰度圖的方式開啟圖片。程式呼叫opencv庫中的imread()函式來開啟圖片,預設為false
backend:需要轉換成的db檔案格式,可選為leveldb或lmdb,預設為lmdb
resize_width/resize_height: 改變圖片的大小。在執行中,要求所有圖片的尺寸一致,因此需要改變圖片大小。 程式呼叫opencv庫的resize()函式來對圖片放大縮小,預設為0,不改變
check_size: 檢查所有的資料是否有相同的尺寸。預設為false,不檢查
encoded: 是否將原圖片編碼放入最終的資料中,預設為false
encode_type: 與前一個引數對應,將圖片編碼為哪一個格式:‘png’,’jpg’……
好了,知道這些引數後,我們就可以呼叫命令來生成最終的lmdb格式資料了。
(1)繼續編寫create_db.py檔案,使用如下指令:
vim create_db.py
檔案新增內容如下:
# -*- coding: UTF-8 -*-
import commands
import os
import re
"""
函式說明:生成圖片列表清單txt檔案
Parameters:
images_path - 圖片存放目錄
txt_save_path - 圖片列表清單txt檔案的儲存目錄
Returns:
無
Author:
Jack Cui
Modify:
2017-03-29
"""
def createFileList(images_path, txt_save_path):
#開啟圖片列表清單txt檔案
fw = open(txt_save_path,"w")
#檢視圖片目錄下的檔案,相當於shell指令ls
images_name = os.listdir(images_path)
#遍歷所有檔名
for eachname in images_name:
#正則表示式這裡可以根據情況進行更改
#正則表示式規則:找以cat開頭,緊跟0到10個數字,並以jpg結尾的圖片檔案
pattern_cat = r'(^cat\d{0,10}.jpg$)'
#正則表示式規則:找以fish-bike開頭,緊跟0到10個數字,以jpg結尾的圖片檔案
pattern_bike = r'(^fish-bike\d{0,10}.jpg$)'
#正則表示式匹配
cat_name = re.search(pattern_cat, eachname)
bike_name = re.search(pattern_bike, eachname)
#按照規則將內容寫入txt檔案中
if cat_name != None:
fw.write(cat_name.group(0) + ' 1\n')
if bike_name != None:
fw.write(bike_name.group(0) + ' 2\n')
#列印成功資訊
print "生成txt檔案成功"
#關閉fw
fw.close()
"""
函式說明:生成lmdb檔案
Parameters:
caffe_root - caffe根目錄
images_path - 圖片存放目錄
txt_save_path - 圖片列表清單txt檔案的儲存目錄
Returns:
無
Author:
Jack Cui
Modify:
2017-03-29
"""
def create_db(caffe_root, images_path, txt_save_path):
#lmdb檔名字
lmdb_name = 'img_train.lmdb'
#生成的db檔案的儲存目錄
lmdb_save_path = caffe_root + 'my-caffe-project/' + lmdb_name
#convert_imageset工具路徑
convert_imageset_path = caffe_root + 'build/tools/convert_imageset'
cmd = """%s --shuffle --resize_height=256 --resize_width=256 %s %s %s"""
status, output = commands.getstatusoutput(cmd % (convert_imageset_path, images_path,
txt_save_path, lmdb_save_path))
print output
if(status == 0):
print "lmbd檔案生成成功"
if __name__ == '__main__':
#caffe_root目錄
caffe_root = '/home/Jack-Cui/caffe-master/'
#my-caffe-project目錄
my_caffe_project = caffe_root + 'my-caffe-project/'
#圖片存放目錄
images_path = caffe_root + 'examples/images/'
#生成的圖片列表清單txt檔名
txt_name = 'filelist.txt'
#生成的圖片列表清單txt檔案的儲存目錄
txt_save_path = my_caffe_project + txt_name
#生成txt檔案
createFileList(images_path, txt_save_path)
#生成lmdb檔案
create_db(caffe_root, images_path, txt_save_path)
設定引數-shuffle,打亂圖片順序。設定引數-resize_height和-resize_width將所有圖片尺寸都變為256*256。
./home/xxx/caffe-master/examples/images/ 為圖片儲存的絕對路徑,我的caffe放在了/home/Jack-Cui目錄下。
最終結果執行如下,大功告成!