mxnet里im2rec的坑

用了一下mxnet,感觉速度上确实比Tensorflow快不少。之前试过部署到Moible端[LINK],也挺方便的。
mxnet训练的时候可以通过ImageDataIter从预处理过的rec文件里读图。rec基本上就是一个打包了label和image的大文件。用rec文件配合DataIter做训练,GPU利用率很高。

遇到两个问题,废了些时间。

1.用im2rec.py生成rec的时候,输入文件格式是,图片序号+Label+图片路径。之间必须用\t分隔,不然会有奇怪的报错。
2.im2rec.py生成图片的时候是用OpenCV读的图,然后从BGR转RGB。图读出来是HxWxC,需要转成CxHxW。不然结果自然会差很多。

Crazyflie 2.0 + Camera

最近给Crazyflie加上了Camera,挺有趣的。

之前在网上看过不少帖子讨论各种解决方案,但是始终没有发现一个简单易行的方法。

IMG_6237

IMG_6239

IMG_6238

最后发现是上面这种带无线传输的一体式的摄像头最方便,重量也小,Crazyflie带着飞无压力。

Crazyflie 2.0 + Flow Deck + Camera!

从VCOM的引脚直接给摄像头供电可以利用Crazyflie本身的开关来控制Camera的开和关。摄像头除了供电以外和Crazyflie是独立的。

接下来的问题就是怎么样在另一台机器上得到Crazyflie传回的图像。因为是摄像头输出的其实是模拟信号,所以需要一个模转数的模块。这部分在很早之前做 智能轮椅 (^_^) 的时候就发现很麻烦。通常是去找一个叫Easycap的小东西,但似乎因为仿制Easycap或者是Ez-Cap的厂家太多了,所以很难找到一个真的可以兼容信号和系统的Easycap。而且Easycap只是一个模转数的模块,在此之前还需要一个多频道的无线接收器。因为这个无线接收器通常需要12V的电源,所以整套接收图像的设备非常“笨重”,而且还不一定好用…

不过所幸最近发现了一个从USB供电的一体的无线接收模转数的模块,非常棒。随便用一个带摄像头的drone试了一下:

可以直接用OpenCV读到图像!可以做CV乐!

IMG_6268

iOS上mxnet的一个演示App

mxnet是最近火的不行的一个深度学习的框架,支持好多好多语言,有好多好多大牛在写。

之前也有想过把同样很牛很牛的caffe跑到iOS上看看速度怎么样,但是caffe有一大堆文件,感觉做起来很麻烦。

最近看到mxnet居然有一个单文件的版本
就做了一个简单的图像识别的演示App。跑在6上速度还可以,大概4秒一张图。

代码在这里:

WhatsThis-iOS on Github

[Note] Saliency Detection: A Boolean Map Approach

Saliency应该是翻译为显著性。个人理解显著性检测是得到一张图片上每一个像素点的显著程度的过程。对于这个显著程度,直观的理解就是它在这张图上的重要程度。比如,这些照片里

Bird Diversity 2013

组成鸟的像素应该是比背景的像素更加重要,也就是应该有更高的显著性值。知道了各个像素点的显著性之后,可以用来帮助一系列的更加具体的任务,比如这篇文章里的Eye Fixation的预测,也就是预测在这张图片上人会看哪里。还有显著物体的检测,可以更进一步的做物体检测和识别。

直接描述这篇文章的方法吧。输入是一张图片,输出是一张Saliency Map,表示每一个像素点上的显著性。根据Saliency Map可以进一步的做更佳具体的任务。得到Saliency Map的过程是先得到一组Boolean Maps,然后每一张Boolean Map得到一张Attention Map,对所有的Attention Maps求均值之后做Dilation就得到了Saliency Map。过程很简洁。

假设输入图片有三个颜色通道,随机的选一个颜色取一个阈值。然后据此把图片转成一张0/1的图片,颜色值大于阈值的为1,否则为0。这张0/1的图就是一张Boolean Map。重复这个过程就得到了一组Boolean Maps。Boolean Map如果一块区域和很好的封闭的边缘,那么就有可能是一个显著的物体。所以连着图片边框的区域显著性就会比较低。基于这个假设,把连着图片边框的区域都去掉,然后对全图做归一化,就得到了Attention Map。

没有做过Saliency Detection,欢迎指出各种错误。看到一篇文章引用了这个叫BMS的方法就找来看看。然后就发现作者是一起实习的小伙伴。。

[Note] Learning to See by Moving

这是一篇用CNN做特征学习的文章,题目比较格调。目标是训练得到可以用来做场景识别、物体识别等等任务的特征。
和之前的工作相比,训练时需要的监督信息不是图片所属的类别,而是两张图片之间的位置变换。准确地说,是拍摄两张相关图片的相机的相对位置变换。

Screen Shot 2015-05-25 at 12.29.27 PM

