【用Python學習Caffe】1. 使用Caffe完成圖像分類

1. 使用Caffe完成圖像分類

本節將以著名的圖像分類深度學習網絡AlexNet爲例子,通過Python Caffe來進行圖像分類。雖然不同的網絡的結構是不樣的,但其大體的過程都是一致的,因此大家可以通過這個例子,熟悉如何利用Caffe進行圖像分類。

關於AlexNet的原理,可以參見其論文:Krizhevsky A, Sutskever I, Hinton G E. Imagenet classification with deep convolutional neural networks[C]. In Proc. Advances in Neural Information Processing Systems (NIPS). 2012: 1097-1105.

基於深度學習的圖像分類網絡,一般是將原始圖像經過深度網絡後,最後將得到一組向量,這組向量的長度等於分類種類的數目,向量中每個值對應於該圖像在相應的分類種類下的概率。因此通常的情況將向量最大值對應的序號視爲最可能的分類。

1.1 準備文件

  • deploy.prototxt: 網絡結構配置文件
  • bvlc_alexnet.caffemodel: 網絡權重文件
  • synset_words.txt: 分類名稱
  • 測試圖像

本文的AlexNet是在ilsvrc12下進行訓練的,bvlc_alexnet.caffemodel是在該數據庫下訓練得到的權重文件,而synset_words.txt也是該數據庫下的分類種類名稱,該文件的每一行代表一種類,每一種類可能會有多個相似的名稱,當然近似名稱並不重要,但要知道每一行代表一類,行號則代表其在網絡最終輸出向量的序號,舉個例子,比如說,如果最終輸出向量的第50個值最大,則代表該圖像的分類爲synset_words.txt第50行表示的分類。

1.2 加載網絡


    caffe_root = '../../'
    # 網絡參數(權重)文件
    caffemodel = caffe_root + 'models/bvlc_alexnet/bvlc_alexnet.caffemodel'
    # 網絡實施結構配置文件
    deploy = caffe_root + 'models/bvlc_alexnet/deploy.prototxt'
    net = caffe.Net(deploy,  # 定義模型結構
                    caffemodel,  # 包含了模型的訓練權值
                    caffe.TEST)  # 使用測試模式(不執行dropout)

1.3 測試圖像預處理

預處理主要包含兩個部分:

  1. 減去均值
  2. 調整大小

    # 加載ImageNet圖像均值 (隨着Caffe一起發佈的)
    mu = np.load(caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy')
    mu = mu.mean(1).mean(1)  # 對所有像素值取平均以此獲取BGR的均值像素值

    # 圖像預處理
    transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
    transformer.set_transpose('data', (2,0,1))
    transformer.set_mean('data', mu)
    transformer.set_raw_scale('data', 255)
    transformer.set_channel_swap('data', (2,1,0))

1.4 運行網絡

  1. 導入輸入數據
  2. 通過forward()運行結果

    # 加載圖像
    im = caffe.io.load_image(img)
    # 導入輸入圖像
    net.blobs['data'].data[...] = transformer.preprocess('data', im)

    start = time.clock()
    # 執行測試
    net.forward()
    end = time.clock()
    print('classification time: %f s' % (end - start))

1.5 查看分類結果

用於圖像分類的網絡的最後一層一般是一個名爲’prob’的SoftMax網絡,這個名爲’prob’層的輸出即爲反應該圖像在各分類下的概率向量。而prob層的輸出Blob也名爲prob

    layer {
      name: "prob"
      type: "Softmax"
      bottom: "ip2"
      top: "prob" # 輸出Blob
    }

因此我們可以通過net.blobs['prob']確定最終的輸出結果。找到該向量的最大值即可確定最可能的分類,當然對於圖像可能存在多個目標的情況下,可以提取最大概率的多個分類。


    # 查看目標檢測結果
    # 加載分類名稱文件
    labels = np.loadtxt(synset_words, str, delimiter='\t')
    # 得到分類網絡的最終結果
    category = net.blobs['prob'].data[0].argmax() # 最大概率的分類
    # 得到分類名稱
    class_str = labels[int(category)].split(',')
    class_name = class_str[0]
    # 在圖像中標記分類名稱
    cv2.putText(im, class_name, (0, im.shape[0]), cv2.cv.CV_FONT_HERSHEY_SIMPLEX, 1, (55, 255, 155), 2)

1.6 分類結果展示

1.7 具體代碼下載

GitHub倉庫Caffe-Python-Tutorial中的classification.py

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章