赛题名称:科大讯飞电商图像检索挑战赛
报名链接: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是非常基础的思路,此时可以则需要考虑如何刻画图像的特征。可以考虑使用:
图像在预训练CNN的计算结果; 图像的SIFT关键点特征; 图像的颜色直方图特征;
上述特征中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+的得分,如果想进一步的优化可以考虑如下思路:
修改预训练模型的输入尺寸,接受大尺寸的输入。 修改预训练模型的pooling层,使用max-pooling。 使用训练集类别继续finetune CNN模型,可以使用arcface loss增强模型的建模能力。
关注公众号,回复“CV”加入战队群
最新内容也会在群内更新发布