具体的网络结构如上图。输入两张图片,训练这个网络来判断两张图片之间的变换(Transformation)。每两个BaseCNN取得的特征(Lk)连接起来作为TopCNN的输入,TopCNN输出变换向量。训练结束之后TopCNN就不用了,直接用BaseCNN对输入图片取特征。

在使用相同数量的有标记数据的情况下,用这种相对更容易得到的监督信息训练出来的网络来做分类网络的初始化,比随机初始化分类效果更好。

虽然这个方法并不是完全的无监督学习,但是在移动机器人这种平台上,两张照片的相对位置变换确实是很容易得到的信息。按照这种方法确实可以很方便的给机器人增加场景识别功能。理想情况下,只需要在所在环境下移动的时间采集一些图片来学习特征,简单的通过人机交互标定几个场景,这种用CNN得到的特征应该会有很不错的表现吧。

Reference:

Pulkit Agrawal, Joao Carreira, Jitendra Malik, Learning to See by Moving

[Note] Discovering Hidden Factors of Variation in Deep Networks

一篇很有意思的文章。在一个半监督学习的框架下把需要预测的部分和其他隐含的变化因素(Hidden variations)分开。

比如我们现在的问题是表情分类,给定七种不同的表情,喜怒忧思悲恐惊(老中医..),我们可以训练出一个来判断任一输入图片中人的表情,记为\(y\)。
于此同时,我们还从输入图片中得到了代表其他和任务无关部分的信息,记为\(z\)。具体来说,两个不同的人的照片可以是同样的表情。但是除了表情相同之外,两张照片因为来自不同的人当然有很多其它的不同。除了表情之外其它的隐含信息就是\(z\)。

具体的实现上是基于auto encoder的,在encoding的时候设置两部分输出\(y\)和\(z\)。其中\(y\)的部分就同有监督学习一样。
Screen Shot 2015-05-12 at 10.36.18 AM

目标函数:

\[ \hat{\theta}, \hat{\phi} = \arg \underset{\theta,\phi} \min \sum_{\{x,y\}\in \cal{D}} \alpha U(x,\hat{x}) + \beta S(y,\hat{y}) + \gamma C(\hat{y},z) \]

其中\(\hat{\theta}, \hat{\phi}\)是encoder和decoder的参数,\(\alpha,\beta,\gamma\)是个部分的权值。第一部分就是auto encoder的无监督学习,第二部分是针对需要预测的量的有监督学习,第三部分是作者提出的 cross-covariance penalty (XCov)。目标函数的第三部分XCov意在最小化\(y\)和\(z\)的相关程度,让两者分开。

实验部分也很有意思,给定一个输入图片得到\(y\)和\(z\)之后。可以固定\(z\)然后改变\(y\),从而使得decoder部分可以重建出同样一个人的不同表情。

Screen Shot 2015-05-12 at 10.36.34 AM

Reference:
Brian Cheung and Jesse A. Livezey and Arjun K. Bansal and Bruno A. Olshausen, Discovering Hidden Factors of Variation in Deep Networks, CoRR 2014

[推荐] 王天珍老师的文章

来自科学网博客,王天珍老师的博文:
视觉研究的前世今生(上)
视觉研究的前世今生(中)
视觉研究的前世今生(下)

虽然很多概念不是很明白,但是感觉非常值得一读。这不是关于Computer Vision的研究,主要讨论是对人类视觉的研究。一开始读起来感觉像是在回顾很久远的时代里人们对人类视觉研究的初步探索,读到最后才惊觉原来人们至今对人类视觉的原理仍然知之甚少。我不觉得CV一定要去模拟生物特性来才能得到好的效果。但是人类视觉毕竟是一个强大复杂的系统,非常的有意思。

看到这些文章就想起来上次CVPR上的关于Professor Tsao的邀请报告,讲到她们对猴脑是如何响应视觉刺激而对猴脑的不同部位的不同刺激又是如何影响到视觉感知的研究。虽然我们的CV算法已经可以在很多视觉任务上面得到很好的结果,但是我们对于人类的视觉系统似乎还是不甚了解啊。

Convert the saved checkpoint of cuda-convenet to the proto of Caffe

*Credits of the scripts go to jamt9000 on github, thanks for the helpful work!

You are a deep learning consumer, you have a saved check point you trained with the cuda-convenet. You want to use Caffe to evaluate the trained neural networks on new data possiblely due to the absent of GPU. Hence you need to convert the saved checkpoint to the format compatible to Caffe.

1. check out this version of caffe: jamt9000/caffe:convert-cuda-convnet or my copy.

$git clone https://github.com/jamt9000/caffe/tree/convert-cuda-convnet convert-cuda-convnet

2. compile it following the Caffe installation instruction

## Misc. Setup 
$make all
$make pycaffe

3. convert the check-point with the following codesnippet

import sys
sys.path.append('./python/')
sys.path.append('./tools/extra/')

