1. 程式人生 > >Caffe:利用訓練好的模型進行分類

Caffe:利用訓練好的模型進行分類

    以大神訓練好的模型為基礎,利用自己的資料進行了finetune之後,下一步就可以真正使用模型來進行分類操作了。具體步驟如下:

    1. 編輯分類網路的配置檔案deploy.prototxt

    deploy檔案是真正使用模型時候用的,其結構與train_val.prototxt基本上是一樣的,只是輸入和輸出模組有區別。因此,可以直接把train_val.prototxt拷貝一份,改名為deploy.prototxt,並對其進行編輯:

    (1)輸入模組

    把其中的data層刪除(一般有兩個,一個用於train,一個用於test),新增一個Input層,一般引數如下:

layer{
  name: "data"
  type: "Input"
  top: "data"
  input_param{
    shape: { dim: 1 dim: 3 dim: 227 dim: 227}
  }
}

    需要注意的是,top引數要和後面的cov1的bottom一樣,才能把網路連線上;其次,shape是輸入的圖片的shape,可以在呼叫caffe的程式碼中進行修改。

    (2)輸出模組

    刪除Accuracy層和SoftmaxWithLoss層,新建一個Softmax層,一般引數如下:

layer {
  name: "prob"
  type: "Softmax"
  bottom: "fc8"
  top: "prob"
}

    其中,bottom引數為上面的網路中最後一層的top(一般為全連線層)

    2.圖片資訊預處理

    在輸入到網路之前,需要對圖片進行預處理,如減去均值等。具體步驟如下:

    (1)轉換均值檔案格式

    因為訓練時生成的mean檔案是通過caffe自帶的工具生成的,是C++使用的格式,使用python介面使用caffe需要先將其轉化為npy格式。指令碼程式碼如下:

path =  '/Users/Coder/caffe/examples/my_file/'
blob = caffe.proto.caffe_pb2.BlobProto()
data = open(path + 'mean.binaryproto' , 'rb' ).read()
blob.ParseFromString(data)
arr = np.array( caffe.io.blobproto_to_array(blob) )
out = arr[0]
np.save(path + 'mean.npy' , out )

    (2)圖片格式化    

    python中讀入的圖片與caffe中需要的並不一致,因此需要進行格式化

mu = np.load(my_path + 'mean.npy')
mu = mu.mean(1).mean(1)

transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) #shape要與net中data的shape一致
transformer.set_transpose('data', (2, 0, 1)) #caffe.io.load_image讀取jpg圖片時,第三維是channel,需要把channel換到第一維
transformer.set_mean('data', mu) #減去均值
transformer.set_raw_scale('data', 255) #python中將圖片儲存為[0, 1],而caffe中將圖片儲存為[0, 255],所以需要一個轉換
transformer.set_channel_swap('data', (2, 1, 0)) #python的圖片是RGB格式,而caffe中的是BGR格式,需要進行轉置

    3. 載入模型,進行分類

    載入模型的網路和訓練好的引數,把圖片輸入,進行分類

    載入模型:

my_path = '/Users/Coder/caffe/examples/my_file/'
caffe.set_mode_cpu() #如果只使用CPU,需要這一行,如果使用GPU,則設為GPU
model_def = my_path + 'deploy.prototxt'   #模型配置檔案
model_weights = my_path + 'minemodel/solver_iter_200.caffemodel' #訓練好的引數
net = caffe.Net(model_def, model_weights, caffe.TEST)

    輸入圖片,執行分類:

img = caffe.io.load_image('/Users/Coder/caffe/data/re/test/409.jpg') #載入圖片,進行預處理
transformed_img = transformer.preprocess('data', img)

net.blobs['data'].reshape(1, 3, 227, 227) # 修改net的data的格式,使之與輸入匹配(可以修改第一個引數,進行批處理)
net.blobs['data'].data[...] = transformed_img #輸入
output = net.forward() #分類

output_prob = output['prob'][0] #讀取分類結果
print 'predicted class is: ', output_prob.argmax()