CNN 可以检测图像相似度吗?

人工智能 卷积神经网络 相似
2021-11-09 09:18:20

我一直在进行一些实验,看看 CNN 是否可以检测两个图像是否相同。但是,我似乎无法让它工作。我想知道 CNN 是否无法做我正在尝试的事情,或者我是否犯了错误。

这是设置:我拍摄了两张 128x128 的图像并将它们附加为 128x256。这两个图像要么完全相同: 两个“相同”类的图像 要么不同: 'not_same' 类的两张图片

我还尝试过中间的黑条。整个附加的 128x256 图像(因此包含两个图像)被输入到具有以下设置的 CNN 中: 在此处输入图像描述

根据 dropout 的使用情况,该模型能够以 80-100% 的准确率学习训练数据。但验证准确率从未超过 65%。

我不明白为什么模型不能很容易地达到 100%,因为输入图像要么完全相同,要么非常不同。对我来说似乎是一项微不足道的任务。我会假设卷积核会创建完全相同的图像特征表示,然后将其输入密集层。

附言。我知道有更好的方法可以做到这一点,但我想尝试一下。

1个回答

一个有趣的问题:该模型似乎对训练数据的拟合不足(因为准确度不是那么高),但它对训练数据的拟合也不足。:)

当您展平数据并使用密集层时,您会丢失所有空间信息。在你这样做之前,你可能想从右侧减去输出的左侧(我计算它的大小为 15x30x128,所以一半是 15x15x128?)。这对模型来说有点棘手Sequential,但可以通过一个Lambda层来完成。请注意,张量的第一个维度是None,实际上是训练期间的批大小。

完成此操作后,您可以保持当前的扁平 + 密集结构,看看它是如何进行的。虽然我认为此时它可以简单得多,但 Conv2d 正在做繁重的工作。

您可能还想在模型的早期部分添加 dropout,或者使用足够的数据增强来避免过度拟合。中间的黑条挡住了图像,使它们非常不相同。

或者,您可以制作一个单一的特征提取模型并分别提供这两个输入。这种架构称为Siamese Network,需要更多代码来实现(文章中的示例,但是它使用 PyTorch,与 Keras 相比显得相当冗长)。

实际上,第一个建议也是连体网络,只是结构有点奇怪,只有一个输入。我很想知道这是否更适合您。

编辑:我决定自己尝试这个问题。使用上面描述的想法,使用具有 194 个参数的模型,我在甚至不完全相同的图像上获得了 99% 的验证准确率。一半的示例具有不同的图像,另一半是参考的修改副本(随机 +/- 10 度旋转,+/- 10% 的 TF 缩放ImageDataGenerator)。

如果您想自己弄清楚,我不会分享代码,但这里是显示数据流的摘要(使用SequentialAPI):

Model: "sequential_173"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_132 (Conv2D)          (None, 126, 254, 3)       84        
_________________________________________________________________
max_pooling2d_88 (MaxPooling (None, 63, 127, 3)        0         
_________________________________________________________________
conv2d_133 (Conv2D)          (None, 61, 125, 3)        84        
_________________________________________________________________
max_pooling2d_89 (MaxPooling (None, 30, 62, 3)         0         
_________________________________________________________________
lambda_60 (Lambda)           (None, 30, 30, 3)         0         
_________________________________________________________________
average_pooling2d_47 (Averag (None, 5, 5, 3)           0         
_________________________________________________________________
lambda_61 (Lambda)           (None, 5, 5)              0         
_________________________________________________________________
flatten_52 (Flatten)         (None, 25)                0         
_________________________________________________________________
dense_435 (Dense)            (None, 1)                 26        
=================================================================
Total params: 194
Trainable params: 194
Non-trainable params: 0
_________________________________________________________________

它采用“双”RGB 图像,并应用Conv2D两层,每层只有 3 个内核。这会导致30 x 31 x 3图像特征成形(输出的宽度max_pooling2d_89实际上是62因为有两个图像并排)。

将两侧相减(去掉中间列),然后对结果进行下采样和聚合,得到5 x 5输出。最后Dense一层只是sigmoid预测图像是否几乎相同。

示例结果如下所示。它有六列图像:左图像、右图像、左特征(conv2d_133的输出)、右特征、特征差异和加权特征差异。最后一列显示该模型已经学会更多地关注图像的中心而不是角落,因为使用的图像增强最容易扭曲角落。

结果示例

如果图像被下采样到层1 x 1之前,Flatten那么模型只有 170 个参数,但验证准确率会下降到 97%。编辑 2:使用elu而不是tanh激活使该模型的准确度达到 99.3%,我最初使用tanh它是因为由于其范围有限,它很容易可视化为图像)

使用的数据集是Indoor Scene Recognition,其中我使用了 2000 张随机图像。