用训练好的caffemodel来进行分类

现在我正在利用imagenet进行finetune训练,待训练好模型,下一步就是利用模型进行分类。故转载一些较有效的相关博客。

博客部分来源:http://www.cnblogs.com/denny402/p/5111018.html

caffe程序自带有一张小猫图片,存放路径为caffe根目录下的 examples/images/cat.jpg, 如果我们想用一个训练好的caffemodel来对这张图片进行分类,那该怎么办呢? 如果不用这张小猫图片,换一张别的图片,又该怎么办呢?如果学会了小猫图片的分类,那么换成其它图片,程序实际上是一样的。

开发caffe的贾大牛团队,利用imagenet图片和caffenet模型训练好了一个caffemodel,  供大家下载。要进行图片的分类,这个caffemodel是最好不过的了。所以,不管是用c++来进行分类,还是用python接口来分类,我们都应该准备这样三个文件:

1、caffemodel文件。 

  可以直接在浏览器里输入地址下载,也可以运行脚本文件下载。下载地址为:http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel

文件名称为:bvlc_reference_caffenet.caffemodel,文件大小为230M左右,为了代码的统一,将这个caffemodel文件下载到caffe根目录下的 models/bvlc_reference_caffenet/ 文件夹下面。也可以运行脚本文件进行下载:

  1. # sudo ./scripts/download_model_binary.py models/bvlc_reference_caffenet  

2、均值文件。

有了caffemodel文件,就需要对应的均值文件,在测试阶段,需要把测试数据减去均值。这个文件我们用脚本来下载,在caffe根目录下执行:

  1. # sudo sh ./data/ilsvrc12/get_ilsvrc_aux.sh  


执行并下载后,均值文件放在 data/ilsvrc12/ 文件夹里。

3、synset_words.txt文件

在调用脚本文件下载均值的时候,这个文件也一并下载好了。里面放的是1000个类的名称。

数据准备好了,我们就可以开始分类了,我们给大家提供两个版本的分类方法:

一、c++方法

在caffe根目录下的 examples/cpp-classification/ 文件夹下面,有个classification.cpp文件,就是用来分类的。当然编译后,放在/build/examples/cpp_classification/ 下面

我们就直接运行命令:
  1. # sudo ./build/examples/cpp_classification/classification.bin \  
  2.   models/bvlc_reference_caffenet/deploy.prototxt \  
  3.   models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel \  
  4.   data/ilsvrc12/imagenet_mean.binaryproto \  
  5.   data/ilsvrc12/synset_words.txt \  
  6.   examples/images/cat.jpg  

命令很长,用了很多的\符号来换行。可以看出,从第二行开始就是参数,每行一个,共需要4个参数

运行成功后,输出top-5结果:

---------- Prediction for examples/images/cat.jpg ----------
0.3134 - "n02123045 tabby, tabby cat"
0.2380 - "n02123159 tiger cat"
0.1235 - "n02124075 Egyptian cat"
0.1003 - "n02119022 red fox, Vulpes vulpes"
0.0715 - "n02127052 lynx, catamount"
即有0.3134的概率为tabby cat, 有0.2380的概率为tiger cat ......

二、python方法

python接口可以使用jupyter notebook来进行可视化操作,因此推荐使用这种方法。

在这里我就不用可视化了,编写一个py文件,命名为py-classify.py
  1. #coding=utf-8  
  2. #加载必要的库  
  3. import numpy as np  
  4.   
  5. import sys,os  
  6.   
  7. #设置当前目录  
  8. caffe_root = '/home/xxx/caffe/'   
  9. sys.path.insert(0, caffe_root + 'python')  
  10. import caffe  
  11. os.chdir(caffe_root)  
  12.   
  13. net_file=caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt'  
  14. caffe_model=caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'  
  15. mean_file=caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy'  
  16.   
  17. net = caffe.Net(net_file,caffe_model,caffe.TEST)  
  18. transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})  
  19. transformer.set_transpose('data', (2,0,1))  
  20. transformer.set_mean('data', np.load(mean_file).mean(1).mean(1))  
  21. transformer.set_raw_scale('data'255)   
  22. transformer.set_channel_swap('data', (2,1,0))  
  23.   
  24. im=caffe.io.load_image(caffe_root+'examples/images/cat.jpg')  
  25. net.blobs['data'].data[...] = transformer.preprocess('data',im)  
  26. out = net.forward()  
  27.   
  28.   
  29. imagenet_labels_filename = caffe_root + 'data/ilsvrc12/synset_words.txt'  
  30. labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')  
  31.   
  32. top_k = net.blobs['prob'].data[0].flatten().argsort()[-1:-6:-1]  
  33. for i in np.arange(top_k.size):  
  34.     print top_k[i], labels[top_k[i]]  

执行这个文件,输出:

  1. 281 n02123045 tabby, tabby cat  
  2. 282 n02123159 tiger cat  
  3. 285 n02124075 Egyptian cat  
  4. 277 n02119022 red fox, Vulpes vulpes  
  5. 287 n02127052 lynx, catamount  
caffe开发团队实际上也编写了一个python版本的分类文件,路径为 python/classify.py

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

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

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

  1. Mean shape incompatible with input shape  
的错误。因此,要使用这个文件,我们还得进行修改:

1、修改均值计算:

定位到

  1. mean = np.load(args.mean_file)  


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

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


则可以解决报错的问题。

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

定位到

  1. # Classify.  
  2.     start = time.time()  
  3.     predictions = classifier.predict(inputs, not args.center_only)  
  4.     print("Done in %.2f s." % (time.time() - start))  
这个地方,在后面加上几行,如下所示:
  1. # Classify.  
  2.   start = time.time()  
  3.   predictions = classifier.predict(inputs, not args.center_only)  
  4.   print("Done in %.2f s." % (time.time() - start))  
  5.   imagenet_labels_filename = '../data/ilsvrc12/synset_words.txt'  
  6.   labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')  
  7.   top_k = predictions.flatten().argsort()[-1:-6:-1]  
  8.   for i in np.arange(top_k.size):  
  9.       print top_k[i], labels[top_k[i]]  
就样就可以了。运行不会报错,而且结果会显示在命令行下面。

下面是我自己的成功测试,图片除了测试caffe自带,还测试了从Pascal VOC下载的一些数据。下面贴出其中一组结果:

图片


结果


结果准确到让我惊讶,我以为只能分类为dog,没想到还出现了golden retriever这样的结果 ,艾玛以为误分类了,一搜索,原来是金毛寻回犬,又称金毛猎犬。不得不佩服imagenet包含的数据量之大之全~奋斗


还可以切换到GPU模式下进行测试:

看看这个分类花了多久,和GPU模式做一个比较

[python]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. %timeit net.forward()  

1 loop, best of 3: 1.42 s per loop
即使是50个图的批处理,也只是一会的功夫。那么GPU模式呢?

[python]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. caffe.set_device(0)  # if we have multiple GPUs, pick the first one  
  2. caffe.set_mode_gpu()  
  3. net.forward()  # run once before timing to set up memory  
  4. %timeit net.forward() 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值