caffe web demo运行+源码分析
caffe web demo学习
1、运行
安装好caffe后,进入/opt/caffe/examples/web_demo/的caffe web demo项目目录,查看一下app.py文件,这是一个flask编写的网站
查看readme.md了解该项目,查看requirements.txt了解所需的python包
然后运行该项目:python app.py,发现报错
class_labels_file is missing
网上说还需要下载一些data,运行下面两条命令:
确保已经下载了 Reference CaffeNet Model 和 the ImageNet Auxiliary Data:
python opt/caffe/scripts/download_model_binary.py models/bvlc_reference_caffenet
opt/caffe/data/ilsvrc12/get_ilsvrc_aux.sh
然后再运行该项目:python app.py
在127.0.0.1:5000查看
2、app.py源码分析
这个web demo使用了在ilsvrc2012比赛的数据集上训练得到的模型。
模型已经预先训练好,并给出了模型的网络结构文件deploy.prototxt,训练好的模型文件bvlc_reference_caffenet.caffemodel,训练数据的均值文件ilsvrc_2012_mean.npy(需要它是因为需要对测试数据去均值),标签序号与标签内容的对应文件synset_words.txt,与原始数据集结构有关的imagenet.bet.pickle
其中网络结构文件、训练好的模型文件、均值文件会被输入到caffe.Classifier里用来构造分类器,标签序号与标签内容文件用来在网页上给显示结果。
1)index函数
2)classify_url函数
读取url,urllib.urlopen().read()打开url并读取出二进制字节流(python3中为urllib.request.urlopen().read()),caffe.io.load_image()转换为caffe能接受的格式,输出日志,调用classify_image识别图片,将识别结果和imageurl渲染回html显示给用户
3)classify_upload函数
获取上传的图片,在文件名前插入时间以区分不同文件,将文件保存到服务器,输出日志,调用classify_image识别图片,将识别结果和图片(以base64编码的形式)渲染回html显示给用户
4)embed_image_html函数
为3)服务,读取文件返回base64编码
5)allowed_file函数
检查文件后缀名是否在可接受的类型中(这个函数在app.py中并没有被调用,不知道为什么)
6)ImagenetClassifier内部类
定义了5个默认参数:模型的网络结构文件deploy.prototxt,训练好的模型文件bvlc_reference_caffenet.caffemodel,训练数据的均值文件ilsvrc_2012_mean.npy(需要它是因为需要对测试数据去均值),标签序号与标签内容的对应文件synset_words.txt,与原始数据集结构有关的imagenet.bet.pickle
for循环验证了这些文件存不存在,不存在的话报错(安装过程中的报错就是这里抛出的)
定义了2个默认参数,image_dim表示???,raw_scale表示???
初始化指定识别使用cpu还是gpu
初始化分类器:caffe.Classifier,接收上面定义的模型的网络结构文件deploy.prototxt,训练好的模型文件bvlc_reference_caffenet.caffemodel,训练数据的均值文件ilsvrc_2012_mean.npy(需要它是因为需要对测试数据去均值)三个参数
。。。。。。。
在7)中
app.clf = ImagenetClassifier(**ImagenetClassifier.default_args)
app.clf.net.forward()
两句代码执行完之后,我们实际上就创建并训练好我们的分类器了。
然后我们调用net.predict函数,将caffe.io.load_image得到的图片传进去,就可以进行识别,并返回一个numpy.ndarray类型的最后一层(输出层)的结果。
net.predict完之后,识别的中间结果也已经存在app.clf.net中了,只需要调用net.blobs['layer名'].data就可以获取到numpy.ndarray类型的中间结果了。
predict时的oversample表示过取样,默认为true
ndarray.shape可以获取ndarray数组的形状,更多源于numpy.ndarray数组的信息见这篇https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html
ndarray.flatten表示把ndarray多维数组展开成一维ndarray数组,见这篇https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.flatten.html
ndarray数组前面加负号表示对每个元素取负值
ndarray.argsort不改变原数组,并返回原数组值从小到大的索引值,示例如下,或见这篇http://blog.csdn.net/maoersong/article/details/21875705
>>> x = np.array([3, 1, 2])
>>> np.argsort(x)
array([1, 2, 0])
个人通过加了如下几行代码看了一下这个模型各层结果的格式:(在使用logging.info的过程中注意,logging.info的输出要通过%s来占位,不同于print可直接输出)
# add by zss
# logging.info('classifier.predict.faltten:%s',list(scores))
# logging.info('classifier.predict:%s',list(self.net.predict([image],oversample=True)))
logging.info('########################:%s',list(self.net.blobs['fc8'].data[1]))
如下:
predict函数返回的最后一层(prob层)的结果格式为1*1000的概率数组(值在0-1之间)
‘fc8’层的结果,格式为10*1000的概率数组(值在0-1之间)
分析:
prob层和fc8层的结果对应着1000个标签,含义是该图片是该标签的概率。
fc8层有10个长度1000的数组是因为我们在定义模型(caffe.Classifier())时,对oversample选项采用了默认值true,开启了过取样,相当于将每张图片经过旋转和镜像对称变成了10张相同的图片,所以fc8层有10个结果,然后prob层将这10个结果综合得到了最终结果1*1000的概率数组),关于oversample过取样见这篇http://blog.csdn.net/guoyilin/article/details/42886365
‘fc7’层的结果,格式为10*4096的foat数组(值可能大于1),形如下图
分析:
fc7层的结果对应着输入的那一张图片,经过过取样后的10张图片,各自的4096个特征的值
7)start_tornado函数
为8)服务,启动flask服务器
不太明白,为什么要用tornado的函数启动flask服务器?
8)start_from_terminal函数
为9)服务,使用optparse定义了一些参数debug,port,gpu,用来控制debug模式是否打开,flask运行的端口,gpu模式还是cpu模式,运行flask的端口号,然后调用7)启动flask服务器
9)命令行启动
设置log级别,创建用来存储用户上传的图片的临时文件夹,调用8)
caffe web demo运行+源码分析的更多相关文章
- lesson2:java阻塞队列的demo及源码分析
本文向大家展示了java阻塞队列的使用场景.源码分析及特定场景下的使用方式.java的阻塞队列是jdk1.5之后在并发包中提供的一组队列,主要的使用场景是在需要使用生产者消费者模式时,用户不必再通过多 ...
- Bytom Dapp 开发笔记(三):Dapp Demo前端源码分析
本章内容会针对比原官方提供的dapp-demo,分析里面的前端源码,分析清楚整个demo的流程,然后针对里面开发过程遇到的坑,添加一下个人的见解还有解决的方案. 储蓄分红合约简述 为了方便理解,这里简 ...
- lesson1:threadlocal的使用demo及源码分析
本文中所使用的demo源码地址:https://github.com/mantuliu/javaAdvance 其中的类Lesson1ThreadLocal 本文为java晋级系列的第一讲,后续会陆续 ...
- cocos2D-x demo 的源码分析 #define ..##.. 的妙用.
最近在看cocos2d-x 但不知道如何下手,于是先看一下他编译的完成的testcpp的源码.发现了下面一段程序 typedef CCLayer* (*NEWTESTFUNC)(); #define ...
- ASimpleCache源码分析
ASimpleCache里只有一个JAVA文件——ACache.java,首先我用思维导图制作了ACache类的详细结构图: 通过分析官方给的demo来驱动源码分析吧 以字符串存储为例(官方给的dem ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- spring AOP源码分析(一)
对于springAOP的源码分析,我打算分三部分来讲解:1.配置文件的解析,解析为BeanDefination和其他信息然后注册到BeanFactory中:2.为目标对象配置增强行为以及代理对象的生成 ...
- 移动web app开发必备 - Deferred 源码分析
姊妹篇 移动web app开发必备 - 异步队列 Deferred 在分析Deferred之前我觉得还是有必要把老套的设计模式给搬出来,便于理解源码! 观察者模式 观察者模式( 又叫发布者-订阅者模 ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
随机推荐
- atitit.jQuery Validate验证框架详解与ati Validate 设计新特性
atitit.jQuery Validate验证框架详解与ati Validate 设计新特性 1. AtiValidate的目标1 2. 默的认校验规则1 2.1. 使用方式 1.metadata用 ...
- zookeeper综述
zk概念 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.他主要用来解决分布式应用中的数据管理的一 ...
- C++ STL源代码学习(list篇)
///STL list为双向循环链表 struct _List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; }; t ...
- redis命令_ZADD
ZADD key score member [[score member] [score member] ...] 将一个或多个 member 元素及其 score 值加入到有序集 key 当中. 如 ...
- makefile之findstring函数
#$(findstring <find>,<in> ) #功能:在字串<in>中查找<find>字串. #返回:如果找到,那么返回<find> ...
- tail 命令详解
tail 指令 功能:从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不 ...
- winform播放音乐
string sound = Application.StartupPath +@"\song\123.wav"; //Application.StartupPath:程序exe所 ...
- iOS 新手引导页图片适配及其尺寸大全
早期新手引导页只需要几张图片就可以解决了,随着屏幕尺寸的的越来越多,新手引导页的尺寸适配起来越来越麻烦,否则就会出现尺寸不匹配,图片被拉伸的情况 目前应该是有2种方法来解决这个问题 方法1: 根据每款 ...
- 开源Bug管理系统Redmine安装和使用心得
最终忍受不了公司使用论坛+Excel来进行bug反馈和管理工作了,于是花了一个上午时间研究了下bug管理系统.这样一个bug管理系统能够轻松的查看bug新增了哪些,攻克了哪些.当前是谁,要在什么时间解 ...
- 数据库设计(五)第一范式(1NF)?
In our last tutorial we learned and understood how data redundancy or repetition can lead to several ...