如何为数据集构建图像重复查找器?(附代码)

当您从互联网上下载图像时,通常会发现噪声数据。此外,相似的图片都在附近,一个接一个地看到它们并试图找到重复数据来清理数据集是很繁琐的。 考虑到这个问题,作者构建了一个重复的查找程序,为您找到重复项,您只需要选择是否要删除它们。您可以在fastai库(网址:https://github.com/fastai/fastai)中找到代码。在这篇文章中,作者将解释他是如何构建这个工具的。

这是算法找到的实际副本

第1步:获取激活

我们通常使用CNN对图像进行分类,只对网络末端的softmax输出感兴趣,它告诉我们网络认为图像标签是什么。在这种情况下,我们将比较网络的内层,希望网络学到的一些功能对于查找类似的图像很有用。为了实现这一点,我利用了fastai库中的强大callbacks 功能(代码页:https://docs.fast.ai/callbacks.hooks.html),它允许我们保存网络中任何子层的激活。

hook = hook_output(learn.model[0][7][2])

我使用的激活是Resnet架构的最后一个卷积块的输出,因为我注意到它们在经验上更好地工作。

第2步:合并

您可能知道,CNN中的隐藏层有四个维度:批量大小、高度、宽度和要素数量。假设我们正在谈论一个特定的图像,或者bs = 1。例如,在Resnet 50的情况下,最后一层的输出将具有尺寸(1,7,7,248 )。由于这里的维度非常高,计算相似性会非常耗时,这对用户来说是一种痛苦。这个问题的答案是使用Pooling(网址:http://deeplearning.stanford.edu/tutorial/supervised/Pooling/)   。我们将汇集每个7x7矩阵,以便得到一个维度张量(1,pool_dim,pool_dim,2048)。

我使用的池函数是AdaptiveConcatPooling(自适应平均池和自适应最大池连接在一起),使用的池维数是4,因为我发现它是速度和性能的良好组合。

第3步:展平

我们以四个维度的张量结束了最后一步。然而,为了计算不同示例之间的相似性,我们需要一维张量(向量)。我们将展平每个图像的激活以获得大小为pool_dim x pool_dim x 512的向量,并且我们将每个图像的向量连接成具有维度(n_exs,vector_dim)的矩阵。现在我们为每个n_exs图像都有一个特征向量。是时候计算相似之处了

def get_actns(learn:Learner, dl:DataLoader, hook:Hook, pool=AdaptiveConcatPool2d, pool_dim:int=4, train:bool=True):
"""Gets the activations at the layer specified by `hook`, 
   applies `pool` of dim `pool_dim` and concatenates."""
    pool = pool(pool_dim) 
    
    actns = []
    learn.model.eval()
    with torch.no_grad():
        for i,(xb,yb) in enumerate(dl):
            learn.model(xb)
            actns.append((hook.stored).cpu())
                                    
    return pool(torch.cat(actns)).view(len(dl.x), -1)

第4步:计算相似之处

为了计算每个特征向量之间的相似性,我们将使用余弦相似度函数。请注意,如果我们将每个向量与每个其他向量组合在一起,则所有相似度将被计算两次。还要注意,如果我们计算矢量与其自身的相似性,相似性的度量显然将是最高的。因此,对于我们的相似性矩阵,我们将用零替换对角线和右上角部分。

def comb_similarity(t1: torch.Tensor, t2: torch.Tensor, sim_func=nn.CosineSimilarity(dim=0)):
    """Computes the similarity function `sim_func` between each embedding
       of `t1` and `t2` matrices.
       t1` and `t2` should have dimensions [n_embeddings, n_features]."""
    
    self_sim = False
    if torch.equal(t1, t2): self_sim = True
        
    sims = np.zeros((t1.shape[0], t2.shape[0]))
    for idx1 in range(t1.shape[0]):
        for idx2 in range(t2.shape[0]):
            if not self_sim or idx1>idx2:
                ex1 = t1[idx1,:]
                ex2 = t2[idx2,:]
                sims[idx1][idx2] = sim_func(ex1,ex2)
                
    return sims

第五步:结果

让我们看看我们的方法是否有效!我用来测试算法的数据集是Oxford-IIIT Pet Dataset(http://www.robots.ox.ac.uk/~vgg/data/pets/),有37只狗和猫品种。

完美的重复。该图像在数据集中包含5次。

重复(一个有签名)

相似但不重复

我还用计算机视觉中众所周知的数据集CIFAR10测试了算法,看看我是否能找到一些重复数据。这些是我发现的一些例子:

完美复制

几乎是一个重复的卡车,但有不同的标志

不重复,更像是数据扩充

我还运行了relabeler小部件,这是一个额外有趣的发现:

不是卡车

一旦我们有网络的重复建议,我们应该怎么做?好吧,我们应该选择那些实际上是重复的并从我们的数据集中删除它们,因为重复会导致网络过于重视这些图像。我们如何轻松删除重复项?使用fastai的交互式小部件(https://github.com/fpingham/dataset-cleaner)非常容易!你可以通过运行来试试:

来自fastai.widgets进口*
ds,fns_idxs = DatasetFormatter.from_similars('learner')
ImageCleaner(ds,fns_idxs,duplicates = True)

课程中所提到的网址整理如下:

fastai库:

https://github.com/fastai/fastai

callbacks 功能:

https://docs.fast.ai/callbacks.hooks.html

Pooling:

http://deeplearning.stanford.edu/tutorial/supervised/Pooling/

Oxford-IIIT Pet Dataset:

http://www.robots.ox.ac.uk/~vgg/data/pets/

fastai的交互式小部件:

https://github.com/fpingham/dataset-cleaner

信息来源:https://towardsdatascience.com/how-to-build-an-image-duplicate-finder-f8714ddca9d2

AMiner学术头条
AMiner学术头条

AMiner平台由清华大学计算机系研发,拥有我国完全自主知识产权。系统2006年上线,吸引了全球220个国家/地区800多万独立IP访问,数据下载量230万次,年度访问量1000万,成为学术搜索和社会网络挖掘研究的重要数据和实验平台。

https://www.aminer.cn/
专栏二维码
工程图像分类数据集计算机视觉CNN
4
相关数据
张量技术

张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数,这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 维空间内,有 个分量的一种量,其中每个分量都是坐标的函数,而在坐标变换时,这些分量也依照某些规则作线性变换。称为该张量的秩或阶(与矩阵的秩和阶均无关系)。 在数学里,张量是一种几何实体,或者说广义上的“数量”。张量概念包括标量、矢量和线性算子。张量可以用坐标系统来表达,记作标量的数组,但它是定义为“不依赖于参照系的选择的”。张量在物理和工程学中很重要。例如在扩散张量成像中,表达器官对于水的在各个方向的微分透性的张量可以用来产生大脑的扫描图。工程上最重要的例子可能就是应力张量和应变张量了,它们都是二阶张量,对于一般线性材料他们之间的关系由一个四阶弹性张量来决定。

计算机视觉技术

计算机视觉(CV)是指机器感知环境的能力。这一技术类别中的经典任务有图像形成、图像处理、图像提取和图像的三维推理。目标识别和面部识别也是很重要的研究领域。

暂无评论
暂无评论~