之前曾用Matlab測試訓練好的model(詳細見:http://blog.csdn.net/sihailongwang/article/details/72700482),現在打算用Python測試訓練好的model,這裏用imagenet爲例。
step1:準備階段
1.這裏我們需要將編譯好的“pycaffe文件”複製到你的Python程序所在的文件夾下
2.將待測圖片也複製到該文件夾下
3.新建一個TXT文件(名爲synset_words.txt)(爲了將輸出的值映射到標籤時用)
4.根據train_val.prototxt,改寫所需要的deploy.prototxt
name: "CaffeNet"
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 10 dim: 3 dim: 227 dim: 227 } }
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
convolution_param {
num_output: 96
kernel_size: 11
stride: 4
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "norm1"
type: "LRN"
bottom: "pool1"
top: "norm1"
lrn_param {
local_size: 5
alpha: 0.0001
beta: 0.75
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "norm1"
top: "conv2"
convolution_param {
num_output: 256
pad: 2
kernel_size: 5
group: 2
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "norm2"
type: "LRN"
bottom: "pool2"
top: "norm2"
lrn_param {
local_size: 5
alpha: 0.0001
beta: 0.75
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "norm2"
top: "conv3"
convolution_param {
num_output: 384
pad: 1
kernel_size: 3
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "conv4"
type: "Convolution"
bottom: "conv3"
top: "conv4"
convolution_param {
num_output: 384
pad: 1
kernel_size: 3
group: 2
}
}
layer {
name: "relu4"
type: "ReLU"
bottom: "conv4"
top: "conv4"
}
layer {
name: "conv5"
type: "Convolution"
bottom: "conv4"
top: "conv5"
convolution_param {
num_output: 256
pad: 1
kernel_size: 3
group: 2
}
}
layer {
name: "relu5"
type: "ReLU"
bottom: "conv5"
top: "conv5"
}
layer {
name: "pool5"
type: "Pooling"
bottom: "conv5"
top: "pool5"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "fc6"
type: "InnerProduct"
bottom: "pool5"
top: "fc6"
inner_product_param {
num_output: 4096
}
}
layer {
name: "relu6"
type: "ReLU"
bottom: "fc6"
top: "fc6"
}
layer {
name: "drop6"
type: "Dropout"
bottom: "fc6"
top: "fc6"
dropout_param {
dropout_ratio: 0.5
}
}
layer {
name: "fc7"
type: "InnerProduct"
bottom: "fc6"
top: "fc7"
inner_product_param {
num_output: 4096
}
}
layer {
name: "relu7"
type: "ReLU"
bottom: "fc7"
top: "fc7"
}
layer {
name: "drop7"
type: "Dropout"
bottom: "fc7"
top: "fc7"
dropout_param {
dropout_ratio: 0.5
}
}
layer {
name: "fc8"
type: "InnerProduct"
bottom: "fc7"
top: "fc8"
inner_product_param {
num_output: 1000
}
}
layer {
name: "prob"
type: "Softmax"
bottom: "fc8"
top: "prob"
}
step2:均值文件轉換(.binaryproto轉.py):
# encoding: utf-8
#!/usr/bin/python
import sys
caffe_root = '../PythonCode/' #該文件要從路徑{caffe_root}/examples下運行,否則要調整這一行。
sys.path.insert(0, caffe_root + 'pycaffe')
import caffe
import numpy as np
MEAN_PROTO_PATH = 'mean.binaryproto' # 待轉換的binaryproto圖像均值文件路徑
MEAN_NPY_PATH = 'mean.npy' # 轉換後的npy圖像均值文件路徑
blob = caffe.proto.caffe_pb2.BlobProto() # 創建protobuf blob
data = open(MEAN_PROTO_PATH, 'rb' ).read() # 讀入mean.binaryproto文件內容
blob.ParseFromString(data) # 解析文件內容到blob
array = np.array(caffe.io.blobproto_to_array(blob))# 將blob中的均值轉換成numpy格式
mean_npy = array[0] # 一個array中可以有多組均值存在,故需要通過下標選擇其中一組均值
np.save(MEAN_NPY_PATH ,mean_npy)
step3:核心程序:
# encoding: utf-8
#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
import sys
caffe_root = '../python/'
sys.path.insert(0, caffe_root + 'pycaffe') #指定到caffe所在的路徑下
import caffe
import os
if os.path.isfile(caffe_root + 'bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'):
print 'It is OK !'
else:
print 'Please download this model'
caffe.set_mode_cpu()
model_def = caffe_root + 'bvlc_reference_caffenet/deploy.prototxt'
model_weights = caffe_root + 'bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'
net = caffe.Net(model_def, # 定義模型結構
model_weights, # 包含了模型的訓練權值
caffe.TEST) # 使用測試模式
#加載均值文件(注意是npy格式的)
mu = np.load(caffe_root + 'caffe/imagenet/ilsvrc_2012_mean.npy')
mu = mu.mean(1).mean(1)
print 'mean-subtracted values:', zip('BGR', mu)
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))
#設置輸入圖像大小
net.blobs['data'].reshape(50, # batch 大小
3, # 3-channel (BGR) images
227, 227) # 圖像大小爲:227x227
image = caffe.io.load_image(caffe_root + '../examples/images/cat.jpg')
transformed_image = transformer.preprocess('data', image)
plt.imshow(image)
plt.show()
# 將圖像數據放入到net中
net.blobs['data'].data[...] = transformed_image
#進行分類測試
output = net.forward()
output_prob = output['prob'][0]
print 'predicted class is:', output_prob.argmax()
#映射到標籤中
labels_file = caffe_root + '../python/synset_words.txt'
if not os.path.exists(labels_file):
print'This file is not be found'
labels = np.loadtxt(labels_file, str, delimiter='\t')
print 'output label:', labels[output_prob.argmax()]