天天看點

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

環境:ubuntu16.04 CPU

經過千難萬險将環境配置好之後,MNIST資料集也測試過了,MNIST資料集是通過caffe可以直接擷取資料集,如果我們要處理自己的資料的話,我們就需要做一些轉化了,我們的圖像資料往往是圖檔檔案,jpg,jpeg,png等,然而在caffe中我們需要使用的資料類型是lmdb或leveldb,是以我們在對自己的圖像資料進行訓練/測試之前,需要轉換成caffe架構可以直接使用的db檔案。

說明:本篇部落格是在我看過一些資料之後總結的,一方面分享給大家,希望能給初學者者帶來幫助,另外一方面,部落客也是小白入門,記錄本篇部落格也算是作為自己的一個知識總結。

ps:本篇部落格将會用兩個資料集進行,一個是caffe自帶的簡單圖檔,一個是自己制作的簡單資料集

caffe自帶簡單圖檔樣例

1.1:建立自己的圖檔資料

我們知道caffe自帶了兩張圖檔,如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

1.2 建立圖檔清單清單

這一步我們需要建立自己圖檔資料集的清單txt檔案,這裡提供兩種方法。

方法1:建立一個sh檔案

cd ~/caffe-master/
sudo gedit examples/images/create_filelist.sh
           

sudo就是擷取管理者權限,gedit是用記事本的方式打開檔案,其實在caffe-master/examples/images下并沒有create_filelist.sh檔案,上述指令就是在上述目錄下建立一個空的create_filelist.sh腳本檔案,并打開,如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

然後将以下代碼複制到create_filelist.sh檔案中,儲存退出。

DATA=examples/images
echo "Create train.txt..."
rm -rf $DATA/train.txt
find $DATA -name *cat.jpg | cut -d '/' -f3 | sed "s/$/ 1/">>$DATA/train.txt
find $DATA -name *bike.jpg | cut -d '/' -f3 | sed "s/$/ 2/">>$DATA/tmp.txt
cat $DATA/tmp.txt>>$DATA/train.txt
rm -rf $DATA/tmp.txt
echo "Done.."
           

代碼解釋:

>DATA=examples/images   解釋:DATA就代表了該路徑
           
  • rm: remove删除檔案
rm -rf $DATA/train.txt    解釋:删除該路徑下的所有train.txt,注意前面的路徑表示
           
  • find: 尋找檔案
  • cut: 截取路徑
  • sed: 加标注
find $DATA -name *cat.jpg | cut -d '/' -f3 | sed "s/$/ 1/">>$DATA/train.txt

解釋:
》》find,在DATA路徑下尋找cat.jpg,前面的*号應該是表示任何字首的意思,意思就是名字的前面不考慮,之後最後面是cat.jpg就算是找到,詳情百度find指令的用法。
》》 '|' 這個代表或的意思。
》》cut -d '/' -f3 意思是截取檔案名,詳情百度cut用法。
》》sed "s/$/ 1/"表示在檔案名後加上标注,也就是所謂的label,從開始,自己人為定義的,注意前面有個空格,也就是标簽和檔案名中間有個空格。
》》$DATA/train.txt意思是将以上内容存入train.txt檔案中,注意>>的使用,train.txt原本并不存在,系統會自動建立該檔案夾,(Ubuntu就是這麼),下一行指令同理。
           
  • cat: catenate 将檔案内容合并到一個檔案裡。

cat $DATA/tmp.txt>>$DATA/train.txt

将tmp.txt中的指令合并到train.txt中

然後執行以下指令運作create_filelist.sh,生成對應的train.txt

cd ~/caffe-master/
sudo sh examples/images/create_filelist.sh
           

如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

執行結束,在路徑~/caffe-master/examples/images/下可以看到生成的train.txt.

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

打開train.txt檔案

sudo gedit train.txt
           

如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

這裡生成的是train.txt,測試集test.txt和驗證集val.txt類似。

注意:這隻是個樣例,是以資料和配置檔案都放在了一起。

方法2:直接使用代碼

準備工作:在~/caffe-master/examples/images/路徑下建立兩個檔案夾,cat和bike,然後将cat.jpg移動到cat檔案将夾,将fish-bike.jpg移動到bike檔案夾,如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

執行以下指令

cd ~/caffe-master/examples/images/
ls bike | sed "s:^:bike/:" | sed "s:$: 1:" >> train.txt
           

