Hi, 树莓Pi的创客们,大家好。
今天跟大家分享一下一个很实用的例子,如果你已经玩过我的上一个入门教程,觉得不过瘾,那么就来试试今天的项目。
这次是用Pi制作智能摄像头,监视我家的猫咪,当它在台盆里喝水时就会被摄像头拍下来。当我们人的手或其他东西在台盆上时,摄像头则视而不见。因此要用深度学习技术,让摄像头能够将猫和其他东西区分出来。这里要在keras框架中运行inceptionV3模型,用到finetune技术。
技术介绍
InceptionV3
这是Google设计的深度学习网络框架,由很多层卷积层和一个分类器(全连接神经网络)组成。卷积层是核心,他负责从图片中提取特征,比如边缘,颜色,几何形状等等,还有人的五官,汽车的轮子等等,前一种叫浅特征,后一种叫深特征。而分类器,只做一些是非判断。所以卷积层相当于人类的感知,分类器则是纯粹的计算器。
这个网络特性优异,可以区分1000种类别的图片。因为他卷积层有很多,并且用数万张图片进行训练,从而学到了很多特征。特征被存放在权重文 件中,我们要用他来做摄像头程序。
finetune
inceptionV3的类别其实已经包含了猫。但是,我家的田园土猫,经常被识别成法国斗牛犬(图1),有时还会蹦出一些稀奇古怪的狗的名字(图2)。为了能让inceptionV3认出我家的猫,我必须让inceptionV3多识别几次,记录下它输出的一些奇特类别,然后把它们转换成猫咪类别。但有时猫咪站在台盆上,inceptionV3会输出浴缸,可能是台盆比猫清晰。要是每次这样也道倒算了,问题是台盆空着时,他也认成浴缸(图3),这就很麻烦了。
你可以到basin_cat/full_test/中运行recognize.ipynb,他会把我洗手的图认成皮搋子(图4)。
所以,最好能够训练一个自己的深度网络。但是训练卷积层需要昂贵的硬件设备和几周的时间,好在有了finetune技术。
finetune(图6)。就是不全部借用整个网络,而只是借用卷积层框架和它学到的特征,至于分类器,你必须重新设计,包括给出你自己的类别个数,当然训练用的图片也应该是你自己的。在训练过程中,卷积层的参数不会被修改,但是分类器的参数会改变,直到这个分类器能够分对图片。因为从全部模型做的识别中看出,卷积层学到的特征都还靠谱,他至少知道猫咪是个四条腿的动物,所以这些特征可以拿来利用。
教程
硬件
Pi3B+picamera2+Pi显示器(最好5寸以上),系统:Raspbian Jessie with PIXEL(2017-03-02)
PC/笔记本,系统:Ubuntu 14.04
软件包的安装
我希望你已经对python和Linux比较熟悉,知道如何安装缺少的包,熟悉从GitHub克隆安装软件包。然后在Pi和PC上都安装好下面的包。过程可能比较麻烦,有问题可以联系我hotgarlic@163.com
首先运行:
$sudo apt-update #系统更新 $sudo apt-upgrade #系统升级 $python3 get-pip.py #安装python软件包安装器pip3,在basin_cat文件夹中
tensorflow
他是keras的后台程序。
- Pi上安装:参考这里,选用第一种pip安装方式,以及python3对应的包。本教程所用
的代码,python包,和包的安装方式也都是针对python3的。
- PC上安装:具体参考这里,如果打不开,请百度禾斗学上网。
$sudo apt-get install python-pip python-dev $pip3 install tensorflow
Keras
$git clone https://github.com/fchollet/keras.git $cd yourfloder/keras $sudo python3 setup.py install
他操作起来比tensorflow简单许多,值得多多学习,其包含了很多例子和优秀的模型,甚至你可以在他的仓库里找到alpha go的相关算法,这是现在很多人工智能的开源项目里面第二大开发平台,第一就是比较难用的他的后台tensorflow。
jupyter notebook
$sudo pip3 install jupyter $jupyter notebook #进入jupyter界面
他是一个非常简洁易用的IDE,适合调试代码,现在越来越多的教程开始使用这个平台。具体用法很简单,这里就不细说了,请百度。
h5py
$sudo apt-get install python3-h5py
是用来存取训练分类器权重的软件包。
skimage,imageio
$sudo pip3 install -U scikit-image $sudo pip3 install imageio
他们都是图片处理包。其中Imageio可以将mp4转换成图片。
Matplotlib
$python -m pip install -U pip setuptools
$python -m pip install matplotlib
这是可以在IDE中查看图片的工具包,可以不用安装,特别是不需要在Pi上安装。
gpac
$sudo apt-get install gpac
$MP4Box -add path/file.264 path/file.mp4 #格式转换命令
只需Pi上安装的包,可以将h264视频转换成MP4格式。
操作流程
- 将整个basin_cat文件夹复制到你的PC上。
- 打开jupyter,在jupyter中打开ipynb,单步运行代码。
- 先运行*和2.1之间的代码。之后sample文件夹里会多许多图片,请把图片中没有人,没有猫出现的图片放到basin_cat/label_2/sample中。
- 再运行其余代码:
将分好类的图片进行扩增
加载inceptionV3模型及其学到的特征
让inceptionV3转换所有扩增好的图片
将inceptionV3转换好的数据作为分类器的训练数据
建立分类器模型
训练分类器
- 最后h5生成,里面是权重参数,在train.ipynb同文件夹。
将ipynb和trial_0.h5一起复制到Pi的同一个文件夹中。
- 打开jupyter,在jupyter中打开ipynb,单步运行代码。
- 先是一段预览摄像头的代码,会在屏幕上显示摄像头拍到的图像,你有10秒中调整摄
像头的位置。
- 然后是加载inceptionV3模型及权重、建立分类器模型的代码。注意这里的分类器一
定要和train.ipynb中一致!
- 最后是主程序,它循环不断得抓取图片,然后进行识别,如果识别到0类图片,也就是猫咪在台盆里喝水的图,那么将会把这个图片保存在硬盘中,在monitor.ipynb所在的文件夹。逮住猫咪喝水的图片是这样的(图5)。
说明
- random文件夹,是用来存放扩增图片的。扩增图片是从原始的图片中产生的,经过
了随机的几何变形和明暗变化后,原先的图片就可以成倍的增长,可以在样本不多的情况下让模型训练得更好。
- 你可以拍摄mp4,并存放到sample文件夹,注意要用mp4, 1.mp4, 2.mp4 …等等作
为文件名。
- 你也可以增加类别,先新建一个label_n文件夹,里面也要保含random和sample
文件夹。同时也要到train.ipynb中修改相应的代码。具体怎么改,请看代码里面的comment,这里就不细说了。当然,你最好也改一下分类器的模型和类别的个数。
- 如何改进识别的准确度
我在第一次试运行中发现,虽然Pi可以捕捉到猫咪跳上台盆的证据,但有时也会误判。比如Pi会把台盆上的黑裤子当成猫咪。这是因为负样本(不是猫咪的图片)没有包含了黑色裤子的图片。
在这种情况下,从inceptionV3中获得的转换后数据,虽然包含了很多关于猫咪的深度特征,但分类器会故意忽略掉一些。
黑色裤子并不像猫咪那样有两个尖尖的耳朵(深度特征)。当缺乏黑裤子这样的训练样本时,分类器就只会根据颜色(浅特征)来分类。因为对分类器来说,只要看看图片里那块地方颜色是不是黑的,占了多大地方,连续度怎么样,就足以做出正确的判断了。
能否充分调动那些特征,使得分类器在判断时采纳这些信息,就取决于你能否给出足够数量的具有迷惑性的数据。
另外,将猫咪拖到其他背景中采集图片,也可以迫使分类器多多参考深度特征进行判断。
所以,你就要有意无意得对Pi进行干扰,让它拍下一些误判的图片,然后把这些图片加入到非猫咪图片的样本中去,再按照流程重新训练一遍。这里给出的代码也已经使得工作简化了许多,而且那些误判的图片并不会很多。
待完善
我还没有制作驱赶猫咪的机构,比如声光报警,喷水,来吓唬猫咪。希望有兴趣的并且同样讨厌猫咪不良行为的创客可以帮我完成。我并不擅长这些硬件方面的知识。
因为我用的是可见光摄像头,而不是红外摄像头,所以光线太暗就会导致误判,因
为很多细节的特征会被淹没。所以我就把昏暗的图片归类到了非猫咪类中,希望猫咪不会发现其中的漏洞。有兴趣的创客可以再加一个红外传感器来辅助一下。
题外话
也许你会认为,图片越多越准确,算什么智能。确实,现在有很多人提出这一的质疑。但是如果没有深度神经网络,卷积这样的算法,即便你拥有所有的图片,你都很难把这些图片抽象成可计算的特征,而现在的深度网络最成功的地方,就是自动提取特征,而且是深层次的特征。相比人工对特征参数化,就已经进步了不少。当然,还远远没有达到理想中的智能的目标。