1. 程式人生 > >從零開始學caffe(九):在Windows下實現影象識別

從零開始學caffe(九):在Windows下實現影象識別

本系列文章主要介紹了在win10系統下caffe的安裝編譯,運用CPU和GPU完成簡單的小專案,文章之間具有一定延續性。

step1:準備資料集

資料集是進行深度學習的第一步,在這裡我們從以下五個連結中下載所需要的資料集:
animal
flower
plane
house
guitar

我們在原先的models資料夾下新建資料夾my_models_recognition,用於存放本文在實現影象識別過程中的相關檔案。我們之前下載的五個壓縮包包含animal、flower、plane、house和guitar五個類別。我們首先需要將其分成訓練集和測試集兩個部分,在這裡,我們採用手工的方法來製作資料集。

首先分別在train和test資料夾下新建五個類別的資料夾,用於存放每個類別的訓練集和測試集。
在這裡插入圖片描述
在這裡,我們設定訓練集的數目為500,測試集的數目為300,我們將每個分類的前500章圖片剪下到train資料夾的相應類別下,用於作為訓練集,剪下300張圖片到test的相應資料夾下作為測試集。至此,我們已經完成了資料集的準備工作。

step2:製作標籤

我們以“檔案路徑+標籤”的形式對每個影象進行命名,在這裡,如果我們繼續採用手工操作對影象標籤進行製作,這個過程需要耗費大量的時間。為此,我們在jupyter 中執行下列程式來幫助我們完成標籤製作。在執行程式之前先新建labels資料夾用於存放產生的標籤。

import os 

#定義Caffe根目錄
caffe_root = 'E:/caffe-windows/'

#製作訓練標籤資料
i = 0 #標籤
with open(caffe_root + 'models/my_models_recognition/labels/train.txt','w') as train_txt: 
    for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/train/'): #遍歷資料夾
        for dir in dirs:
            for
root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/train/'+str(dir)): #遍歷每一個資料夾中的檔案 for file in files: image_file = str(dir) + '\\' + str(file) label = image_file + ' ' + str(i) + '\n' #檔案路徑+空格+標籤編號+換行 train_txt.writelines(label) #寫入標籤檔案中 i+=1 #編號加1 #製作測試標籤資料 i=0 #標籤 with open(caffe_root + 'models/my_models_recognition/labels/test.txt','w') as test_txt: for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/test/'): #遍歷資料夾 for dir in dirs: for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/test/'+str(dir)): #遍歷每一個資料夾中的檔案 for file in files: image_file = str(dir) + '\\' + str(file) label = image_file + ' ' + str(i) + '\n' #檔案路徑+空格+標籤編號+換行 test_txt.writelines(label) #寫入標籤檔案中 i+=1#編號加1 print "成功生成檔案列表"

執行程式,輸出“成功生成檔案列表”,開啟labels資料夾,就可以在裡面分別找到train和test的標籤檔案。在這裡插入圖片描述
至此,我們也已經完成了標籤的製作過程。

step3:資料轉換

由於我們的資料集中圖片是png的形式,我們需要將其轉化為LMDB的格式,新建lmdb資料夾用於存放生成的lmdb檔案。

和之前我們講述的方法一樣,在這裡我們運用convert_imageset.exe來完成格式轉化。執行批處理檔案如下,對訓練集的影象進行格式轉換並打亂圖片順序:

%格式轉換的可執行檔案%
%重新設定影象大小%
%打亂圖片%
%轉換格式%
%圖片路徑%
%圖片標籤%
%lmdb檔案的輸出路徑%

E:\caffe-windows\Build\x64\Release\convert_imageset.exe ^
--resize_height=256  --resize_width=256 ^
--shuffle ^
--backend="lmdb" ^
E:\caffe-windows\models\my_models_recognition\data\train\ ^
E:\caffe-windows\models\my_models_recognition\labels\train.txt ^
E:\caffe-windows\models\my_models_recognition\lmdb\train\
pause

同理,執行如下程式修改測試集中的圖片格式。

%格式轉換的可執行檔案%
%重新設定影象大小%
%打亂圖片%
%轉換格式%
%圖片路徑%
%圖片標籤%
%lmdb檔案的輸出路徑%

E:\caffe-windows\Build\x64\Release\convert_imageset.exe ^
--resize_height=256  --resize_width=256 ^
--shuffle ^
--backend="lmdb" ^
E:\caffe-windows\models\my_models_recognition\data\test\ ^
E:\caffe-windows\models\my_models_recognition\labels\test.txt ^
E:\caffe-windows\models\my_models_recognition\lmdb\test\
pause

在這裡插入圖片描述

step5:修改網路引數檔案