會在images目錄下生成train.txt檔案,然後打開

sudo gedit train.txt
           

如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

然後執行以下指令:

打開train.txt,如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

代碼解釋:

  • ls bike 代表列出該目錄下的圖檔,相當于擷取檔案名
  • sed “s:^:bike/:” 表示給檔案名加字首bike/,該字首也代表了路徑
  • sed “s:$: 1:” 表示給檔案名加字尾 1,注意有個空格
  • train.txt 表示将以上内容放到train.txt下一行代碼同理,隻是将bike換成cat,同時最後都放到了train.txt下

ps:兩種方法其實本質上是一樣的,隻是表達形式不一樣。

1.3 利用清單檔案生成對應的db檔案

在路徑~/caffe-master/tools路徑下,存在檔案convert_imageset.cpp

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

編譯之後,生成可執行檔案convert_imageset,存在于路徑~/caffe-master/build/tools/

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

ps:convert_imageset可以将資料生成的txt檔案轉換成caffe架構能夠直接使用的db檔案,将該指令的介紹附在此:

指令行使用格式:

convert_imageset [FLAGS] ROOTFOLDER/ LISTFILE DB_NAME
           
  • FLAGS: 圖檔參數組
    • gray: 是否以灰階圖的方式打開圖檔。程式調用opencv庫中的imread()函數來打開圖檔,預設為false。
    • shuffle: 是否随機打亂圖檔順序。預設為false。
    • backend:需要轉換成的db檔案格式,可選為leveldb或lmdb,預設為lmd。
    • resize_width/resize_height: 改變圖檔的大小。在運作中,要求所有圖檔的尺寸一緻,是以需要改變圖檔大小。 程式調用opencv庫的resize()函數來對圖檔放大縮小,預設為0,不改變。
    • check_size:檢查所有的資料是否有相同的尺寸。預設為false,不檢查。
    • encoded:是否将原圖檔編碼放入最終的資料中,預設為false。
    • encode_type: 與前一個參數對應,将圖檔編碼為哪一個格式:‘png’,’jpg’等。
  • ROOTFOLDER/: 圖檔存放的絕對路徑,從linux系統根目錄開始(不是caffe根目錄,需要圖檔存放的絕對路徑)
  • LISTFILE: 圖檔檔案清單清單,一般為一個txt檔案,一行一張圖檔
  • DB_NAME: 最終生成的db檔案存放目錄

方法1:建立腳本sh檔案實作轉換:

PS:該方法對應的路徑如下圖所示(該方法對應生成txt檔案的方法1)

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

注意:這個地方兩張圖檔都在images目錄下,而不是在各自的兩個檔案夾下,因為下面create_lmdb.sh檔案的代碼中,convert_imageset的使用必須得是圖檔存放的絕對路徑,這樣兩張圖檔在同一個絕對路徑下,如果兩張圖檔在不同的檔案夾下,那麼圖檔的絕對路徑就不同了,得修改sh檔案了!

執行以下指令生成sh檔案:

cd ~/caffe-master/
sudo gedit examples/images/create_lmdb.sh
           

編輯生成的sh檔案,将以下代碼複制到create_lmdb.sh檔案

DATA=examples/images
rm -rf $DATA/img_train_lmdb
build/tools/convert_imageset --shuffle --resize_height= --resize_width= /home/heimu/caffe-master/examples/images/ $DATA/train.txt  $DATA/img_train_lmdb
           

代碼解釋:

build/tools/convert_imageset

這個表示convert_imageset的路徑,它的絕對路徑為/home/heimu/caffe-master/build/tools/,由于該檔案在路徑~/caffe-master目錄下執行的,是以前面的路徑可以省略。

--shuffle

該參數用于打亂圖檔順序。

--resize_height=256 --resize_width=256

該參數用于限制圖檔的尺寸為256*256,因為資料圖檔可能尺寸不同,在這将尺寸歸化。

/home/heimu/caffe-master/examples/images/

該路徑為圖檔資料的存放絕對路徑,從根目錄開始。

$DATA/train.txt

該檔案為圖檔清單清單,就是上一步生成的,此處為該檔案的路徑。

$DATA/img_train_lmdb

此處為生成的db檔案的存放目錄,會自動新生成img_train_lmdb檔案。

