PyCaffe食用指南

非官方的PyCaffe食用指南 以AlexNet为例

第三方函数 显示层输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 第三方函数写在前面
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 image
data = 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()

1、引入

导入numpy matplotlib caffe time

1
2
3
4
5
6
7
8
9
10
import numpy as np
import matplotlib.pyplot as plt
import time
%matplotlib inline
import sys
caffe_root = '/home/weijian/caffe/' # 该文件要从路径{caffe_root}/examples下运行,否则要调整这一行。
sys.path.insert(0, caffe_root + 'python')
import caffe
import time
import cv2

2、加载网络

设置计算模式

1
2
3
# caffe.set_device(0)  # 如果你有多个GPU,那么选择第一个
# caffe.set_mode_gpu()
caffe.set_mode_cpu() # 设置CPU模式

设置网络权重文件和网络结构文件

1
2
3
4
5
6
# 网络参数(权重)文件
caffemodel = caffe_root + 'models/bvlc_alexnet/bvlc_alexnet.caffemodel'
# 网络实施结构配置文件
deploy = caffe_root + 'models/bvlc_alexnet/deploy.prototxt'
# deploy:定义模型结构 / caffemodel:包含了模型的训练权值 / caffe.TEST:使用测试模式(不执行dropout)
net = caffe.Net(deploy, caffemodel, caffe.TEST)

3、测试图像预处理

加载ImageNet图像均值 (随着Caffe一起发布的)

1
2
mu = np.load(caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy')
mu = mu.mean(1).mean(1) # 对所有像素值取平均以此获取BGR的均值像素值

减去均值/调整大小

1
2
3
4
5
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))

4、运行网络

加载图像

1
2
img = "/home/weijian/caffe/examples/images/cat.jpg"
im = caffe.io.load_image(img)

导入输入图像

1
2
net.blobs['data'].data[...] = transformer.preprocess('data', im)
start = time.clock()

执行测试

1
2
3
4
5
6
7
print ">>>>>>>>> classification start <<<<<<<<<<"
# 向前传播
net.forward()
print "time cost in classfication:"
%timeit net.forward()
end = time.clock()
print('classification time: %f s' % (end - start))

5、查看目标检测结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 加载分类名称文件
synset_words = caffe_root + 'data/ilsvrc12/synset_words.txt'
labels = np.loadtxt(synset_words, str, delimiter='\t')
# 得到分类网络的最终结果
category = net.blobs['prob'].data[0].argmax() # 最大概率的分类
# 得到分类名称
class_str = labels[int(category)].split(',')
class_name = class_str[0]
print class_name
# 在图像中标记分类名称
cv2.putText(im, class_name, (0, im.shape[0]), cv2.FONT_HERSHEY_SIMPLEX, 1, (55, 255, 155), 2)
# 显示结果
plt.imshow(im, 'brg')
plt.show()

6、层输出可视化

1
2
3
4
5
6
7
8
9
10
filters = net.params['conv1'][0].data
# 将filter的transpose(转置)传入vis_square
vis_square(filters.transpose(0, 2, 3, 1))
print "上图为conv1的输出"
feat = net.blobs['conv1'].data[0, :36]
vis_square(feat)
print "上图为conv1的前36个数据的输出"
feat = net.blobs['pool5'].data[0]
vis_square(feat)
print "上图为pool5的输出"

7、显示输出结果及直方图

1
2
3
4
5
6
7
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()
print "以上是输出结果及直方图"

8、分类的聚类结果,峰值对应的标签为预测结果

1
2
3
4
5
feat = net.blobs['prob'].data[0]
plt.figure(figsize=(15, 3))
plt.plot(feat.flat)
plt.show()
print "分类的聚类结果,峰值对应的标签为预测结果."


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!