在之前的文章中,我們使用過Googlenet,Googlenet適用於分類多,資料量大的情況,當資料集太小的時候容易出現過擬合現象(如本文只採用500個數據集),因此在這裡我們使用caffenet來完成影象的分類。
在這裡插入圖片描述
把上述檔案複製到my_models_recognition中,然後編輯網路引數檔案
在這裡,我們沒有使用均值檔案,因此將下列程式碼註釋掉

#  transform_param {
#   mirror: true
#    crop_size: 227
#    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"
#  }
# mean pixel / channel-wise mean instead of mean image

同理,還有下列程式碼:

#  transform_param {
#    mirror: false
#    crop_size: 227
#    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"
#  }
# mean pixel / channel-wise mean instead of mean image

將第25行batch size改為100
將293和333行num_output改為512
373行中,因為這裡我們只有五個類別,所以只需要5個輸出即可,將1000改為5

step6:修改超引數檔案

對超引數檔案中的路徑進行修改,最大迭代次數改為3000.,每500次迭代輸出一次model,並新建資料夾model,用於存放訓練得到的模型

net: "E:/caffe-windows/models/my_models_recognition/train_val.prototxt"
test_iter: 30
test_interval: 200
base_lr: 0.01
lr_policy: "step"
gamma: 0.1
stepsize: 1000
display: 50
max_iter: 3000
momentum: 0.9
weight_decay: 0.0005
snapshot: 500
snapshot_prefix: "E:/caffe-windows/models/my_models_recognition/model/"
solver_mode: GPU

step7:準備標籤

新建label檔案,在裡面放置物體的類別
在這裡插入圖片描述

step8:修改deploy Prototxt檔案

雖然在之前我們已經修改了網路結構檔案,但是在測試過程中我們使用的是deploy Prototxt檔案,因此我們對其進行同樣的修改:

181行和157行輸出改為512,第205行改為5.

step9:模型執行

執行批處理檔案如下:

%train訓練資料%
%超引數檔案%

E:\caffe-windows\Build\x64\Release\caffe.exe train ^
-solver=E:/caffe-windows/models/my_models_recognition/solver.prototxt ^
pause

在這裡插入圖片描述
(第一次進行訓練的時候是設定沒5次迭代輸出一次結構,第二次訓練改為500次訓練輸出一次結構,因此前面有那些第五次第十次之類,忽略即可)

step10:準備測試圖片

新建image資料夾,將我們要測試的圖片放置在其中:
在這裡插入圖片描述

step11:模型測試

在jupyter中執行如下程式碼:

import caffe
import numpy as np
import matplotlib.pyplot as plt
import os
import PIL
from PIL import Image
import sys

#定義Caffe根目錄
caffe_root = 'E:/caffe-windows/'
#網路結構描述檔案
deploy_file = caffe_root+'models/my_models_recognition/deploy.prototxt'
#訓練好的模型
model_file = caffe_root+'models/my_models_recognition/model/_iter_3000.caffemodel'

#gpu模式
#caffe.set_device(0)
caffe.set_mode_cpu()

#定義網路模型
net = caffe.Classifier(deploy_file, #呼叫deploy檔案
                       model_file,  #呼叫模型檔案
                       channel_swap=(2,1,0),  #caffe中圖片是BGR格式,而原始格式是RGB,所以要轉化
                       raw_scale=255,         #python中將圖片儲存為[0, 1],而caffe中將圖片儲存為[0, 255],所以需要一個轉換
                       image_dims=(227, 227)) #輸入模型的圖片要是227*227的圖片


#分類標籤檔案
imagenet_labels_filename = caffe_root +'models/my_models_recognition/labels/label.txt'
#載入分類標籤檔案
labels = np.loadtxt(imagenet_labels_filename, str)

#對目標路徑中的影象,遍歷並分類
for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/image/'):
    for file in files:
        #載入要分類的圖片
        image_file = os.path.join(root,file)
        input_image = caffe.io.load_image(image_file)

        #列印圖片路徑及名稱
        image_path = os.path.join(root,file)
        print(image_path)
        
        #顯示圖片
        img=Image.open(image_path)
        plt.imshow(img)
        plt.axis('off')
        plt.show()
        
        #預測圖片類別
        prediction = net.predict([input_image])
        print 'predicted class:',prediction[0].argmax()

        # 輸出概率最大的前5個預測結果
        top_k = prediction[0].argsort()[::-1]
        for node_id in top_k:     
            #獲取分類名稱
            human_string = labels[node_id]
            #獲取該分類的置信度
            score = prediction[0][node_id]
            print('%s (score = %.5f)' % (human_string, score))

執行程式碼即可輸出分類結果,我們發現模型的識別準確率非常高
在這裡插入圖片描述