之前曾用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()]