Caffe學習系列(20):用訓練好的caffemodel來進行分類


caffe程序自帶有一張小貓圖片,存放路徑為caffe根目錄下的 examples/images/cat.jpg, 如果我們想用一個訓練好的caffemodel來對這張圖片進行分類,那該怎么辦呢? 如果不用這張小貓圖片,換一張別的圖片,又該怎么辦呢?如果學會了小貓圖片的分類,那么換成其它圖片,程序實際上是一樣的。

開發caffe的賈大牛團隊,利用imagenet圖片和caffenet模型訓練好了一個caffemodel,  供大家下載。要進行圖片的分類,這個caffemodel是最好不過的了。所以,不管是用c++來進行分類,還是用python接口來分類,我們都應該准備這樣三個文件:

1、caffemodel文件。 

  可以直接在瀏覽器里輸入地址下載,也可以運行腳本文件下載。下載地址為:http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel

文件名稱為:bvlc_reference_caffenet.caffemodel,文件大小為230M左右,為了代碼的統一,將這個caffemodel文件下載到caffe根目錄下的 models/bvlc_reference_caffenet/ 文件夾下面。也可以運行腳本文件進行下載:

# sudo ./scripts/download_model_binary.py models/bvlc_reference_caffenet

2、均值文件。

有了caffemodel文件,就需要對應的均值文件,在測試階段,需要把測試數據減去均值。這個文件我們用腳本來下載,在caffe根目錄下執行:

# sudo sh ./data/ilsvrc12/get_ilsvrc_aux.sh

執行並下載后,均值文件放在 data/ilsvrc12/ 文件夾里。

3、synset_words.txt文件

在調用腳本文件下載均值的時候,這個文件也一並下載好了。里面放的是1000個類的名稱。

數據准備好了,我們就可以開始分類了,我們給大家提供兩個版本的分類方法:

一、c++方法

在caffe根目錄下的 examples/cpp-classification/ 文件夾下面,有個classification.cpp文件,就是用來分類的。當然編譯后,放在/build/examples/cpp_classification/ 下面

我們就直接運行命令:

# sudo ./build/examples/cpp_classification/classification.bin \
  models/bvlc_reference_caffenet/deploy.prototxt \
  models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel \
  data/ilsvrc12/imagenet_mean.binaryproto \
  data/ilsvrc12/synset_words.txt \
  examples/images/cat.jpg

命令很長,用了很多的\符號來換行。可以看出,從第二行開始就是參數,每行一個,共需要4個參數

運行成功后,輸出top-5結果:

---------- Prediction for examples/images/cat.jpg ----------
0.3134 - "n02123045 tabby, tabby cat"
0.2380 - "n02123159 tiger cat"
0.1235 - "n02124075 Egyptian cat"
0.1003 - "n02119022 red fox, Vulpes vulpes"
0.0715 - "n02127052 lynx, catamount"

即有0.3134的概率為tabby cat, 有0.2380的概率為tiger cat ......

二、python方法

python接口可以使用jupyter notebook來進行可視化操作,因此推薦使用這種方法。

在這里我就不用可視化了,編寫一個py文件,命名為py-classify.py

#coding=utf-8
#加載必要的庫
import numpy as np

import sys,os #設置當前目錄 caffe_root = '/home/xxx/caffe/' sys.path.insert(0, caffe_root + 'python') import caffe os.chdir(caffe_root) net_file=caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt' caffe_model=caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel' mean_file=caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy' net = caffe.Net(net_file,caffe_model,caffe.TEST) transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) transformer.set_transpose('data', (2,0,1)) transformer.set_mean('data', np.load(mean_file).mean(1).mean(1)) transformer.set_raw_scale('data', 255) transformer.set_channel_swap('data', (2,1,0)) im=caffe.io.load_image(caffe_root+'examples/images/cat.jpg') net.blobs['data'].data[...] = transformer.preprocess('data',im) out = net.forward() imagenet_labels_filename = caffe_root + 'data/ilsvrc12/synset_words.txt' labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t') top_k = net.blobs['prob'].data[0].flatten().argsort()[-1:-6:-1] for i in np.arange(top_k.size): print top_k[i], labels[top_k[i]]

執行這個文件,輸出:

281 n02123045 tabby, tabby cat
282 n02123159 tiger cat
285 n02124075 Egyptian cat
277 n02119022 red fox, Vulpes vulpes
287 n02127052 lynx, catamount

 caffe開發團隊實際上也編寫了一個python版本的分類文件,路徑為 python/classify.py

運行這個文件必需兩個參數,一個輸入圖片文件,一個輸出結果文件。而且運行必須在python目錄下。假設當前目錄是caffe根目錄,則運行:

# cd python
# sudo python classify.py ../examples/images/cat.jpg result.npy

分類的結果保存為當前目錄下的result.npy文件里面,是看不見的。而且這個文件有錯誤,運行的時候,會提示

Mean shape incompatible with input shape

的錯誤。因此,要使用這個文件,我們還得進行修改:

1、修改均值計算:

定位到 

mean = np.load(args.mean_file)

 這一行,在下面加上一行:

mean=mean.mean(1).mean(1)

 則可以解決報錯的問題。

2、修改文件,使得結果顯示在命令行下:

定位到

# Classify.
    start = time.time()
    predictions = classifier.predict(inputs, not args.center_only)
    print("Done in %.2f s." % (time.time() - start))

這個地方,在后面加上幾行,如下所示:

  # Classify.
    start = time.time()
    predictions = classifier.predict(inputs, not args.center_only)
    print("Done in %.2f s." % (time.time() - start))
    imagenet_labels_filename = '../data/ilsvrc12/synset_words.txt'
    labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')
    top_k = predictions.flatten().argsort()[-1:-6:-1]
    for i in np.arange(top_k.size):
        print top_k[i], labels[top_k[i]]

 就樣就可以了。運行不會報錯,而且結果會顯示在命令行下面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM