对传入面部识别数据流进行聚类的替代方法

数据挖掘 Python 聚类
2021-09-21 09:25:34

我有一个传入面部数据的时间序列数据集。每个数据点都是一个长度为 256 的面部特征向量,代表一个人的面部特征(它由修改后的 RESNET 生成)。靠近的特征被认为属于同一个人。

我(成功地)通过 DBSCANing 对传入的面部特征进行聚类。我最近切换到 HDBSCAN 也取得了不错的效果。

我的问题是:DBSCAN 和 HDBSCAN 要求我同时拥有所有数据。我经常有超过 200,000 个功能,这可能是一个非常大的下载量。

我更希望能够获取每个传入的 f 并将其分配给一个人,而不必一次收集所有信息。

是否有替代方案(最好使用 Python 实现)?

4个回答

您正在描述增量学习,输入数据不断用于扩展现有模型的知识。

增量 DBSCAN有一个 Python 实现

当前没有增量 HDBSCAN的 Python 实现

在我看来,你真正应该做的是在数据集上训练一个(多类)分类器,然后用它来“预测”每个新的传入人脸。
如果您没有其他标签来源,您可以使用您的 DBScan 结果作为标签(即使用集群作为类标签)。

话虽这么说,从技术上讲,您可以通过与以前的样本进行比较来检查新的数据样本,但它的计算量比分类器上的推断要重,因为您需要加载数据(或更准确地说 - 中的核心点) DBScan 模型;这并没有好多少,也不适合流),而不是加载更薄、更精简的分类器模型。

Stack Overflow中的这个问题也有一些有用的讨论,以及一个示例代码片段,用于将新点与 DBScan 模型中的现有点进行比较;如果你想走那条路,你可以试试。但实际上,如果 DBScan 能够让您满意地解决您的问题,我假设您也可以使用 DBScan 集群作为标签来训练分类器。祝你好运!

我建议您使用自动编码器进行降维自动编码器是具有沙漏形状的神经网络,旨在学习数据的压缩表示。您可以先在已有的数据上对其进行训练,然后使用它一次提取压缩表示。在您的情况下,您需要一个带有卷积层的自动编码器,因为您需要处理像素数据。

一旦你训练得足够好,你就可以从你的流中一个一个地生成每个图像的表示。您可以一次加载一个而不会出现内存问题。每次生成压缩表示时,都可以将其与以前的表示进行比较。来自同一个人的两张照片最终会在潜在压缩空间中彼此非常相似。或者,您甚至可以训练一个简单的分类器来为您进行匹配(例如,如果您想匹配两张同一张脸但转向相反方向的图片,这可能特别有用)。

互联网和 GitHub 上有很多 Autoencoder 作品。在这里,我为 Python + TensorFlow 2 中的前馈编写了一个简单的教程。在您的情况下,您需要它的卷积版本。您的 Encoder 部分将需要 2D Conv 层,而 Decoder 将需要一个逆操作,可以使用 Upsampling 层或 Transpose Conv 层来完成(我已经看过这两种实现,是对两者的解释以及如何使用它们) .

中的自动编码器模型tensorflow.keras看起来像这样:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D

autoencoder = Sequential([
    # Encoder
    Conv2D(16, (3, 3), input_shape=(28,28,1) activation='relu', padding='same'),
    MaxPooling2D((2, 2), padding='same'),
    Conv2D(8, (3, 3), activation='relu', padding='same'),
    MaxPooling2D((2, 2), padding='same'),
    Conv2D(8, (3, 3), activation='relu', padding='same'),
    MaxPooling2D((2, 2), padding='same'),  # This is the compressed representation

    # Decoder
    Conv2D(8, (3, 3), activation='relu', padding='same'),
    UpSampling2D((2, 2)),
    Conv2D(8, (3, 3), activation='relu', padding='same'),
    UpSampling2D((2, 2)),
    Conv2D(16, (3, 3), activation='relu'),
    UpSampling2D((2, 2)),
    Conv2D(1, (3, 3), activation='sigmoid', padding='same')
])

这是我从这篇 Keras 博客文章中获取的带有上采样层的稍微修改的版本。或者,可以在此处找到带有 Conv Traspose 层的版本。

PS:看看这篇关于在手写数字中查找对齐的文章。不完全是您的问题,但有丰富的类比恕我直言。

当然。正如我从您的问题中得到的那样,您需要一些在线或即时方法才能将传入的类别分类为现有类别,或者可能是新的。因此,像 Kmeans 和 DBSCAN 这样的聚类技术将失败,因为正如您所说,它一次需要数据,并且从数据中学到的任何假设都只针对特定的那批数据。如果您的数据是一致的类别,您可能已经使用了该聚类模型。这里有一些我想在下面指出的解决方案:

  • 集成建模
    • 怎么可能?我假设您的数据以迭代批处理方式出现,而不是您可以为每个批处理训练模型,并记住批处理大小应该很大,以便它可以适合您的内存。最后你会得到这么多的模型在你的手中。这很好,因为它存储在磁盘上。
    • 如何使用它进行预测?现在棘手的部分从这里开始。最好将您的查询(图像矢量表示)传递给每个模型并查看每个模型的结果。再次提出的问题是什么可能是评估矩阵?对。因此,您将拥有自己的设计评估矩阵,它真正代表特定样本属于特定类别的程度。我的意思是说那种显示有多少样本或数据点属于一个类的置信度度量。你可以使用准确度、熵等,所以你将获得关于所有类或集群的分数。因为相同,每个模型返回相同。现在您将确定哪个模型自信地说该样本属于特定类或集群,因此您可以选择它并相应地处理您的输出。
    • 优点:对于每批,您将拥有不同的模型,因此您可以利用不同的假设。主要优点是您的输出将始终保持一致。所以你可能不会面临准确性下降的问题。

参考:https ://machinelearningmastery.com/ensemble-methods-for-deep-learning-neural-networks/

请查看我的解决方案并提供反馈。很高兴听到你的观点。祝你好运!