暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kaggle从零到实践:讯飞图像检索挑战赛

Coggle数据科学 2022-02-16
1093

赛题名称:科大讯飞电商图像检索挑战赛

报名链接:http://challenge.xfyun.cn/topic/info?type=e-commerce-image-retrieval&ch=dw-sq-1

赛题介绍

在电商应用中每天商家都会上传数以百万的商品图像,商品图像可能是从不同角度拍摄的,也有可能是不同款式的商品图像。对于消费者而言,很难通过肉眼去找到相似的商品。如果有一种人工智能算法,能够找到相同商品的相同图像,则是非常有用的一项技术。

赛题任务

给定一批电商商品(主要是服务商品)的图像,找到属于同一个商品的图像。任务可以视为一个图像检索问题,或者一个图像聚类问题,需要将同一个商品的图像聚类到一起。

具体可以在train.csv标注文件查找到,每行为一个图片对应的商品图像集合。

  • 训练集
    :约7千张商品图像,并且给定了相同商品对应的商品图像集合。

  • 测试集
    :约4.8千张商品图像,需要选手识别出相同商品的图片集合。

输出的结果样例如下:

name,label
011898.jpg,011898.jpg 010116.jpg 011187.jpg 010247.jpg
010116.jpg,011898.jpg 010116.jpg 011187.jpg 010247.jpg
011187.jpg,011898.jpg 010116.jpg 011187.jpg 010247.jpg

每一行第一列图像名称,第二列为属于相同商品的图像。注意本张商品图像属于相同商品的,所以第二列包含第一列的图像名称。

赛题思路

赛题是任务需要识别相同图像的图像,在训练集中大概每个商品有2-3张图片,所以训练集类别个数上千。

赛题难点在于如何识别出相同商品的图像,可以使用一下思路来完成:

  • 思路1:计算不同图像的相似度,如果相似度很高,则任务属于相同的商品;
  • 思路2:识别图像中模特,认为相同模特对应的图像属于相同的商品;

在上述思路中思路1是非常基础的思路,此时可以则需要考虑如何刻画图像的特征。可以考虑使用:

  1. 图像在预训练CNN的计算结果;
  2. 图像的SIFT关键点特征;
  3. 图像的颜色直方图特征;

上述特征中CNN思路得到的精度最好,也是baseline的思路。

baseline思路

baseline思路如下:利用预训练的CNN提取测试集所有图像的特征,然后计算图片之间的相似度,并通过相似度阈值确定组成的图像。

步骤1:读取常见模块

import os, sys, codecs, glob
from PIL import Image, ImageDraw

import numpy as np
import pandas as pd
import cv2

import torch
torch.backends.cudnn.benchmark = False

import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torch.utils.data.dataset import Dataset

步骤2:定义数据集

class XunFeiDataset(Dataset):
    def __init__(self, img_path, transform):
        self.img_path = img_path
        self.transform = transform

    def __getitem__(self, index):
        img = Image.open(self.img_path[index]).convert('RGB')
        if self.transform is not None:
            img = self.transform(img) 
        return img

    def __len__(self):
        return len(self.img_path)

这里我们只需要测试集数据集即可:

test_path = glob.glob('./电商图像检索_数据集/test/*')
test_path.sort()
test_path = np.array(test_path)

test_loader = torch.utils.data.DataLoader(
    XunFeiDataset(test_path,
                        transforms.Compose([
                        transforms.Resize((256, 256)),
                        transforms.ToTensor(),
                        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ])
    ),
    batch_size=50, shuffle=False, num_workers=5,
)

步骤3:提取CNN特征

这里我们使用到了预训练的ResNet18网络,提取图像在全连接层之前的卷积特征。

import timm
model = timm.create_model('resnet18', pretrained=True, in_chans=3)
model.fc = torch.nn.Identity()
model.cuda()

test_feats = []
with torch.no_grad():
    for data in test_loader:
        data = data.cuda()
        feat = model(data)
        test_feats.append(feat.data.cpu().numpy())

步骤4:计算相似度

首先对提取好的图像特征进行L2归一化,方便之后做相似度筛选。

from sklearn.preprocessing import normalize
test_feats = np.vstack(test_feats)
test_feats = normalize(test_feats)

对每张图片计算其与测试集其他图像的相似度,并以0.85作为相似度阈值,生成结果集合。

test_submit = []
for feat in test_feats:
    dis = np.dot(feat, test_feats.T)
    ids = dis.argsort()[::-1]
    
    test_submit.append([
        test_path[ids[0]].split('/')[-1],
        [x.split('/')[-1] for x in test_path[ids[dis[ids] > 0.85]]]
    ])
    
test_submit = pd.DataFrame(test_submit, columns=['name''label'])
test_submit['label'] = test_submit['label'].apply(lambda x: ' '.join(x))
test_submit.to_csv('submit.csv',index=None)

步骤5:预测结果可视化

改进思路

基于baseline思路以及可以得到线上0.43+的得分,如果想进一步的优化可以考虑如下思路:

  1. 修改预训练模型的输入尺寸,接受大尺寸的输入。
  2. 修改预训练模型的pooling层,使用max-pooling。
  3. 使用训练集类别继续finetune CNN模型,可以使用arcface loss增强模型的建模能力。

关注公众号,回复“CV”加入战队群

最新内容也会在群内更新发布


学习交流群已成立
学习推荐系统,算法竞赛,组队参赛
添加👇微信拉你进群
加入了之前的社群不需要重复添加~

文章转载自Coggle数据科学,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论