神经网络 - 查找最相似的图像

数据挖掘 Python 神经网络 喀拉斯
2021-10-13 04:31:22

我正在使用 Python、scikit-learn 和 keras。我有 300 万张正面手表的图像,例如: Watch_1Watch_2Watch_3

我想编写一个程序,它接收一张真实手表的照片作为输入,这张照片可能是在比上面的照片不太理想的条件下拍摄的(不同的背景颜色、较暗的闪电等),并在 3000 块手表中找到最相似的手表。所谓相似性,我的意思是,如果我输入一张带有细花边的圆形棕色手表的照片,那么我期望输出的是圆形、深色和细花边的手表。

最有效的机器学习算法是什么?

例如,通过点击此链接,我想到了两种不同的解决方案:

1) 使用 CNN 作为特征提取器,并参考输入图像比较每对图像的这些特征之间的距离。

2) 在连体神经网络中使用两个 CNN 来比较图像。

这两个选项是完成这项任务的最佳选择,还是您会提出其他建议?

您是否知道任何用于此任务的预训练神经网络(具有预先确定的超参数)?

我在 StackOverflow 上发现了一些有趣的帖子,但它们已经很老了:Post_1Post_2Post_3

4个回答

我不认为这样的高级架构是最合适的,但它取决于许多因素和细节。据我所知,第一种方法很有希望,尤其是在通过TiefVision中所做的额外步骤进行扩展时:

  1. 额外的边界框网络用于将图像的相关部分与其余部分区分开来
  2. 特征向量不是简单地直接比较,而是用于训练一个使用三元组的比较网络(基于特征向量的相似性和更多或更少相似实例的示例)。

这项工作比您发布的内容更新得多(2016/17),并附带了一个不错的工具集和更详细的论文

为什么使用三元组又名深度排名?

如评论中所述:为什么要使用三元组来进行图像相似性而不是学习特征向量并计算它们的距离?三元组是一种将相似性问题表述为学习问题的方法,而不是学习基本上不关心相似性的特征向量。这种方法在人类感知相似性很重要的情况下特别有意义,这可能与机器感知不同。

三胞胎的工作方式如下:您提供 3 张图像。一个比较,一个相似(接近)和一个不太相似(远)的图像。这是您的训练/测试/验证数据。在这些样本上训练你的网络并预测正确的顺序(从不相似的图像中分类相似)让网络学习如何根据图像的相似性对图像进行排序。

总而言之,这种方法比较复杂。它可能被过度设计,但您也要求最好的方法来做到这一点,并且深度排名可以实现非常高的精度值。

我会选择一个分类器,比如 VGG-16,它在 imagenet 类上效果很好。然后,通过它运行您的手表图像。当然,您可以期望输出大部分是“观看”的可能性很大。

但是,您会获得额外的功能:所有其他类别的激活级别。这为您提供了一个包含 0 到 1 之间的一千个值的向量。

您还可以在网络中的各个点提取激活。然后,只有当图像相似时,这些激活和输出的相似性才应该在两种情况下相似。

我会首先关注数据增强。由于您的图像具有白色背景,因此您可以轻松一点。将白色背景变成透明背景,缩小图像,旋转并将其置于与您的目标数据相似的背景中。

使用不同的组合多次执行此操作,并为每只手表贴上标签。那么我建议你使用常规的卷积神经网络进行分类。每个标签都会有一个分数,选择具有最高置信度的一个并且应该是最相似的一个。

例如,假设您使用图像运行分类器并获得以下结果:

Watch1: 0.51

Watch2: 0.30

Watch3: 0.25

CNN 表示它有 51% 的信心认为 Watch1 是输入图像中的手表。但同样真实的是,它认为它看起来更相似,Watch2 将是下一个更相似的,依此类推。

如果你没有得到好的结果,照常做。试验参数和/或添加更多层。尝试找出失败的地方。有了这种洞察力后,您可以使用它为您的特定问题选择更专业的卷积网络类型。在事先不知道它会如何执行的情况下寻找它不是正确的方法。我建议你从一个基本的卷积模型开始,然后从那里开始工作。

我会尝试用某种自我监督的方法来训练一个神经网络,你可以拍摄所有的图像,然后以某种方式改变它们(稍微弄乱颜色、旋转、重新缩放等)和任务网络是为这两个创建嵌入,使其靠近并远离所有其他图像。

与不相似的图像相比,网络可能更难推开更多相似的图像。

例如,一种这样的自我监督方法是 SimCLR。可以值得一试。