caffe的python接口学习(11):特征的批量提取

原文链接1:http://blog.csdn.net/guoyilin/article/details/42886365

修改prototxt实现

caffe在[1]讲到如何看一个图片的特征和分类结果,但是如何批量抽取特征呢?可以使用c++的版本点击打开链接,这里我们谈下如何用Python批量抽取特征。

首先,我们要注意caffe filter_visualization.ipynb的程序中deploy.prototxt中网络每一轮的图片batch是10, 这个数刚好和oversample=true的crop数量是一样的,也就是net一轮forward 刚好是一张图片的10个crop。

第一种,oversample = true的情况, 也就是每张图片会产生10张crop的图片: center, 4 corner, 和mirror

假如我们要抽取两张图片, 每张图片有10个crop

首先是修改deploy.prototxt: input_dim : 20

然后:将imagelist 放入predict参数。


scores = net.predict([caffe.io.load_image(caffe_root + "building.jpg"), caffe.io.load_image(caffe_root + "thumb.jpg")])  
最后用


net.blobs['fc7'].data[4]  
net.blobs['fc7'].data[14]  


import numpy as np  
import scipy  
caffe_root = '/home/hduser/Project/caffe/'  
import sys  
sys.path.insert(0,caffe_root + 'python/')  
import caffe  
  
net = caffe.Classifier(caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt',  
        caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel',image_dims=(256, 256))  
net.set_phase_test()  
net.set_mode_cpu()  
net.set_mean('data', np.load(caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy'))  
net.set_raw_scale('data', 255)  
net.set_channel_swap('data', (2,1, 0))  
  
#in fact, you can input a list of images.  
scores = net.predict([caffe.io.load_image(caffe_root + "building.jpg"), caffe.io.load_image(caffe_root + "thumb.jpg")])  
output = open("feature.txt", "w")  
  
#the fc6 is the fc6 layer feature, data[4] means the five crop images, because each image will be crop to 10 sub-images.  
feat = net.blobs['fc6'].data[4]  
feat2 = net.blobs['fc6'].data[14]  
这样不好的地方是需要修改deploy.prototxt, 另一种方法[2]:modify predict() in python/caffe/classifier.py to store them before the blobs in net are overwritten by the features of a subsequent batch. 该种方法我还没尝试,改天试下。


第二种情况, 如果图片不需要crop成10张子图片的话,可以用oversample=False,如果设置image_dims=(256, 256), 由于bvlc_reference_caffenet trained model 是227*227的图片大小,所以python/caffe/classifier.py的代码会take center crop 227*227 from 256*256.  
input_dim : 2 


第一张图片:net.blobs['fc7'].data[0]

第二张图片:net.blobs['fc7'].data[1]
后记:还需要熟悉下caffe的python接口函数,可惜貌似看不到这方面的api,只有自己先琢磨琢磨。


参考文章:

1. http://nbviewer.ipython.org/github/BVLC/caffe/blob/master/examples/filter_visualization.ipynb 

2. https://groups.google.com/forum/#!searchin/caffe-users/python$20batch$20feature$20extraction/caffe-users/wIgLYMF54AI/iuDf3fZ0_K0J

原文链接2:http://blog.csdn.net/guoyilin/article/details/43420711

修改源码实现

http://blog.csdn.NET/guoyilin/article/details/42886365 上文是使用修改deploy.prototxt文件的input_dim为我们想要的图片的张数,因为net.blobs每当forward执行完毕一次batch, 都会更新网络的blobs数据。本文介绍在不修改deploy.prototxt情况下,更方便抽取图片特征。

首先,修改Python/caffe/classifier.py, 修改predict方法



out = self.forward_all(blobs=['fc7'], **{self.inputs[0]: caffe_in})  
        predictions = out[self.outputs[0]].squeeze(axis=(2,3))  
        fc7 = out['fc7'].squeeze(axis=(2,3))  
        return fc7  
重新编译下caffe的python:
cd build

make pycaffe

然后copy 编译好的包到源码路径下:


cp build/python/libpycaffe.so python/caffe/_caffe.so && \  
mkdir -p python/caffe/proto && \  
touch python/caffe/proto/__init__.py && \  
protoc --proto_path=src/caffe/proto --python_out=python/caffe/proto src/caffe/proto/caffe.proto && \  
protoc --proto_path=src/caffe/proto --python_out=python/caffe/proto src/caffe/proto/caffe_pretty_print.proto  
主程序文件调用如下:


features  = net.predict(imageList, oversample=False)  
for feature in features:  
    print feature  #feature是4096维度  

注意:

运行python/classify文件必需两个参数,一个输入图片文件,一个输出结果文件。而且运行必须在python目录下。假设当前目录是caffe根目录,则运行:

# cd python
# sudo python classify.py ../examples/images/cat.jpg result.npy

分类的结果保存为当前目录下的result.npy文件里面,是看不见的。而且这个文件有错误,运行的时候,会提示

Mean shape incompatible with input shape

的错误。因此,要使用这个文件,我们还得进行修改:

1、修改均值计算:

定位到 

mean = np.load(args.mean_file)

 这一行,在下面加上一行:

mean=mean.mean(1).mean(1)

 则可以解决报错的问题。

2、修改文件,使得结果显示在命令行下:

定位到

# Classify.
    start = time.time()
    predictions = classifier.predict(inputs, not args.center_only)
    print("Done in %.2f s." % (time.time() - start))

这个地方,在后面加上几行,如下所示:

复制代码
  # Classify.
    start = time.time()
    predictions = classifier.predict(inputs, not args.center_only)
    print("Done in %.2f s." % (time.time() - start))
    imagenet_labels_filename = '../data/ilsvrc12/synset_words.txt'
    labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')
    top_k = predictions.flatten().argsort()[-1:-6:-1]
    for i in np.arange(top_k.size):
        print top_k[i], labels[top_k[i]]
复制代码

 就样就可以了。运行不会报错,而且结果会显示在命令行下面。

1

你可能感兴趣的:(深度学习)