1. 程式人生 > >使用訓練好的Caffemodel 網路進行分類

使用訓練好的Caffemodel 網路進行分類

在之前的部落格裡我已經寫過 CaffeModel的檔案了,這個就是我們訓練的網路結果。

現在既然已經有了訓練好的模型,就要開始通過這個網路進行自己的分類了。

準備內容

  1. 首先找到訓練好的 .caffemodel檔案。
  2. 然後準備網路模型的 deploy.prototxt
  3. 準備訓練時候使用的均值檔案imagenet_mean.binaryproto
  4. 新建一個label.txt檔案裡面寫上你的各個類的名字(注意順序)
  5. 要分類的檔案:1.jpg

解釋一下 deploy.prototxt檔案並不是你訓練的時候使用的 train_val.prototxt

檔案,因為是分類所以deploy.prototxt把訓練的內容部分全部給刪除了。所以如果沒有deploy.prototxt的話,請自己寫一份,仿照其他網路的樣例。

其次binaryproto檔案是訓練時候使用的均值檔案,不是分類生成的。

然後就是label.txt就是標籤檔案,裡面每行是一個內容,我的標籤檔案裡面是:

down
sitdown
standup
handup
1
2
3
.
.
.
996

我這裡面一共有4類,但是有1000行,是因為我訓練的時候忘了修改train_val.prototxt裡面的輸出向量的大小了。所以用數字替補了。如果你訓練的時候修改過train_val.prototxt

inner_product_paramnum_output的值,那麼對應的你這個標籤檔案裡也寫多少行就可以了。然後deploy.prototxt也要一樣。

分類

Caffe可以通過 C++方法也可以通過 Python方法或者直接命令列方法來分類,我自己只測試了使用 C++的方法

C++方法分類

在 caffe下面有寫好的 C++檔案:

caffe/build/examples/cpp_classification/classification.bin

這個是編譯好的 classification.bin的可執行檔案,其原始碼在:

caffe/examples/cpp_classification/classification.cpp

如果要修改,在這裡修改之後編譯。

然後在caffe根目錄下新建一個classification_test.sh檔案,裡面的內容如下:

#!/bin/bash
./build/examples/cpp_classification/classification.bin \
    examples/imgsnet/bvlc_alexnet/deploy.prototxt \
    examples/imgsnet/bvlc_alexnet/caffe_alexnet_train_iter_1000.caffemodel \
    examples/imgs/data/imagenet_mean.binaryproto \
    examples/imgs/data/label.txt \
    examples/imgs/data/val/down/1.jpg

這裡的檔案位置,請自行指定,我這個檔案裡面的位置都是我網路的。

然後會輸出類似的內容:

---------- Prediction for examples/imgs/data/val/down/20170309_163509_down.jpg ----------
0.9756 - "down"
0.0229 - "sitdown"
0.0016 - "standup"
0.0000 - "handup"
0.0000 - "59"

前面是概率,後面是對應的 label,輸出的 top 5的預測。

錯誤解決

問題1:

F0329 12:55:18.108248  8610 classification.cpp:82] Check failed: labels_.size() == output_layer->channels() (4 vs. 1000) Number of labels is different from the output layer dimension.

說明你label.txt的內容長度和 deploy.prototxt的長度不一致,說lebel.txt的長度是4而deploy.prototxt裡的 output_num的內容長度是1000. 這裡的解決辦法是,其中一個改成一樣的長度就行了。

問題2:

F0329 15:48:14.703812  9905 net.cpp:757] Cannot copy param 0 weights from layer 'fc8'; shape mismatch.  Source param shape is 1000 4096 (4096000); target param shape is 4 4096 (16384). To learn this layer's parameters from scratch rather than copying from a saved net, rename the layer.

這個問題說的是你網路訓練的檔案train_val.prototxt裡的output_numdeploy.prototxtoutput_num長度不一致。

所以我最後的解決辦法就是,把所有長度以train_val.prototxt的寫的輸出向量長度為準。