接下來運作剛剛編輯儲存的create_lmdb.sh的腳本檔案:

cd ~/caffe-master/
sudo sh examples/images/create_lmdb.sh 
           

如下圖所示,可以看到新生成的img_train_lmdb檔案

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

打開img_train_lmdb,如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

ps:如果在終端直接打開img_train_lmdb檔案夾,會遇到權限不夠問題,是以需要先執行下面指令,改變檔案權限

sudo chmod  img_train_lmdb/
           

然後再打開檔案即可,至此就生成了caffe架構所需要的lmdb檔案。

方法2:終端使用代碼直接實作

資料存儲如下:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

終端輸入以下代碼:

cd ~/caffe-master/examples/images

/home/heimu/caffe-master/build/tools/convert_imageset --resize_width= --resize_height= /home/heimu/caffe-master/examples/images/ ./train.txt ./img_train_lmdb
           

注意:此處路徑最為需要注意,由于是先進到的image目錄下,是以convert_imageset就需要指明絕對路徑,不然會提示找不到。

/home/heimu/caffe-master/examples/images/

該路徑加上train.txt中的圖檔路徑必須為圖檔的絕對路徑,切記images後面的 / 必不可少!

./train.txt

相當于/home/heimu/caffe-master/examples/images/train.txt

./img_train_lmd

同理,./的意思應該是表示目前目錄路徑

心得:使用convert_imageset的時候,最關鍵的一點是注意圖檔資料的絕對路徑不錯就行,此處的絕對路徑指的是前面的路徑加上txt檔案中的路徑才是圖檔的絕對路徑,切記切記!

結果如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

至此生成了db檔案,其實兩種方法一樣,個人推薦第一種!

自己制作簡單資料集

2.1制作自己的簡單資料集

部落客從網上下載下傳了一些圖檔,分為兩類,bird60張和cat60張,其中50張bird和50張cat作為訓練集,10張bird和10張cat作為驗證集,在/home/heimu/caffe-master/data下建立檔案夾myself,然後在myself檔案夾下建立兩個檔案夾,train和val,即訓練集和測試集,然後train檔案夾下建立兩個檔案夾,bird和cat,bird檔案夾下放50張bird圖檔,cat檔案夾下放50張cat圖檔,在val檔案夾下放10張bird和10張cat,至此準備好了我們的資料,如下圖所示

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

注意:為了便于處理,應該将圖檔統一命名,如上圖

2.2生成train.txt和val.txt,即訓練集和驗證機清單清單

在路徑/home/heimu/caffe-master/examples/建立一個myself檔案夾,用來存放配置檔案和腳本檔案。

ps:上面的例子由于簡單是以資料和配置檔案等檔案放在了一起,推薦分開兩個目錄。

cd ~/caffe-master/
sudo mkdir examples/myself
           
  • 指令mkdir,make directory,建立目錄

然後建立腳本檔案create_filelist,用來生成train.txt

sudo gedit examples/myself/create_filelist.sh
           

将以下代碼編輯進去,儲存退出:

DATA=data/myself
MY=examples/myself

echo "Create train.txt..."
rm -rf $DATA/train.txt
find $DATA/train/bird -name birdt*.jpg | cut -d '/' -f5 | sed "s:^:bird/:" | sed "s/$/ 1/">>$MY/train.txt
find $DATA/train/cat -name catt*.jpg | cut -d '/' -f5 | sed "s:^:cat/:" |  sed "s/$/ 2/">>$MY/train.txt

echo "Create val.txt..."
rm -rf $DATA/val.txt
find $DATA/val -name birdv*.jpg | cut -d '/' -f4 | sed "s/$/ 1/">>$MY/val.txt
find $DATA/val -name catv*.jpg | cut -d '/' -f4  | sed "s/$/ 2/">>$MY/val.txt

echo "All done"
           

代碼解釋:

rm -rf $DATA/train.txt

表示清除該路徑下的train.txt檔案

find $DATA/train/bird -name birdt*.jpg

此處為find指令的用法。

$DATA/train/bird

表示具體的圖檔路徑

birdt*.jpg

表示在以圖檔名字以birdt開始的jpg圖檔

cut -d '/' -f5

