机器不学习系列-是猫是狗,遛一遛!
为了更好的阅读体验,请大家移步与:https://mp.weixin.qq.com/s/7FOEAnZFMyRInk48qiRbUg
额,,深度学习,机器学习的文章看的多了,但是好像并不知道实际上有啥卵用!!!这次咱们就整点儿实际的,来识别一下图片当中的东西咋样(狗呀,猫呀,当然还可以识别美女咯)
谷歌相册可以识别出来图片里面的风景!相似的,iPhone相册也可以识别出图片里面的动物,人,美食等等,都是自动对其进行打标签的!
他们的原理到底是啥呐,这些大厂,一定是技术相当成熟了,才把这种功能用于用户体验的,所以让我们一探究竟吧!
相信小孩子(3岁左右就成)看见上面的图片一下子就知道,“哇,鸟!”
以前,但是如果让计算机去理解图片当中有一只鸟,emmm,估计你要把电脑砸了,然后把自己装进去才成!
这么多年过去了,多亏了广大的学者朋友们,给我们提供了一种好用又简单的方法用于目标检测和识别!--深度卷积神经网络
let`s do it,~
我们识别鸟之前,让我们做点儿简单的功课!“机器不学习系列-机器学习是个啥”说的“手写数字识别”大家还记得吧!再结合我们在上一篇说的神经网络的知识,我们来改造一下咱们的神经网络让其能够进行手写数字识别!
说过很多遍,机器学习的前提是:数据,大量的训练数据,好在手写数字识别有相应的训练集MNIST^_^,
MNIST data set of handwritten numbers
里面有60000张手写数字的图像,并且每张图像都是18*18。
看看这密密麻麻的数字8,是不是有的还很像你的字迹!
咳咳咳,回到正题, 记住,在计算机的世界里面全都是以数值进行表征的!在上一篇房屋销售的例子中,我们单纯用数字来表征卧室的个数,房间的大小等等,如果我们想解决我们现在手写数字识别的问题,我们应该怎么做呐?
其实答案非常的简单,因为图像在计算机当中是以像素点进行存储的!我们可以将图片转化为像素值,然后将其输入到神经网络当中去!
将上面所有的数值展开,得到如下的数组!
其包括324个输入,我们可以依照此输入来调整我们的神经网络模型!
这时候我们的输出包含两个,一个是预测结果是8,一个是预测结果不是8
通过这样的分类算法,我们就可以对输入的图片进行辨识了!
比起上一篇而言,我们的神经网络模型复杂了很多,但是这对于计算机而言,都是小case!
接下来,我们就可以开始训练我们的神经网络模型了,让机器学会辨识图像里面的数字,当我们输入一个手写数字为8的图像时,我们告诉机器,你听好了这是8,当我们输入一个手写数字不是8的图像时,我们告诉机器,你也听好了,这不是8。
如图所示,是我们部分训练集!包含0-9手写数字。
这个是TensorFlow的入门课程,这里我就不仔细说下去咯。
传送门┏ (゜ω゜)=☞
https://github.com/gzdaijie/tensorflow-tutorial-samples
很简单是不是!机器学习是不是也不是那么的难!
但是好像又不是那么的简单!
上面的图片和下面的图片区别在于:数字不居中
但是这样在现实世界中好像不合理!写字很可能就写偏了是不!
让我们来想一想解决方案:
方案一:使用滑动窗口搜索
目前我们的模型已经可以识别手写数字8了,现在我们要做的只是想让手写数字8居于区域的中间,我们可不可以采用滑动窗口平移我们的待识别区域,使得数字8刚好落在识别区域的中间!
这种方式称为滑窗法!在有限作用域的情况下,可以很好的工作!但是效率比较低!需要在一幅图片上进行不断的尝试!
方案二:使用更多的训练数据进行训练
因为我们在初始训练的时候,我们的训练集中只包含了手写数字8位于正中间的图像,如果我们的训练集中包含更多一些手写数字8不位于正中间的图像,那么训练出来的模型就可以更好的work了!
我们甚至都不需要重新制作新的手写图像,我们可以通过简单的平移放缩和旋转就可以生成所需要的数据集!
但是于此同时,我们又需要更复杂的网络结构来拟合这些数据。
上述的结构,在原来单层神经网络的基础上又增加了几层,姑且就称之为:“深度神经网络”吧!
之前,训练很复杂的神经网络如果单使用CPU的话超级慢,好在学者们发现显卡可用于加速计算,推动了现在深度神经网络的高速发展!
但是纵观我们有了很先进的设备,但是总不能一直将神经网络一层一层的堆叠下去吧!我们需要一些其他的解决方案!
我们继续回想手写数字识别这个问题!
现在模型的问题在于:位置的偏差导致模型不work!
好在科学家们比较厉害!解决办法就是:卷积
优秀的你,是不是一眼就看出来这幅图片里面有个小孩子骑着一个玩具马!不管周围的环境多么的复杂,我们都可以一眼就辨识出来这个小孩就在这副图片里面!
但是我们现有的模型肯定就分辨不出来,它竟然认为事物的本质与其所处的位置有关系!
我们需要让我们的模型理解:事物其平移不变型的特征!8就是8,不管处在什么位置,它都是8!我就是我,不管在哪儿,我还是我!(哈哈哈)
所以,我们需要借助:无论物体出现在图片的任何地方,它总是一致的。这一思想来解决这个问题!
第一步:我们将图片进行分割,然后采用跟上述滑窗思想类似的手段,让滑动窗口在分割出来的小图片上进行滑动!
第二步:我们对每个小图片进行模型计算
在这个过程中,中间的小神经网络对于所有的小图片都是一样的,我们对每个小图片都一视同仁!
第三步:我们将每个小图片的输出结果进行保存!并且输出结果的排列方式与原图像中小图片的排列方式一样!
换句话说,我们将原图像通过模型计算,将其转化为了信息更为简化的数组,这个数组里面保存着原图像中最有意义的信息!
第四步:采样
在第三步得到的数组好像还是太过于冗余了,信息量还是太大了,我们可以继续对其进行简化!
我们采用的是max pooling的思想,即只选择指定区域里面最大的值作为该区域的信息表征!
最后一步:我们就可以使用我们改造后的模型进行预测了!
我们将上述通过采样得到的数据作为我们上篇提到的单层神经网络(其名为全连接神经网络)的输入,最后对结果进行判定即可!
整个网络模型如下图所示:
过程包括为:卷积层、池化层、全连接层等!
在解决实际问题的时候,上述结构可以任意的进行堆叠,达到模型效果!其中卷积的个数越多,卷积层的数量越多,原图像中信息提取的就越丰富,就可以进行更为复杂的目标检测或识别任务!
比如:第一个卷积可以用于识别猫的耳朵,第二个卷积用于识别猫的嘴巴等。
看看下面一个较为复杂的网络结构。
你就知道卷积的厉害之处了吧!
你可能会说,好简单哦,但是往往事情本身还是比较复杂滴!
想要训练得到一个较为优秀的卷积神经网络,不仅参数调优还需要结构调整,机器学习的过程需要不断的尝试!
来点儿实际的吧!!!
鸟类识别器走起~
首先数据报告一下,
CIFAR10 data set
6,000 pictures of birds and 52,000 pictures.
Caltech-UCSD Birds-200–2011 data set
12,000 bird pics.
讲道理哈,咱们的数据量还是很小很小的!想谷歌类似的企业其数据量都是千万级别亿级别的!
In machine learning, having more data is almost always more important that having better algorithms
随着训练次数的增加,模型的精度也会逐渐变优!差不多50轮迭代之后,可以到达95.5%左右!
可是采用上面的脚本对模型进行检验,相信大家训练模型的时候,都懂得规矩吧!
训练集-验证集-测试集(当然你还可以有自己的划分方式,只要确保你进行测试的数据没有在训练过程中使用到即可)
(训练集(80%数据)用于训练模型-验证集(10%数据)用于检验模型训练效果-测试集(10%数据)用于测试模型最终性能)
使用测试集进行测试得到的模型准确率为95%左右!
结果好像非常的棒!但是事实真的是这样嘛!如果我们的测试集里面一共1000张照片,里面有50张鸟的照片,950张不是鸟的照片,模型只要都将图片判定为不是鸟,就可以达到95%的准确率了!但是这样的模型没有任何的意义!
所以我们采用另外一种评定模型性能的方式。
-
图像中是鸟并且模型识别为也是鸟:称其为真阳性
-
图像中不是鸟并且模型识别不是鸟:称其为真阴性
-
图像中不是鸟但是模型偏识别为鸟:称其为假阳性
-
图像中是鸟但是模型识别为不是鸟:称其为假阴性
我们将测试集中的鸟类的图片按照上述的评定方式进行统计:
之所以这样做,是因为很多事情犯错的成本或者成功的收益往往是不对等的!比如说:癌症检测,假阴性比假阳性要坏的多;人脸识别,假阳性比假阴性要坏的多!
采用这种方式,我们就可以计算出模型的精准率和召回率,而不是单单采用模型准确率来对模型进行评判!
精准率告诉我们模型有97%的概率能够猜对是鸟!
召回率告诉我们模型只能找到数据集中91%的鸟!
如果你想学习更多,这里有更多的例子供你学习:
https://github.com/tflearn/tflearn/tree/master/examples#tflearn-examples
#机器学习##深度学习##算法工程师#