导言

本教程中,我们将会利用Caffe官方提供的深度模型——CaffeNet(该模型是基于Krizhevsky等人的模型的)来演示图像识别与分类。我们将分别用CPU和GPU来进行演示,并对比其性能。然后深入探讨该模型的一些其它特征。

1、准备工作

1.1 首先,安装Python,numpy以及matplotlib。

 #安装Python环境、numpy、matplotlibimport numpy as npimport 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 osif 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) images227, 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()

说明:这里的”plt.show()”是我自己加的,不加的话没法显示图像。

3.3 接下来,开始进行识别分类

# 将图像数据拷贝到为net分配的内存中net.blobs['data'].data[...] = transformed_image### 执行分类output = net.forward()  output_prob = output['prob'][0]  #batch中第一张图像的概率值   print 'predicted class is:', output_prob.argmax()

predicted class is: 281

网络输出是一个概率向量;最可能的类别是第281个类别。但是结果是否正确呢,让我们来查看一下ImageNet的标签。

    # 加载ImageNet标签labels_file = caffe_root + 'data/ilsvrc12/synset_words.txt'if not os.path.exists(labels_file):!../data/ilsvrc12/get_ilsvrc_aux.shlabels = np.loadtxt(labels_file, str, delimiter='\t')print 'output label:', labels[output_prob.argmax()]

说明:ImageNet标签文件(synset_words.txt)需要自己下载

output label: n02123045 tabby, tabby cat

”Tabby cat”是正确的,然后我们再来看下其它几个置信的较高的结果。

# sort top five predictions from softmax outputtop_inds = output_prob.argsort()[::-1][:5]  # reverse sort and take five largest itemsprint 'probabilities and labels:'zip(output_prob[top_inds], labels[top_inds])

probabilities and labels:

[(0.31243637, 'n02123045 tabby, tabby cat'),(0.2379719, 'n02123159 tiger cat'),(0.12387239, 'n02124075 Egyptian cat'),(0.10075711, 'n02119022 red fox, Vulpes vulpes'),(0.070957087, 'n02127052 lynx, catamount')]

我们可以看出,较低置信度的结构也是合理的。

4、GPU模式

4.1 让我们先看下CPU的分类时间,然后再与GPU进行比较。

    %timeit net.forward()

1 loop, best of 3: 1.42 s per loop

还是需要一段时间的,即使是对批量的50张图像。然后,让我们看下GPU模式下的运行时间。

caffe.set_device(0)  # 如果你有多个GPU,那么选择第一个
caffe.set_mode_gpu()
net.forward()  # run once before timing to set up memory
%timeit net.forward()

10 loops, best of 3: 70.2 ms per loop

这下就快多了。

5、测试网络的中间层输出

我们的网络不单单是一个黑盒子。接下来,我们来看下该模型的一些参数和一些中间输出。首先,我们来看下如何读取网络的结构(每层的名字以及相应层的参数)。对于每一层,其结构构成为:(batch_size, channel_dim, height, width)。

# 对于每一层,显示输出类型。for layer_name, blob in net.blobs.iteritems():print layer_name + '\t' + str(blob.data.shape)data    (50, 3, 227, 227)conv1   (50, 96, 55, 55)pool1   (50, 96, 27, 27)norm1   (50, 96, 27, 27)conv2   (50, 256, 27, 27)pool2   (50, 256, 13, 13)norm2   (50, 256, 13, 13)conv3   (50, 384, 13, 13)conv4   (50, 384, 13, 13)conv5   (50, 256, 13, 13)pool5   (50, 256, 6, 6)fc6 (50, 4096)fc7 (50, 4096)fc8 (50, 1000)prob    (50, 1000)

现在,我们来看下参数的形状。参数是OrderdDict类型,net.params。我们根据索引来访问参数。[0]:表示weights,[1]:表示biases。

参数形状的构成为:

(output_channels, input_channels, filter_height, filter_width)为weights;(output_channels,)为biases。

for layer_name, param in net.params.iteritems():print layer_name + '\t' + str(param[0].data.shape), str(param[1].data.shape)conv1   (96, 3, 11, 11) (96,)conv2   (256, 48, 5, 5) (256,)conv3   (384, 256, 3, 3) (384,)conv4   (384, 192, 3, 3) (384,)conv5   (256, 192, 3, 3) (256,)fc6 (4096, 9216) (4096,)fc7 (4096, 4096) (4096,)fc8 (1000, 4096) (1000,)

因为我们处理的是四位数据,所以我们将定义一个帮助函数来可视化特征。

def vis_square(data):"""输入一个形如:(n, height, width) or (n, height, width, 3)的数组,并对每一个形如(height,width)的特征进行可视化sqrt(n) by sqrt(n)"""# 正则化数据data = (data - data.min()) / (data.max() - data.min())# 将滤波器的核转变为正方形n = int(np.ceil(np.sqrt(data.shape[0])))padding = (((0, n ** 2 - data.shape[0]),(0, 1), (0, 1))                 # 在相邻的滤波器之间加入空白 + ((0, 0),) * (data.ndim - 3))  # 不扩展最后一维data = np.pad(data, padding, mode='constant', constant_values=1)  # 扩展一个像素(白色)# tile the filters into an imagedata = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])plt.imshow(data)plt.axis('off')plt.show()

