8.5 构建图像相似度的引擎
如果你一直读到现在,那么现在可以开始享受成果了。我们将利用人工智能的强大力量做一些真正重要的事情。我们将找到你的灵兽。嗯,不完全是。我们将使用它,在CIFAR-10图像数据集中找到最像你的猫。CIFAR-10是什么?这个数据集是用作计算机视觉研究标准的一组图像。它包括10个分类,成千上万的图像,例如狗、青蛙,飞机和汽车等等。不过,对我们而言最重要的是,其中包括猫。
现在,我们需要理解在所有讨论的算法中,深度学习往往是最强大的,但同时对于“家庭使用者”也是最不友好的。我的意思是,相对于其他算法,深度学习通常需要更长的训练时间、更多的计算能力。事实上,这也是神经网络架构没有被快速接受的原因之一。随着较便宜的GPU(图形处理单元)出现,它才成为研究人员的可选项之一。
鉴于此,我们将采取两大措施来减少模型的处理时间。
第一个措施是利用GraphLab Create。它是一个很流行的大规模机器学习框架。它提供了一个很好的API,有点像pandas和scikit-learn的结合。通常,它是收费的服务——需要许可证,但是对于学术用途是免费的,似乎还包括了Bootcamps和大规模在线公开课程(MOOC),如Coursera。请务必阅读该站点的说明细节。
Graphlab的安装很简单。细节可以在这里找到:https://dato.com/download/ install-graphlab-create-command-line.html。基本上,它只需要填写表单就可以获取许可证,然后复制并粘贴它提供的pip命令。
注意,你必须使用Python 2.7。Python 3目前还不支持这些。
缩短处理时间的下一个措施是使用被称为迁移学习的东西。迁移学习的基本思想是利用大规模的、高度训练的、针对某项具体任务的深度学习网络的能力。然后,我们砍掉这些网络的最高层,以使用较低层作为特征,让其运作在没有受过训练的任务中。请记住,在事物的综合表示方面,较低层的特殊性更少。在数字识别的世界中,较低层可以表示环状或直线,而较高层更多的是关注0或1。在大象识别的世界中,低层更多的是关于扇子和树干。在迁移学习中,我们可以提取这些较低级别的特征,以便将它们应用到新的领域——那些它们没有专门受训过的领域。
本节中的很多信息都参考了有关机器学习基础的Coursera课程,可用这里访问:https://www. coursera.org/learn/ml-foundations。如果你有兴趣深入研究这些材料,我强烈推荐你阅读它。
有了这些,让我们开始编码。灵兽等着我们呢。
我们将从包的引入开始。
import graphlab graphlab.canvas.set_target('ipynb')
接下来,我们从CIFAR-10数据集中加载将要使用的一组图像。
gl_img = graphlab.SFrame('http://s3.amazonaws.com/dato-datasets/coursera/ deep_learni ng/image_train_data') gl_img
这将产生图8-22的输出。
图8-22
你会看到几列标识信息,例如编号和标签,你还会注意到名为“深度特征”的列。这些特征是从一个大规模的、经过训练的深度学习网络提取而来。稍后我们将解释如何使用它们。现在,让我们继续。
使用下面的代码,我们可以观察一下图像。
gl_img['image'][0:5].show()
这将产生图8-23的输出。
图8-23
不幸的是,图片非常小,但你可以调整它们的大小,让其看得稍微清楚些。
graphlab.image_analysis.resize(gl_img['image'][2:3], 96,96).show()
这将产生图8-24的输出。
现在,所有用于比较的图片都已经加载完毕了,我们只需要加载自己的照片。我会加载自己的一张照片,它应该适用于这个任务。当然,你需要在该位置加载你自己的。
img = graphlab.Image('/Users/alexcombs/Downloads/profile_pic.jpg') ppsf = graphlab.SArray([img]) ppsf = graphlab.image_analysis.resize(ppsf, 32,32) ppsf.show()
这将产生图8-25的输出。
图8-24
图8-25
接下来,我们需要将该图像放入包含之前训练图像的数据框中。但是,要做到这一点,我们首先需要提取其特征。具体如下。
ppsf = graphlab.SFrame(ppsf).rename({'X1': 'image'}) ppsf
上述代码生成图8-26的输出。
现在,我们将提取图像的深度特征。
ppsf['deep_features'] = deep_learning_model.extract_features(ppsf) ppsf
上述代码生成图8-27的输出。
图8-26
图8-27
此刻,我们只需要一些最后的操作,就能让自己的照片与训练的图片拥有同样的格式。
ppsf['label'] = 'me' gl_img['id'].max()
上述代码生成图8-28的输出。
图8-28
我们看到数据框中最大的ID编号为49,970。我们为自己照片分配的编号为50,000,这样做只是为了便于记忆。
ppsf['id'] = 50000 ppsf
上述代码生成图8-29的输出。
图8-29
差不多快好了,现在我们将使用这些列来连接所有的内容。
labels = ['id', 'image', 'label', 'deep_features'] part_train = gl_img[labels] new_train = part_train.append(ppsf[labels]) new_train.tail()
这将产生图8-30的输出。
图8-30
好吧,我们现在有一个很大的数据框架,包含所有的图像,以及表示为向量的图像深度特征。此时,我们可以使用非常简单的模型来找到最相似的图像。
我们首先使用k-最近邻居模型,将某个随机选取的猫和集合中其他的猫进行比较,感觉一下我们的模型效果如何。
knn_model = graphlab.nearest_neighbors.create(new_train,features=['deep_ features'], label='id')
上述代码生成图8-31的输出。
图8-31
让我们看看被测试的小猫。
cat_test = new_train[-2:-1] graphlab.image_analysis.resize(cat_test ['image'], 96,96).show()
这将产生图8-32的输出。
图8-32
因此,这个可爱的像素化小怪物就是我们的测试主角。让我们找到和它面貌相似的其他小猫。
sim_frame = knn_model.query(cat_test) sim_frame
上述代码生成图8-33的输出。
图8-33
最后让我们看看匹配上的小猫们。
def reveal_my_twin(x): return gl_img.filter_by(x['reference_label'],'id') spirit_animal = reveal_my_twin(knn_model.query(cat_test)) spirit_animal['image'].show()
这将导致图8-34的输出。
图8-34
这就是结果。每个图像是一只猫,我觉得它们看起来都很像被测试的小猫。
让我们再运行一次,选择另一只小猫。这里我省略了代码,只是给你看看被测试的猫和相似查找的结果。
首先,这是被测试的对象,如图8-35所示。
图8-35
现在是相似度匹配的结果,如图8-36所示。
图8-36
对于编号145的图片,我必须承认这个匹配相当不错。然而,现在,到了我们一直期待的时刻。让我们揭示我的动物双胞胎。
me_test = new_train[-1:] graphlab.image_analysis.resize(me_test['image'], 96,96).show()
这将产生图8-37的输出。
图8-37
现在,我们运行一次搜索,查找和我的照片最匹配的图片。
sim_frame = knn_model.query(me_test) sim_frame
上述代码生成图8-38的输出。
图8-38
现在,我们加载结果。
graphlab.image_analysis.resize(spirit_animal['image'][0:1], 96,96).show()
这将产生图8-39的输出。
图8-39
我觉得还行。我认为自己戴的帽子决定了一切,但我一定会接受它作为我的灵兽。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论