您的位置:首页 > 编程语言 > Python开发

【caffe源码研究】第二章:使用篇(4) : python接口

2016-12-23 12:16 791 查看
本小节介绍一下python的使用接口。python接口的调用需要在编译正确python接口的环境下,详见安装篇。

make pycaffe


一、画网络结构图

使用python接口的draw_net.py可以将提供的网络结构画出图像。

首先,需要安装graphviz,源码安装,yum源安装,jumbo安装等等都可以。

这里讲一下源码安装。

graphviz源码安装暂留

然后安装pydot,直接使用pip安装即可

pip install pydot


然后可以使用draw_net.py来画网络图,如下

draw_net.py执行的时候带三个参数

第一个参数:网络模型的prototxt文件

第二个参数:保存的图片路径及名字

第三个参数:–rankdir=x , x 有四种选项,分别是LR, RL, TB, BT 。用来表示网络的方向,分别是从左到右,从右到左,从上到小,从下到上。默认为LR。

python draw_net.py ../examples/cifar10/cifar10_quick_train_test.prototxt cifa10.png


画出来的网络图如下



二、python接口

Python接口应用的很广泛,主要是简单易用。

写一个预测数字的python代码

predict_num.py代码如下:

__author__ = 'frank'
import os
import numpy as np
import matplotlib.pyplot as plt
import sys
import caffe

caffe_root = '/home/thirdparty/caffe-master/'
import sys
sys.path.append(caffe_root + 'python')

Path = "F:/caffe/data/"

# load mean file
mean_filename = Path+'image_mean.binaryproto'
proto_data = open(mean_filename, "rb").read()
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)
mean  = caffe.io.blobproto_to_array(a)[0]

#load pretrain file
pretrained_file = Path+'lenet_iter_10000.caffemodel'

#load modle file
model_file = Path+'deploy.prototxt'

#create caffe net
numReg_net = caffe.Classifier(model_file, pretrained_file,
mean = mean,
channel_swap=(2,1,0),
raw_scale=255,
image_dims=(32, 32))

#labels
list=['0','1','2','3','4','5','6','7','8','9']

image_path = Path + 'trainData/7/7-5-IFPYM1SLG8.jpg'
test_image = caffe.io.load_image(image_path)
plt.imshow(test_image)
plt.show()
prediction = numReg_net.predict([test_image])

print 'predictions:', prediction[0]  #list[prediction[0].argmax()]
print 'predicted num:', list[prediction[0].argmax()]


运行结果

predictions: [ 0.   0.5  0.   0.   0.   0.   0.   0.5  0.   0. ]
predicted num: 1


试了好几次,每次都是输出两个概率为0.5的数字。后来经过调试,发现问题在于predict函数定义为

def predict(self, inputs, oversample=True):
"""
Predict classification probabilities of inputs.

Parameters
----------
inputs : iterable of (H x W x K) input ndarrays.
oversample : boolean
average predictions across center, corners, and mirrors
when True (default). Center-only prediction when False.

Returns
-------
predictions: (N x C) ndarray of class probabilities for N images and C
classes.
"""


其中有一个默认参数oversample,如果将其值设为True,则会将图像从中心,边界取图,做镜像翻转,然后预测之后取平均值。这里做数字预测肯定是不能开启这个选项的!

修改代码为

prediction = numReg_net.predict([test_image],False)


再次运行即得到正确结果

predictions: [ 0.  0.  0.  0.  0.  0.  0.  1.  0.  0.]
predicted num: 7


三、python预测

python接口是对函数进行了封装,这部分不使用封装好的函数,直接用python进行预测。其实本质就是Classifier和predict函数。

一个实例如下

# -*- coding:utf-8 -*-

__author__ = 'fangjin'

import numpy as np           #调用numpy模块,调用名称为np
import matplotlib.pyplot as plt #调用matplotlib.pyplot模块,调用名称为plt
import sys
import caffe

ImageEqulity_root = 'D:/data/'   #caffe根目录

model_file = ImageEqulity_root + 'lenet_deploy.prototxt'  #CaffeNet网络结构
pretrained = ImageEqulity_root + 'lenet_iter_10000.caffemodel'   #参数文件
image_file = ImageEqulity_root+'testData/4/4-3-0Z5FN38C0Q.jpg'     #测试数据
mean_filename = ImageEqulity_root + 'image_mean.binaryproto'

#npload = ImageEqulity_root + '/python/caffe/imagenet/ilsvrc_2012_mean.npy'    #计算平均值

# 显示图像模块
plt.rcParams['figure.figsize'] = (10, 10)       # 显示图标大小为10
plt.rcParams['image.interpolation'] = 'nearest'     # 图形差值以最近为原则
plt.rcParams['image.cmap'] = 'gray'        #背景颜色为灰色

IMAGE_SIZE = (32, 32)
MEAN_VALUE = 128

caffe.set_mode_cpu()
net = caffe.Net(model_file, pretrained, caffe.TEST)

proto_data = open(mean_filename, "rb").read()
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)
mean  = caffe.io.blobproto_to_array(a)[0]

transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))
# transformer.set_channel_swap('data',(2,1,0)) # 参考模型通道为BGR,需转换成RGB,括号中的数字表示排列顺序
#transformer.set_mean('data', np.array([MEAN_VALUE]))
#transformer.set_mean('data', mean)
transformer.set_raw_scale('data', 255)

image = caffe.io.load_image(image_file, True)

# net.blobs['data'].reshape(1, 3, 100, 100)
# net.blobs['data'].reshape(1, 3, *IMAGE_SIZE) # reshaoe

transformed_image = transformer.preprocess('data',image)#读取文件

net.blobs['data'].data[...]=transformed_image
out = net.forward()
score = out['prob'][0]

num_list=['0','1','2','3','4','5','6','7','8','9']
print "Predicted class is : " ,score
print 'predicted num:', num_list[score.argmax()]


主要是定义了一个Transformer,对图像进行预处理。然后通过
out = net.forward()
进行前向计算,之后
score = out['prob'][0]
输出prob层的结果就可以了,因为只有一张图像,所以是
out['prob'][0]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python