我虽然乐于帮助读者解决问题,但实话实说,一开始不太理解这种需求。
我文章里的样例图片(哆啦a梦和瓦力),都是从网络搜集来的。如果你需要从网上找到跟某张图片近似的图像,可以使用Google的“以图搜图”功能啊。
进群:125240963 即可获取数十套PDF哦!
你于是很想搞清楚这种鸟类的出现时间、生活状态等。这就需要从大量图片里,找到与其近似的图片(最有可能是拍到了同一种鸟)。
这种图片集合,也许是社会安全数据。例如你在反恐部门,系统突然发现某个疑似恐怖分子出现在敏感区域。这家伙每一次现身,都伴随着恶性刑事案件的发生,给人民群众的生命财产安全带来严重威胁。
这时候无论对其衣着、外貌还是交通工具的相似度搜索,就显得至关重要了。
上述例子中,因为你都没有把图像上传到互联网,Google的“以图搜图”引擎功能再强大,也无能为力。
doraemon的目录下,都是各式各样的蓝胖子图片。
瓦力目录下的图片是这个样子的:
数据已经有了,下面我们来准备一下环境配置。
环境
本文中,我们需要使用到苹果公司的机器学习框架TuriCreate。
请注意TuriCreate发布时间不久,目前支持的操作系统列表如下:
这就意味着,如果你用的操作系统是Windows 7及以下版本,那么目前TuriCreate还不支持。如需使用,有两种办法:
解决了系统兼容性问题,下面我们在TuriCreate支持的系统中,安装Python集成运行环境Anaconda。
请到这个网址 下载最新版的Anaconda。下拉页面,找到下载位置。根据你目前使用的系统,网站会自动推荐给你适合的版本下载。我使用的是macOS,下载文件格式为pkg。
下载页面区左侧是Python 3.6版,右侧是2.7版。请选择2.7版本。
双击下载后的pkg文件,根据中文提示一步步安装即可。
装好Anaconda后,我们安装TuriCreate。
请到你的“终端”下面,进入咱们刚刚下载解压后的样例目录。
这样就进入到了Jupyter笔记本环境。我们新建一个Python 2笔记本。
浏览器里出现了一个空白笔记本。
点击左上角笔记本名称,修改为有意义的笔记本名“demo-python-image-similarity”。
准备工作完毕,下面我们就可以开始编写程序了。
代码
首先,我们读入TuriCreate软件包。
data包含两列信息,第一列是图片的地址,第二列是图片的长宽描述。
下面我们要求TuriCreate给数据框中每一行添加一个行号。这将作为图片的标记,好在后面查找图片时使用。
把鼠标悬停在某张缩略图上面,就可以看到对应清晰大图。
第一张图片,是哆啦a梦:
第二张图片,是瓦力:
下面,是重头戏。我们让TuriCreate根据输入的图片集合,建立图像相似度判别模型。
确认无误,还是那张哆啦a梦。
下面我们来查询,我们让模型寻找出与这张图片最相似的10张。
similar_images = model.query(data[0:1], k=10)
复制代码
很快,系统提示我们,已经找到了。
我们把结果存储在了 similar_images 变量里面,下面我们来看看其中都有哪些图片。
similar_images
复制代码
返回的结果一共有10行。跟我们的要求一致。
每一行数据,包含4列。分别是:查询图片的标记
获得结果的标记
结果图片与查询图片的距离
结果图片与查询图片近似程度排序值
你可以自己数一数,其中标为1的那些图片位置,和我们存储在 similar_image_index 中的数字是否一致。
验证完毕以后,请执行以下语句。我们再次调用TuriCreate的 explore() 函数,展现相似度查询结果图片。
data[filtered_index].explore()
复制代码
系统会弹出以下对话框:
我们可以看到,全部查询结果图片中,只出现了哆啦a梦。瓦力的图片,一张都没有出现。
近似图片查找成功!
在全连接层(Fully Connected Layer)之前,你可能进行了多次的卷积、抽样、卷积、抽样……这些中间层次,帮我们描绘了图片的一些基本特征,例如边缘大概是个什么形状,某个区块主要的颜色是哪些等。
到了全连接层,你只剩下了一组数据,这组数据可能很长,它抽取了你输入数据的全部特征。
如果你的输入是一只猫,此时的全连接层里就描述了这只猫的各种信息,例如毛发颜色、面部组成部分排列方式、边缘的形状……
这个模型可以帮你提取猫的特征,但它并不知道“猫”的概念是什么。
你自然可以用它帮你提取一条狗的特征。
同理,哆啦a梦的照片,与猫咪的照片一样,都是二维图片,都是用不同颜色分层。
那用其他图片训练的模型,能否提取哆啦a梦照片里的特征呢?
当然也可以!
使用迁移学习的关键,在于冻结中间过程的全部训练结果,直接把一幅图,利用在 其他图片集合上训练的模型,转化为一个特征描述结果。
后面的工作,只把这个最后的特征描述(全连接层),用来处理分类和相似度计算。
前面的好几十层参数迭代训练,统统都被省却了。
难怪可以利用这么小的数据集获得如此高的准确度;也难怪可以在这么短的时间里,就获得整合后的模型结果。
把在某种任务上积累下的经验与认知,迁移到另一种近似的新任务上,这种能力就叫做迁移学习。
比起机器来,人的迁移学习能力更为强大。
雨果奖作者郝景芳在最近的一篇文章里,描述了人的这种强大学习能力:
小孩子可以快速学习,进行小数据学习,而且可以得到「类」的概念。小孩子轻易分得清「鸭子」这个概念,和每一只具体不同的鸭子,有什么不同。前者是抽象的「类」,后者是具体的东西。小孩子不需要看多少张鸭子的照片,就能得到「鸭子」这个抽象「类」的概念。
网友评论