关于 annotation / label 的个数,有两种说法:
24
个,如 DCMH[4],就是去除了那些 _r1.txt 文件,其实看一下那些 _r1.txt 文件内用就会发现,在对应的没有 _r1 后缀的文件中已经包含了,比如 baby.txt 和 baby_r1.txt,其实后者中的内容在前者中都已包含;38
个,如 [6],应该就是将诸如 baby.txt 和 baby_r1.txt 区别对待的效果。我也不知道带和不带 _r1 的区别。在 README.txt 里,不带的叫 POTENTIAL LABELS,带的叫 RELEVANT LABELS。
将两个文件上传到百度网盘共享:
https://pan.baidu.com/s/19Zud5NQRKQRdcpGGJtpKjg
Flickr-25K 有 2,5000 张图,每张图有对应的 tags 和 annotation。
tags 可作为文本描述(text),其中至少出现在 20 张图片中的 tags 有 1386
个;
annotation 作为 label,一共 24
个。
最终将 image 处理成 VGG19 的 4096-D 特征、text 是 1386-D BoW 向量、label 是 24-D 0/1 向量。
[4] 有提供一份处理好的 flickr 数据集,但总数是 2,0015。
下载 mirflickr25k.zip 和 mirflickr25k_annotations_v080.zip,解压出 mirflickr/
和 mirflickr25k_annotations_v080/
。
mirflickr/
,文件名标了号:im*.jpg。mirflickr/doc/
下有 common_tags.txt
,里面是上述的 1386 个 tags 和其对应的出现频数。mirflickr/meta/tags/
是每张图对应的处理过的 tags(转成小写、去除空格…),就用这些 tags。mirflickr25k_annotations_v080/
下是各 annotations 的文件,除去那些 *_r1.txt 和一个 README.txt 共 24 个。每个文件里都是若干个标号,表示这些标号的 image 属于这个 annotation。from os.path import join
from os import listdir, makedirs
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
BASE = 'mirflickr'
IMG_P = BASE # image 路径
TXT_P = join(BASE, 'meta/tags') # text 路径
LAB_P = 'mirflickr25k_annotations_v080' # label 路径
SAV_P = join(BASE, 'sav') # 保存路径
COM_TAG_F = join(BASE, 'doc/common_tags.txt') # common tags
N_DATA = 25000
from imageio import imread, imwrite
# from scipy.misc import imresize
from skimage.transform import resize
from keras.applications.vgg19 import VGG19
from keras.models import Model
# 加载 VGG 19
vgg = VGG19(weights='imagenet')
# vgg.summary()
vgg = Model(vgg.input, vgg.get_layer('fc2').output) # 取 4096-D feature 输出
vgg.summary()
# image 文件列表
fs_img = [f for f in listdir(IMG_P) if '.jpg' in f]
fs_img = sorted(fs_img, key=key_img) # 按标号排序
key_img = lambda s: int(s.split('.jpg')[0].split('im')[-1])
fs_img = [join(IMG_P, f) for f in fs_img]
N_IMG = len(fs_img)
print(N_IMG)
# 提取 image 特征
all_img = []
for i in range(N_IMG):
im = imread(fs_img[i])
im = resize(im, (224, 224, 3))
im = np.expand_dims(im, axis=0)
all_img.append(vgg.predict(im))
all_img = np.vstack(all_img)
print(all_img.shape)
# 保存
np.save(SAV_P, all_img)
# 处理 common tags
tag_idx, idx_tag = {}, {}
cnt = 0
with open(COM_TAG_F, 'r') as f:
for line in f:
line = line.split()
tag_idx[line[0]] = cnt
idx_tag[cnt] = line[0]
cnt += 1
DIM_TXT = len(tag_idx.keys())
print(DIM_TXT)
# text 文件列表
key_txt = lambda s: int(s.split('.txt')[0].split('tags')[-1]) # 按标号排序
fs_tags = sorted(listdir(TXT_P), key=key_txt)
fs_tags = [join(TXT_P, f) for f in fs_tags]
N_TXT = len(fs_tags)
print(N_TXT)
def get_tags(tag_f):
"""读 tag 文件,获取该 sample 的 tags"""
tg = []
with open(tag_f, 'r') as f:
for line in f:
a = line.strip()
if a in tag_idx:
tg.append(a)
return tg
# 制成 BoW
all_txt = np.zeros((N_TXT, DIM_TXT))
for i in range(N_TXT):
tag = get_tags(fs_tags[i])
for s in tag:
if s in tag_idx: # 在 common tags 内
# print(i, s)
all_txt[i][tag_idx[s]] = 1
print(all_txt.shape)
# 保存
np.save(SAV_P, all_txt)
# label 文件列表
fs_lab = []
for f in listdir(LAB_P):
if '_r1' not in f and 'README' not in f:
fs_lab.append(join(LAB_P, f))
N_CLASS = len(fs_lab)
print(N_CLASS)
def sample_of_lab(lab_f):
"""读 annotation 文件,获取属于该类的 samples 标号"""
samples = []
with open(lab_f, 'r') as f:
for line in f:
sid = int(line)
samples.append(sid)
return samples
# 处理 label
all_lab = np.zeros((N_DATA, N_CLASS))
for i in range(len(fs_lab)):
samp_ls = sample_of_lab(fs_lab[i])
for s in samp_ls:
all_lab[s - 1][i] = 1 # s-th 样本属于 i-th 类
# 保存
np.save(SAV_P, all_lab)