1. 程式人生 > >Caffe學習筆記(二):使用Python生成caffe所需的lmdb檔案和txt列表清單檔案

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目錄下。     最終結果執行如下,大功告成!