1. 程式人生 > >caffe----訓練自己的圖片caffenet模型

caffe----訓練自己的圖片caffenet模型

    學習的caffe的目的,不是簡單的做幾個練習,而是最終落實到自己的專案或科研中去。因此,本文介紹一下,從自己的原始圖片到lmdb資料,再到訓練和測試的整個流程。

一、資料的準備

    有條件的同學,可以去ImageNet的官網點選開啟連結,下載ImageNet圖片來訓練。但是我沒有下載,因為我註冊過程中一直出現bug。哭

    也可以去這個網盤點選開啟連結下載影象資料,包括手寫數字.jpg,手寫數字.csv,人臉檢測正負樣本224*224,image.zip,.CASIA-WebFace.zip

    我重新找了500張圖片來代替,分為大巴車、恐龍、大象、鮮花和馬五個類,每個類100張。需要的同學,可以去這個網盤下載

點選開啟連結

    編號分別以3,4,5,6,7開頭,各為一類。我從其中每類選出20張作為測試,其餘80張作為訓練。因此最終訓練圖片400張,測試圖片100張,共5類。我將圖片放在caffe根目錄下的data檔案下。即訓練圖片目錄:caffe/data/re/train/,測試圖片目錄:caffe/data/re/test/

二、轉換為lmdb格式

   1、 在根目錄caffe下,首先在examples下面建立一個myfile的資料夾,來用存放配置檔案和指令碼檔案。然後編寫一個指令碼create_filelist.sh,用來生成train.txt和test.txt清單檔案

   #sudo mkdir examples/myfile

    #sudo vi examples/myfile/create_filelist.sh

    編輯create_filelist.sh檔案,並寫入如下程式碼,並儲存。目錄不要寫錯

 #!/usr/bin/env sh
    DATA=/home/hyb/caffe/data/re/
    MY=/home/hyb/caffe/examples/myfile


    echo "Create train.txt..."
    rm -rf $MY/train.txt
    for i in 3 4 5 6 7 
    do
    find $DATA/train -name $i*.jpg | cut -d '/' -f9 | sed "s/$/ $i/">>$MY/train.txt
    done
    echo "Create test.txt..."
    rm -rf $MY/test.txt
    for i in 3 4 5 6 7
    do
    find $DATA/test -name $i*.jpg | cut -d '/' -f9 | sed "s/$/ $i/">>$MY/test.txt
    done
    echo "All done"


注: 這個指令碼檔案中,用到了rm,find,cut,sed,cat等Linux命令

    rm:刪除檔案

    find:尋找檔案

    cut :擷取路徑

    sed:在每行的最後面加上標註。本例中將找到的“i*.jpg”檔案加入標註為i,比如“3*.jpg”標註為3

    cat:將兩個類別合併在一個檔案裡。

       其中f-9指的是第9個目錄下

然後,執行此指令碼

    #sudo sh examples/myfile/create_filelist.sh

成功的話,就會在examples/myfile/檔案下生成train.txt和test.txt兩個文字檔案,裡面就是圖片的列表清單

    開啟train.txt可以看到如下內容,同樣test.txt檔案裡面的內容也是如此,二者僅數量不同。

    注:在此處,我們手動的通過查詢替換功能,將train.txt檔案和test.txt檔案裡面的圖片編號依次由3,4,5,6,7改為0,1,2,3,4。之所以要改編號的原因是,編號從3~7會影響訓練精度。修改完後,train.txt內容如下圖所示

;

    由於上述生成的train.txt檔案和test.txt檔案是加許可權檔案,因此需要修改許可權,以方面修改。linux命令為:chmod a+w examples/myfile/train.txt

    2、接著再編寫一個指令碼檔案,呼叫convert_imageset命令來轉換資料格式

   #sudo vi examples/myfile/create_lmdb.sh

插入:

    #!/usr/bin/env sh
    MY=/home/hub/caffe/examples/myfile


    echo "Create train lmdb.."
    rm -rf $MY/img_train_lmdb
    build/tools/convert_imageset \
    --shuffle \
    --resize_height=256 \
    --resize_width=256 \
    /home/hub/caffe/data/re/ \
    $MY/train.txt \
    $MY/img_train_lmdb


    echo "Create test lmdb.."
    rm -rf $MY/img_test_lmdb
    build/tools/convert_imageset \
    --shuffle \
    --resize_width=256 \
    --resize_height=256 \
    /home/hyb/caffe/data/re/ \
    $MY/test.txt \
    $MY/img_test_lmdb


    echo "All Done.."

    注:程式碼中的shuffle為,打亂圖片順序。/home/xxx/caffe/data/re為下載的影象資料儲存的絕對路徑。

