1. 程式人生 > >caffe學習筆記1:轉化自己的資料為(leveldb/lmdb)檔案

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

環境:ubuntu16.04 CPU

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

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

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

caffe自帶簡單圖片樣例

1.1:建立自己的圖片資料

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

這裡寫圖片描述

這裡寫圖片描述

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指令碼檔案,並開啟,如下圖:

這裡寫圖片描述

然後將以下程式碼複製到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,從0開始,自己人為定義的,注意1前面有個空格,也就是標籤和檔名中間有個空格。
》》$DATA/train.txt意思是將以上內容存入train.txt檔案中,注意>>的使用,train.txt原本並不存在,系統會自動新建該資料夾,(Ubuntu就是這麼6),下一行命令同理。
  • 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-master/examples/images/下可以看到生成的train.txt.

這裡寫圖片描述

開啟train.txt檔案

sudo gedit train.txt

如下圖:
這裡寫圖片描述

這裡生成的是train.txt,測試集test.txt和驗證集val.txt類似。
注意:這只是個樣例,所以資料和配置檔案都放在了一起。

方法2:直接使用程式碼

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

這裡寫圖片描述

執行以下命令

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

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

sudo gedit train.txt

如下圖:
這裡寫圖片描述

然後執行以下指令:

ls cat | sed "s:^:cat/:" | sed "s:$: 2:" >> train.txt

開啟train.txt,如下圖:
這裡寫圖片描述

程式碼解釋:

  • 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

這裡寫圖片描述

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

這裡寫圖片描述

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)
這裡寫圖片描述

注意:這個地方兩張圖片都在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=256 --resize_width=256 /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檔案

這裡寫圖片描述

這裡寫圖片描述

開啟img_train_lmdb,如下圖:
這裡寫圖片描述

ps:如果在終端直接開啟img_train_lmdb資料夾,會遇到許可權不夠問題,所以需要先執行下面指令,改變檔案許可權

sudo chmod 777 img_train_lmdb/

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

方法2:終端使用程式碼直接實現

資料儲存如下:
這裡寫圖片描述

終端輸入以下程式碼:


cd ~/caffe-master/examples/images

/home/heimu/caffe-master/build/tools/convert_imageset --resize_width=256 --resize_height=256 /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檔案中的路徑才是圖片的絕對路徑,切記切記!

結果如下圖:

這裡寫圖片描述
這裡寫圖片描述

至此生成了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,至此準備好了我們的資料,如下圖所示
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
注意:為了便於處理,應該將圖片統一命名,如上圖

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,而是將驗證集10張bird和10張cat一起放到了val資料夾下,這是上述方法的圖片資料的儲存格式。
變更之處:此處需要將val資料夾下新建兩個資料夾,bird和cat1(因為在程式碼中需要使用該資料夾名稱,而cat是Ubuntu中的一個指令,衝突),同時將train資料夾下的cat資料夾重新命名為cat1,將10張bird圖片放到bird資料夾下,10張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

執行結果如下圖

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

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=256 --resize_width=256 /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=256 --resize_height=256 /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

結果如下圖:
這裡寫圖片描述

這裡寫圖片描述

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

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