导言
本教程中,我们将会利用Caffe官方提供的深度模型——CaffeNet(该模型是基于Krizhevsky等人的模型的)来演示图像识别与分类。我们将分别用CPU和GPU来进行演示,并对比其性能。然后深入探讨该模型的一些其它特征。
1、准备工作
1.1 首先,安装Python,numpy以及matplotlib。
#安装Python环境、numpy、matplotlib
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
#设置默认显示参数
plt.rcParams[\'figure.figsize\'] = (10, 10) # 图像显示大小
plt.rcParams[\'image.interpolation\'] = \'nearest\' # 最近邻差值: 像素为正方形
plt.rcParams[\'image.cmap\'] = \'gray\' # 使用灰度输出而不是彩色输出
1.2 然后,加载Load caffe。
# caffe模块要在Python的路径下;
# 这里我们将把caffe 模块添加到Python路径下.
import sys
caffe_root = \'../\' #该文件要从路径{caffe_root}/examples下运行,否则要调整这一行。
sys.path.insert(0, caffe_root + \'python\')
import caffe
# 如果你看到"No module named _caffe",那么要么就是你没有正确编译pycaffe;要么就是你的路径有错误。
说明:该步骤,本人是将编译好的pycaffe文件下的全部东西复制到Python的“site-packages”下的。所以不知道按上述做法具体会出现什么问题。
1.3 必要的话,需要事先下载“CaffeNet”模型,该模型是AlexNet的变形。
import os
if os.path.isfile(caffe_root + \'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel\'):
print \'CaffeNet found.\'
else:
print \'Downloading pre-trained CaffeNet model...\'
!../scripts/download_model_binary.py ../models/bvlc_reference_caffenet
说明:该步骤,本人是事先下载好”bvlc_reference_caffenet.caffemodel”,然后将其放在”caffe_root + ‘models/bvlc_reference_caffenet/”目录下面,因为用代码下载太慢了。
2、加载网络并设置输入预处理
2.1 将Caffe设置为CPU模式,并从硬盘加载网络。
caffe.set_mode_cpu()
model_def = caffe_root + \'models/bvlc_reference_caffenet/deploy.prototxt\'
model_weights = caffe_root + \'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel\'
net = caffe.Net(model_def, # 定义模型结构
model_weights, # 包含了模型的训练权值
caffe.TEST) # 使用测试模式(不执行dropout)
2.2 设置输入预处理(我们将用Caffe’s caffe.io.Transformer来进行预处理。不过该步骤与caffe的其它模块是相互独立的,所以任何预处理代码应该都是可行的)。我们使用的CaffeNet模型默认的输入图像格式是BGR格式的,其像素值位于[0,255]之间,同时每个像素值都减去了ImageNet图像的平均值。除此之外,通道的维数等于第一维(outermost)的大小。另外,因为matplotlib加载的图像的值位于[0,1]之间,并且格式是RGB格式,通道的维数等于innermost的维数,所以我们需要做一些变换(感觉这一段翻译的太烂),如下:
# 加载ImageNet图像均值 (随着Caffe一起发布的)
mu = np.load(caffe_root + \'python/caffe/imagenet/ilsvrc_2012_mean.npy\')
mu = mu.mean(1).mean(1) #对所有像素值取平均以此获取BGR的均值像素值
print \'mean-subtracted values:\', zip(\'BGR\', mu)
# 对输入数据进行变换
transformer = caffe.io.Transformer({\'data\': net.blobs[\'data\'].data.shape})
transformer.set_transpose(\'data\', (2,0,1)) #将图像的通道数设置为outermost的维数
transformer.set_mean(\'data\', mu) #对于每个通道,都减去BGR的均值像素值
transformer.set_raw_scale(\'data\', 255) #将像素值从[0,255]变换到[0,1]之间
transformer.set_channel_swap(\'data\', (2,1,0)) #交换通道,从RGB变换到BGR
3、用CPU分类
3.1 现在我们开始进行分类。尽管我们只对一张图像进行分类,不过我们将batch的大小设置为50以此来演示batching。
# 设置输入图像大小
net.blobs[\'data\'].reshape(50, # batch 大小
3, # 3-channel (BGR) images
227, 227) # 图像大小为:227x227
3.2 加载图像(caffe自带的)并进行预处理。
image = caffe.io.load_image(caffe_root + \'examples/images/cat.jpg\')
transformed_image = transformer.preprocess(\'data\', image)
plt.imshow(image)
plt.show()
O image.jpg $my_image_url # 变换图像并将其拷贝到网络 image = caffe.io.load_image(\'image.jpg\') net.blobs[\'data\'].data[...] = transformer.preprocess(\'data\', image) # 预测分类结果 net.forward() # 获取输出概率值 output_prob = net.blobs[\'prob\'].data[0] # 将softmax的输出结果按照从大到小排序,并提取前5名 top_inds = output_prob.argsort()[::-1][:5] plt.imshow(image) plt.show() print \'probabilities and labels:\' zip(output_prob[top_inds], labels[top_inds])