最後,執行這個指令碼

   #sudo sh examples/myfile/create_lmdb.sh

    因為圖片大小不一,因此統一轉換成256*256大小。執行成功後,會在examples/myfile下面生成兩個img_test_lmdb和img_train_lmdb,分別用於儲存圖片轉換後的lmdb檔案。

三、計算均值並儲存

   圖片減去均值再訓練,會提高訓練速度和精度。因此,一般都會有這個操作。

    caffe程式提供了一個計算均值的檔案compute_image_mean.cpp,我們直接使用就可以了

   #sudo build/tools/compute_image_mean examples/myfile/img_train_lmdb examples/myfile/mean.binaryproto

compute_image_mean帶兩個引數,第一個引數時lmdb訓練資料位置,第二個引數設定均值檔案的名字及儲存路徑。

    執行成功後,如下圖所示

    

四、建立模型並編寫配置檔案

模型就用程式自帶的caffenet模型,位置在caffe/models/bvlc_reference_caffenet/資料夾下,將需要的兩個配置檔案,複製到myfile資料夾內

#sudo cp models/bvlc_reference_caffenet/solver.prototxt examples/myfile/

    #sudo cp models/bvlc_reference_caffenet/train_val.prototxt examples/myfile/

修改其中的solver.prototxt

    #sudo vi examples/myfile/solver.prototxt

輸入以下內容:

     net: "examples/myfile/train_val.prototxt"
     test_iter: 2
     test_interval: 50
     base_lr: 0.001
     lr_policy: "step"
    gamma: 0.1
    stepsize: 100
    display: 20
    max_iter: 500
    momentum: 0.9
    weight_decay: 0.005
    solver_mode: GPU

 注:電腦沒有GPU的同學,solver_mode:CPU

100個測試資料,batch_size為50,因此test_iter設定為2,就能全覆蓋了。在訓練過程中,調整學習率,逐步變小。

修改train_val.prototxt,只需要修改兩個階段的data層就可以了,其他可以不用管。

    name: "CaffeNet"
    layer {
        name: "data"
        type: "Data"
        top: "data"
        top: "label"
    include {
        phase: TRAIN
    }
    transform_param {
        mirror: true
        crop_size: 227
        mean_file: "examples/myfile/mean.binaryproto"
     }
    data_param {
        source: "examples/myfile/img_train_lmdb"
        batch_size: 256
        backend: LMDB
     }
    }
     layer {
         name: "data"
         type: "Data"
         top: "data"
         top: "label"
     include {
         phase: TEST
     }
     transform_param {
         mirror: false
         crop_size: 227
         mean_file: "examples/myfile/mean.binaryproto"
     }
     data_param {
         source: "examples/myfile/img_test_lmdb"
         batch_size: 50
         backend: LMDB
    }
   }

  實際上就是修改兩個data layer的mean_file和source這兩個地方,其他都沒有變化。

五、訓練

如果前面都沒有問題,資料準備好了,配置檔案也配置好了,這一步就比較簡單了。

 #sudo build/tools/caffe train -solverexamples/myfile/solver.prototxt

 執行時間和最後的精度,會根據機器配置,引數設定的不同而不同。我的機器執行500次,大約15分鐘左右,精度為95%。如下圖所示:

    

    注:執行時,可能會出現以下問題


    原因:由圖可以看出,出現問題的上面一行提示loading mean file from:data/ilsvrc12/imagenet_mean.binaryproto,說明載入均值檔案時,路徑出現問題。

 解決方法:因為訓練時,我們用到兩個指令碼檔案solver.prototxt和train_val.prototxt檔案。所以首先,我們檢視solver.prototxt檔案,看看第一句net:"examples/myfile/train_val.prototxt"裡面的地址對不對(本文的問題就出在這裡,it works after fixed.).如果還沒有解決,繼續檢視train_val.prototxt檔案裡面的data路徑,建議都寫成絕對路徑。畢竟caffe裡面大部分問題都是由路徑不對引起的。