首先,我们来看下第一个卷积层(conv1)的输出特征。

    # 参数为一个[weights, biases]的列表filters = net.params['conv1'][0].datavis_square(filters.transpose(0, 2, 3, 1))

上图为conv1的输出。

    feat = net.blobs['conv1'].data[0, :36]vis_square(feat)

上图为pool5的输出。

    feat = net.blobs['pool5'].data[0]vis_square(feat)

上图为第一个全连接层(fc6)的输出。

接下来,我们将显示输出结果及直方图。

    feat = net.blobs['fc6'].data[0]plt.subplot(2, 1, 1)plt.plot(feat.flat)plt.subplot(2, 1, 2)_ = plt.hist(feat.flat[feat.flat > 0], bins=100)plt.show()

上图为最终的概率输出,prob。

    feat = net.blobs['prob'].data[0]plt.figure(figsize=(15, 3))plt.plot(feat.flat)plt.show()

上图显示了分类的聚类结果,峰值对应的标签为预测结果。

6、测试自己的图像

现在,我们随便从网上找一种图像,然后安装上述步骤来进行分类。

将”my_image_url”设为图像的链接(URL)

点击查看原文

Caffe for Python 官方教程相关推荐

  1. Python官方教程.pdf

    人生苦短,快学Python! 之前总有人询问有没有Python的学习资料? 这次废了九牛二虎之力,为大家找到了几个最适合小白的Python的学习资料!容易入门,又全面,太好用了. 1. Python官 ...

  2. python官网 中文版-python .. 官方教程中文版.pdf

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbspPython python .. 官方教程中文版.pdf105页 ...

  3. PYTHON官方教程:Python3.11中文版文档

    Python 每年都会发布新版本,上半年是功能锁定的测试版,年底是最终版本. Python 3.11 的特性集刚刚定稿,测试版本已经发布,开发人员在非生产代码上可以尝试使用这个最新版本,验证它能否在你 ...

  4. Opencv4 -Python官方教程学习笔记33---BRIEF

    理论 我们知道SIFT使用128维矢量作为描述符.由于它使用浮点数,因此基本上需要512个字节.同样,SURF最少也需要256个字节(用于64像素).为数千个功能部件创建这样的向量会占用大量内存,这对 ...

  5. VS2015+caffe+matlab+python+CPU

    实验平台: Win7 64bit, VS 2015(Professional), matlab 2016b(64bit), python2.7.12, Eclipse IDE for Java Dev ...

  6. python入门教程 官方-Python自学入门?

    如果你是零基础入门 Python 的话,建议初学者至少达到两个目标: 会用,理解. 会用 通过 Python 入门教程,学习 Python 的语法,熟悉 Python 标准库的使用. 目前 Pytho ...

  7. Python 官方中文教程(简)

    Python 官方教程 前言 这是一次系统学习Python官方教程的学习笔记 整个教程一共16章, 在学习过程中记录自己不知道的和一些重要的知识, 水平有限, 请指正. Python3.7 官方教程. ...

  8. python官方中文文档上线_微软官方上线Python教程

    Windows 上做 Python 开发太痛苦?近日,微软上线了一系列Python官方教程<Develop with Python on Windows>,文档内容包括设置Python开发 ...

  9. python PyQt5教程

    引用文章1:python PyQt5 教程 参考文章2:PyQt5 python官方教程 Qt for Python pyqt5-基础 PyQt5是一套来自Digia的Qt5应用框架和Python的粘 ...

最新文章

  1. C#动态加载DLL(转)
  2. mysql安装教程8.0.21安装,mysql 8.0.21 安装配置方法图文教程
  3. SQL Server温故系列(1):SQL 数据操作 CRUD 之增删改合
  4. windows平台oracle无法调度,windows 2003+Legato networker+oracle 9i (框架)
  5. 总结一些linux目录结构和终端命令
  6. Linux安装 Screen出现的问题
  7. gwt-2.8.2下载_GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示
  8. 你有没有想过,在SpringBoot集成下,Mybatis的mapper代理对象究竟是如何生成的?...
  9. 什么是二次元?什么是二次元衍生创作?它的魅力何在?
  10. HDU2024 C语言合法标识符【入门】
  11. python常用字符串方法_python基础之字符串常用方法
  12. Android手机启动流程探究
  13. 如何提升串口响应速度
  14. 【已解决】如何让压缩率达到最大?使用lrzip工具进行文件压缩(好用)
  15. 云开发表情包制作神器微信小程序源码下载,支持各种自定义
  16. mysql数据备份与导入(二)
  17. 文件在服务器中存储,如何发送音频文件在服务器中存储
  18. ProcessOn第一次使用教程
  19. Mysql-计算两个时间之间的差值
  20. 案例分享-21款奔驰S450L升级原厂夜色饰条套件

热门文章

  1. Android Dev Tools官网地址:http://www.androiddevtools.cn/
  2. 星速平台:煤炭板块震荡上扬 昊华能源涨停
  3. 是不是在为 API 烦恼 ?好用免费的api接口大全呼之欲出
  4. Lua快速入门篇(基础概述)(Yanlz+toLua+xLua)
  5. vscode指定中英文字体设置
  6. EventBus3 简单使用及注意点
  7. 财税SaaS行业格局再变,慧算账为何能受资本“偏爱”?
  8. java数组排序sort原理,ZooKeeper的十二连问
  9. 风变Python之旅4---字典列表的学习
  10. 建设工程法规专科【5】