此處為cut指令的用法,具體表示請百度,此處表示以’/’為分隔符,由于該指令在caffe-master目錄下執行,之後路徑為/data/myself/train/bird/然後是圖檔名字,是以要采取的圖檔的名字為第5個,是以為-f5,下面val集的圖檔路徑為/data/myself/val/然後是圖檔名字,為第4個,是以為-f4

sed "s:^:bird/:"

此處表示給圖檔名字加字首’bird/’,表示一種路徑

由于train檔案夾下又分了兩個檔案夾,是以此處加字首,表示路徑

val檔案夾下直接就是圖檔,是以不需要字首。

sed "s/$/ 1/"

加字尾’ 1’,也就是标簽

$MY/train.txt

表示在/examples/myself/路徑下産生train.txt,以上内容全部儲存到此。

ps:此處create_filelist.sh的制作有另外一種方法,如下:

準備工作:
原始資料:train檔案夾下的bird圖檔和cat圖檔分别在各自的檔案夾下,即train檔案夾下有兩個檔案夾,bird和cat,但是val檔案夾目錄下并沒有再分開bird和cat,而是将驗證集張bird和張cat一起放到了val檔案夾下,這是上述方法的圖檔資料的存儲格式。
變更之處:此處需要将val檔案夾下建立兩個檔案夾,bird和cat1(因為在代碼中需要使用該檔案夾名稱,而cat是Ubuntu中的一個指令,沖突),同時将train檔案夾下的cat檔案夾重命名為cat1,将張bird圖檔放到bird檔案夾下,張cat檔案夾放到cat_1檔案夾下,即可!

其他步驟都一樣,隻是将create_filelist.sh代碼部分換成下列代碼:

代碼:

DATA=data/myself
MY=examples/myself

echo "Create train.txt..."
rm -rf $DATA/train.txt
ls $DATA/train/bird | sed "s:^:bird/:" | sed "s/$/ 1/">>$MY/train.txt
ls $DATA/train/cat1 | sed "s:^:cat1/:" | sed "s/$/ 2/">>$MY/train.txt

echo "Create val.txt..."
rm -rf $DATA/val.txt
ls $DATA/val/bird | sed "s:^:bird/:" | sed "s/$/ 1/">>$MY/val.txt
ls $DATA/val/cat1 | sed "s:^:cat1/:" | sed "s/$/ 2/">>$MY/val.txt

echo "All done"

代碼解釋:
此處代碼和上面代碼的改變支出就是将find和cut指令替換為了ls指令,ls表示列舉,具體含義可以百度,此處不細講
!!感覺這種方式簡單點!!!
           

然後在caffe-master根目錄下執行此sh檔案

cd ~/caffe-master/
sudo sh examples/myself/create_filelist.sh
           

執行結果如下圖

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

2.3轉換生成db檔案

建立sh腳本檔案

cd ~/caffe-master/
sudo gedit examples/myself/create_lmdb.sh
           

編輯該sh檔案,代碼如下:

MY=examples/myself

echo "Create train lmdb.."
rm -rf $MY/train_lmdb
build/tools/convert_imageset --shuffle --resize_height= --resize_width= /home/heimu/caffe-master/data/myself/train/ $MY/train.txt $MY/train_lmdb

echo "Create val lmdb.."
rm -rf $MY/val_lmdb
build/tools/convert_imageset --shuffle --resize_width= --resize_height= /home/heimu/caffe-master/data/myself/val/ $MY/val.txt $MY/val_lmdb

echo "All Done.."
           

儲存退出,執行create_lmdb.sh檔案,代碼如下

cd ~/caffe-master/
sudo sh examples/myself/create_lmdb.sh
           

結果如下圖:

caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案
caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

至此,所有轉換過程完成個人推薦建立腳本建sh的方式執行,重點在于了解代碼的意思的,确實ubuntu有很多指令,很多用法,不懂得百度咯,代碼搞懂之後,就可以根據自己的資料自己的需求修改腳本檔案來達到自己的需求!

總結:自己查找了相關的教程,看了相關的講解,跟着做了一遍,成功了,然後花了一天的時間寫這篇部落格,在寫的過程自己又做了一遍,而且跟着寫部落格的思路,不懂的地方自己又查找資料,加上備注,雖然這樣可能慢點,但是隻有自己親手動一動,才能真正了解,獲益匪淺!

推薦部落格:

http://blog.csdn.net/u010193446/article/details/53406754

http://www.cnblogs.com/denny402/p/5083300.html