from convert_net import *

if (len(sys.argv) < 2):
    print "Usage:- path-to-saved-convnet"
    sys.exit(-1)

arg_convnet = sys.argv[1]
output_prototxt = arg_convnet + "-prototxt"
output_proto = arg_convnet + "-proto"

netpt = cudaconv_to_prototxt(arg_convnet)
fh=open(output_prototxt, 'w')
fh.write(netpt)
fh.close()
print "Wrote {0}".format(output_prototxt)

netpb = cudaconv_to_proto(arg_convnet)
fh=open(output_proto, 'wb')
fh.write(netpb.SerializeToString())
fh.close()
print "Wrote {0}".format(output_proto)
$python convert-convnet2caffe.py saved-convnet-checkpoint

4. Now you should find two files: saved-convnet-checkpoint-proto and saved-convnet-checkpoint-prototxt, they are in an older format, you need some tools provided by Caffe to upgrade them.

5. checkout and compile the up-to-date (or any more recent stable) version of Caffe

6. Under build/tools/ you will find tools named upgrade_net_proto_text.bin and upgrade_net_proto_binary.bin, use them to upgrade the saved-convnet-checkpoint-proto and saved-convnet-checkpoint-prototxt accordingly.

7. Almost done, you may need to manually fix the prototext file a little bit for example, add the input layer following any example proto text files provided by the Caffe.

Good luck!

[Code] Mixture-of-Gaussian C++ 实现

一个拟合高斯混合模型(GMM)的C++实现: https://github.com/CVLearner/Mixture-of-Gaussians

只依赖于Eigen,但是因为Eigen可以用到MKL的LAPACK/BLAS实现,所以间接地可以利用MKL加速。相比于OpenCV的实现,一个好处是可以用到多核。所以目前速度尚可,但还有提升空间。感觉上Eigen并没有完全利用到MKL的速度。

[CV]人脸识别检测数据集

做了一段时间的人脸识别和检测,在这里列一下用过的数据集。基本上,大家近期也都是在这几个数据集上检测自己的算法。网上这方面的总结虽然不少,但是一则有些是多年前的数据,或是规模太小或是链接已经失效,再则是数据集的测试协议定义不明,不尽适合用来和其它方法做比较。

1. Labeled Faces in the Wild:
做人脸识别,准确的说是人脸验证(Face Verification),UMass的LFW估计是最近被用的最多的了,LFW采用的测试协议也已经被几个新的数据集沿用了。人脸验证是指,给定两张人脸的照片,算法需要判断它们是不是来自同一个人。最新的结果(ICCV2013),在限制条件最少的协议下,识别的准确率现在已经高达96%了。[广告^_^] 在限制条件最严的协议下,我们的CVPR2013的结果曾经是最好的。最近被Fisher Vector超过了.. 我们还会回来的…

2. YouTube Faces DB:
YouTube Video Faces也是用来做人脸验证的,和LFW不同的是,在这个数据集下,算法需要判断两段视频里面是不是同一个人。有不少在照片上有效的方法,在视频上未必有效/高效。[广告^_^] 在这个数据集上,我们的最新的结果超过81%,目前还没有看到更高的准确率。

3. FDDB:
FDDB也是UMass的数据集,被用来做人脸检测(Face Detection)。这个数据集比较大,比较有挑战性。而且作者提供了程序用来评估检测结果,所以在这个数据上面比较算法也相对公平。FDDB的一个问题是它的标注是椭圆而不是一般用的长方形,这一点可以会导致检测结果评估不准确。不过因为标准统一,问题倒也不大。[广告^_^] 我们ICCV2013的文章在这个数据上面有不错的结果。

4. The Gallagher Collection Person Dataset:
这也是一个做人脸检测的数据集,是Andrew Gallagher的家庭相册。虽然不是给人脸识别设计的,但是很接近实际应用的场景。很适合用来测试自己的方法。

5. The Annotated Faces in the Wild (AFW) testset:
这还是一个做人脸检测的数据集,随UCI的Xiangxin Zhu在CVPR2012的文章发布。值得注意的是在他们的主页有公开的源代码。虽然人脸检测做了很久,但是效果比较好的,可以在网上方便的得到的检测库除了OpenCV以外并不多见。

6. CMU Dataset:
做人脸检测的数据集,这是一个很有些年头的数据集了,虽然大家最近不常用这个数据,但是这不代表这个老数据集很容易对付。最新的检测算法往往需要比较稠密的取比较复杂的特征,这在这个黑白而且分辨率不高的数据集上未必可行。

7. POS Labeled Faces in the Wild:
这个数据我还没有用过,是最近才发布的一个更大型的LFW。可以用来做人脸识别。看起来很不错的样子。

自己感觉比较好用的数据集就是这些了。
感觉不知道应该写点什么,想来还是写写自己专业相关的内容会比较有趣。