本文记录如何基于pycaffe提取pretrained model某一层的特征。
import numpy as np
import matplotlib.pyplot as plt
import scipy.io
# 设置plt画图显示结果
# 图片尺寸
plt.rcParams['figure.figsize'] = (12,12)
plt.rcParams['figure.dpi'] = 150
# 不插值
plt.rcParams['image.interpolation'] = 'nearest'
# 热图
plt.rcParams['image.cmap'] = 'jet'
# 添加工具包的python路径
import sys
import os
tool_root = '/mnt/SSAP/Util/'
tool_pakg = ['caffe', 'libsvm', 'liblinear']
for item in tool_pakg:
sys.path.append(tool_root + item + '/python')
# pycaffe模块
import caffe
caffe_root = '/mnt/SSAP/Util/caffe/' # caffe根目录
model_root = './models/'
opt = {
"debug": False,
"caffeMode": "gpu",
"batchSize": 1,
"inputSize": 227,
"net": "alexNetPlaces",
"layer": "single", # multi, single
"dataset": "MITIndoor67"
}
if opt["caffeMode"] == "cpu":
caffe.set_mode_cpu()
else:
caffe.set_device(0)
caffe.set_mode_gpu()
if opt["net"] == "googleNet":
model_def = model_root + 'deploy_googlenet.prototxt'
model_weights = model_root + 'imagenet_googlelet_train_iter_120000.caffemodel'
elif opt["net"] == "alexNetPlaces":
model_def = model_root + 'alexnet_places/places205CNN_deploy_upgraded.prototxt'
model_weights = model_root + 'alexnet_places/places205CNN_iter_300000_upgraded.caffemodel'
layer_names = ["fc7"]
else:
print "[Error]no model exist."
exit()
net = caffe.Net(model_def, # 定义模型结构
model_weights, # 预训练的网络
caffe.TEST) # 测试模式
net.blobs['data'].reshape( opt["batchSize"], # batch size
3, # BGR
opt["inputSize"], opt["inputSize"] ) # image size
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1)) # 变换image矩阵,把channel放到最后一维
transformer.set_raw_scale('data', 255) # 从[0,1]rescale到[0,255]
transformer.set_channel_swap('data', (2,1,0)) # 调整 channels from RGB to BGR
下面是对一幅图提取CNN特征
featAll = [] # 每一行存一幅图的CNN特征
image = caffe.io.load_image('test.jpg') # 读入图片
transformed_image = transformer.preprocess('data', image)
net.blobs['data'].data[...] = transformed_image
output = net.forward() # 这里output是CNN最后一层的输出向量
feature = net.blobs['fc7'].data[0] # 读取fc7层的特征
# 打印feature维度看看,这里是blob
if opt["debug"]:
print feature.shape
feature_standarlized = (feature - min(feature)) / (max(feature) - min(feature)) # 归一化
# 把ndarray转为list
tmpf = feature_standarlized.reshape(1,feature_standarlized.size)
s = tmpf.tolist()
fe = reduce(lambda x,y: x+y,s)
# 验证list维度
if opt["debug"]:
print len(fe)
featAll.append(fe)
循环执行上述代码,可对整个数据集提取fc7层的CNN特征到featAll中。