独一无二的雪花

2022-03-29 19:48:27 浏览数 (2)

每片雪花都是独一无二的,但有些雪花必须比其他雪花少

好吧,我承认,这个标题有点让人想到另外一家公司Snowflake,但我们这里讲的是现实中的雪花!我在山上度过了假期,如果你和我一样住在北半球,你知道这意味着我在假期里要么庆祝雪,要么诅咒雪。当我还是个孩子的时候,在每年的这个时候,我们总是会做一个制作雪花的艺术项目。我们会拿出剪刀、胶水、纸、绳子和亮片,然后开始工作。在某些时候,老师无疑会拿出重弹,让我们大吃一惊,因为整个世界上的每一片雪花一直都是不同的和独一无二的(人们只是喜欢过度推销不起眼的雪花特征)。

现在我是一个成熟的成年人,一切都弄清楚了(停顿一下),我开始怀疑雪花的独特性。我们说它们都是独一无二的,但有些必须比其他的更独特。有什么方法可以量化雪花的独特性,从而找到最独特的雪花

当然,使用现代机器学习技术,这样的任务不仅应该是可能的,而且我敢说,微不足道吗?将雪花与 ML 结合起来可能听起来像是一个新想法,但现在是时候有人这样做了。在 Cloudera,我们为客户提供了一个广泛的预构建数据科学项目库(包括开箱即用的模型和应用程序),称为 Applied ML Prototypes (AMP),以帮助他们将项目的起点移近终点线。

关于 AMP,我最喜欢的一点是它们是完全开源的,这意味着任何人都可以使用它们的任何部分来做任何他们想做的事情。是的,它们是完整的 ML 解决方案,只需在Cloudera 机器学习(CML)中单击即可部署,但它们也可以重新用于其他项目。AMP 由 Cloudera 的Fast Forward Labs的 ML 研究工程师开发,因此它们是 ML 最佳实践和代码片段的重要来源。它是数据科学家工具箱中的另一个工具,可用于让他们的生活更轻松并帮助更快地交付项目。

启动 AMP

在这篇博客中,我们将深入研究如何重用深度学习图像分析AMP 来寻找彼此不太相似的雪花。如果您是 Cloudera 客户并且可以访问 CML 或 Cloudera Data Science Workbench (CDSW),则可以从“AMPs”选项卡中部署 Deep Learning for Image Analysis AMP 开始。

如果您无权访问 CDSW 或 CML,AMP github 存储库有一个自述文件,其中包含在任何环境中启动和运行的说明。

数据采集

一旦您启动并运行 AMP,我们就可以从那里开始。在大多数情况下,我们将能够重用现有代码的一部分。但是,因为我们只对比较雪花感兴趣,所以我们需要带上自己的数据集,该数据集仅由雪花组成,而且有很多数据。

事实证明,公开可用的雪花图像数据集并不多。这并不是一个巨大的惊喜,因为拍摄单个雪花的图像将是一个手动密集型过程,回报率相对较低。但是,我确实从东印第安纳大学找到了一个很好的数据集,我们将在本教程中使用它。

您可以单独浏览并从网站下载每个图像,也可以使用其他应用程序,但我选择了一个快速笔记本来下载图像并将其存储在项目目录中。您需要将它放在/notebooks 子目录中并运行它。该代码从包含雪花图像的链接网页中解析出所有图像 URL 并下载图像。它将在/notebooks/images中创建一个名为雪花的新子目录,脚本将使用雪花图像填充这个新文件夹。

像任何优秀的数据科学家一样,我们应该花一些时间来探索数据集。您会注意到这些图像具有一致的格式。它们的颜色变化非常小,背景相对恒定。计算机视觉模型的完美游乐场。

重新利用 AMP

现在我们有了数据,而且它看起来非常适合图像分析,让我们花点时间重申我们的目标。我们想量化单个雪花的独特性。根据其描述,用于图像分析的深度学习是一种 AMP,它“展示了如何在图像数据集上构建可扩展的语义搜索解决方案”。传统上,语义搜索是一种 NLP 技术,用于提取搜索词的上下文含义,而不仅仅是匹配关键字。此 AMP 的独特之处在于它将这一概念扩展到图像而不是文本,以查找彼此相似的图像。

该 AMP 的目标主要集中在向用户介绍深度学习和语义搜索的工作原理。在 AMP 内部有一个位于/notebooks的笔记本,标题为Semantic Image Search Tutorial。它为整体解决方案的两种主要技术——特征提取和语义相似性搜索——提供了实用的实施指南。这个笔记本将成为我们雪花分析的基础。继续打开它并运行整个笔记本(因为它需要一点时间),然后我们将看看它包含什么。

笔记本分为三个主要部分:

  1. 语义图像搜索的概念概述
  2. 使用 CNN 和演示代码提取特征的说明
  3. 使用 Facebook 的 AI 相似度搜索 (FAISS) 和演示代码解释相似度搜索

笔记本第 1 节

第一部分包含有关语义搜索的端到端过程如何工作的背景信息。本节没有可执行代码,因此我们无需运行或更改任何内容,但如果时间允许并且主题对您来说是新的,您应该花时间阅读。

笔记本第 2 节

第 2 节是我们将开始进行更改的地方。在带有可执行代码的第一个单元格中,我们需要将变量ICONIC_PATH设置为等于我们的新雪花文件夹,因此更改

代码语言:javascript复制
ICONIC_PATH = “../app/frontend/build/assets/semsearch/datasets/iconic200/”app/frontend/build/assets/semsearch/datasets/iconic200/”

代码语言:javascript复制
ICONIC_PATH = "./images/snowflakes"

现在运行这个单元格和下一个单元格。您应该会在之前有汽车图像的位置看到显示的雪花图像。笔记本现在将只使用我们的雪花图像来执行语义搜索。

从这里开始,我们实际上可以运行第 2 节中的其余单元格,并将代码保持原样,直到第 3 节,使用 FAISS 进行相似性搜索。不过,如果您有时间,我强烈建议您阅读本节的其余部分,以了解正在发生的事情。加载预训练的神经网络,在神经网络的每一层保存特征图,并将特征图可视化以进行比较。

笔记本第 3 节

第 3 部分是我们将进行大部分更改的地方。通常使用语义搜索,您试图找到彼此非常相似的事物,但对于我们的用例,我们感兴趣的是相反的,我们希望在这个数据集中找到与其他数据最不相似的雪花,也就是最独特的。

笔记本中这部分的介绍很好地解释了 FAISS 的工作原理。总而言之,FAISS 是一个库,它允许我们将特征向量存储在高度优化的数据库中,然后使用其他特征向量查询该数据库以检索最相似的向量(或多个向量)。如果您想深入了解 FAISS,您应该阅读Hervé Jegou、 Matthijs Douze、 Jeff Johnson来自 Facebook 工程网站的 这篇文章。

原始笔记本关注的一个教训是,从最后一个卷积层输出的特征如何更抽象和更概括地表示模型认为重要的特征,尤其是与第一个卷积层的输出相比时。本着 KISS 的精神(保持简单愚蠢),我们将把这一课应用到我们的分析中,只关注最后一个卷积层 b5c3 的特征索引,以便找到我们最独特的雪花。

前 3 个可执行单元中的代码需要稍作修改。我们仍然想提取每个图像的特征,然后为特征集创建一个 FAISS 索引,但我们只会对来自卷积层 b5c3 的特征执行此操作。

代码语言:javascript复制
# Cell 1
def get_feature_maps((model, image_holder):
    # Add dimension and preprocess to scale pixel values for VGG
    images = np.asarray(image_holder)
    images = preprocess_input(images)
    # Get feature maps
    feature_maps = model.predict(images)
    # Reshape to flatten feature tensor into feature vectors
    feature_vector = feature_maps.reshape(feature_maps.shape[0], -1)
    return feature_vector
代码语言:javascript复制
# Cell 2
all_b5c3_features = get_feature_maps(b5c3_model, iconic_imgs)
代码语言:javascript复制
# Cell 3
import faiss

feature_dim = all_b5c3_features.shape[1]
b5c3_index = faiss.IndexFlatL2(feature_dim)
b5c3_index.add(all_b5c3_features)

这是我们将开始显着偏离源材料的地方。在原始笔记本中,作者创建了一个函数,允许用户从每个索引中选择特定图像,该函数返回每个索引中最相似的图像并显示这些图像。我们将使用该代码的一部分来实现我们的新目标,找到最独特的雪花,但是为了本教程的目的,您可以删除其余的单元格,我们将介绍在它们的位置添加的内容.

首先,我们将创建一个函数,该函数使用索引来检索与所选索引第二最相似的特征向量(因为最相似的将是同一张图像)。数据集中也恰好有几个重复的图像,所以如果第二个最相似的特征向量也是完全匹配的,我们将使用第三个最相似的。

代码语言:javascript复制
def get_most_similar((index, query_vec):
    distances, indices = index.search(query_vec, 2)
    if distances[0][1] > 0:
        return distances[0][1], indices[0][1]
    else:
        distances, indices = index.search(query_vec, 3)
        return distances[0][2], indices[0][2]

从那里只需遍历每个特征,搜索不是完全相同的图像的最相似图像,并将结果存储在列表中:

代码语言:javascript复制
distance_list = []
for x in range((b5c3_index.ntotal):
    dist, indic = get_most_similar(b5c3_index, all_b5c3_features[x:x 1])
    distance_list.append([x, dist, indic])

现在我们将导入 pandas 并将列表转换为数据框。这为我们提供了每一层的数据框,包含原始 FAISS 索引中每个特征向量的一行,带有特征向量的索引,与其最相似的特征向量的索引,以及两者之间的 L2 距离特征向量。我们很好奇离它们最相似的雪花最远的雪花,所以我们应该以 L2 距离升序对数据帧进行排序来结束这个单元格。

代码语言:javascript复制
import pandas as pd
df = pd.DataFrame(distance_list, columns = ['index', 'L2', 'similar_index'])
df = df.sort_values('L2', ascendingascending=False)

让我们通过打印数据框以及在箱线图中显示 L2 值来看看结果。

代码语言:javascript复制
df.boxplot('L2')
df.head()

惊人的东西。我们不仅找到了与它们最相似的雪花最不相似的雪花的索引,而且我们在箱线图中发现了一些明显的异常值,其中一个是独立的。

最后,我们应该看看那些超级独特的雪花实际上是什么样子,所以让我们在左侧的列中显示前 3 个最独特的雪花,在右侧的列中显示它们最相似的雪花对应物。

代码语言:javascript复制
fig, ax = plt.subplots(nrows=3, ncols=2, figsize=(12, 12))
i = 0
for row in df.head(3).itertuples():
    # column 1
    ax[i][0].axis('off')
    ax[i][0].imshow(iconic_imgs[row.index]/255,)
    ax[i][0].set_title('Unique Rank: %s' % (i 1), fontsize=12, loc='center')
    ax[i][0].text(0.5, -0.1, 'index = %s' % row.index, size=11, ha='center', transform=ax[i][0].transAxes)
代码语言:javascript复制
# column 2
    ax[i][1].axis('off')
    ax[i][1].imshow(iconic_imgs[row.similar_index]/255)
    ax[i][1].set_title('L2 Distance: %s' % (row.L2), fontsize=12, loc='center')
    ax[i][1].text(0.5, -0.1, 'index = %s' % row.similar_index, size=11, ha='center', transform=ax[i][1].transAxes)
    i  = 1
代码语言:javascript复制
fig.subplots_adjust(wspace=-.5656, hspace=.55)
plt.show()

这就是 ML 方法如此出色的原因。没有人会看到第一片雪花并认为那是一片超级独特的雪花,但根据我们的分析,它是迄今为止与下一个最相似的雪花最不相似的。

结论

现在,您可以使用多种工具和 ML 方法,您可以利用它们来寻找独特的雪花,包括那些被过度炒作的雪花。使用 Cloudera 的 Applied ML Prototypes 的好处在于,我们能够利用现有的、完全构建的、功能强大的解决方案,并根据我们自己的目的对其进行更改,从而比我们从头开始时更快地获得洞察力。女士们先生们,这就是 AMP 的全部意义所在!

为了您的方便,我在 github 上提供了最终生成的笔记本。如果您对更快地完成项目感兴趣(更好的问题 - 谁不是?)您还应该花时间查看其他AMP中的哪些代码可用于您当前的项目。只需选择您感兴趣的 AMP,您就会在 GitHub 上看到一个查看源代码的链接。毕竟,从法律上讲,谁不会对在接近终点线的地方开始比赛感兴趣呢?亲自试驾一下 AMP。

原文作者:Jacob Bengtson

原文链接:https://blog.cloudera.com/the-most-unique-snowflake/

0 人点赞