一、ImageNet简介
ImageNet的主要特点
- 规模庞大:包含超过1400万张图像,覆盖了大约21841个类别。
- 类别丰富:这些类别代表了广泛的主题,从动物、植物到人造物品,以及抽象概念。
- 标注详尽:每张图像都经过人工标注,确保了类别标签的准确性。
- 多样性:图像具有不同的视角、光照条件、背景和尺寸,增加了识别的难度。
ImageNet的应用
- 图像分类:广泛用于训练和评估深度学习模型的图像分类能力,如著名的AlexNet、VGGNet、ResNet等模型。
- 目标检测:除了分类,ImageNet的标注信息也可以用于训练目标检测模型,如R-CNN、YOLO和Faster R-CNN等。
- 语义分割:虽然不是直接设计用于语义分割,但ImageNet的图像可以被改造或与其他数据集结合,用于训练分割任务。
- 迁移学习:由于ImageNet的广泛覆盖,预训练在ImageNet上的模型可以作为基础模型,用于其他任务的迁移学习,如医学图像分析、自动驾驶等。
但对于普通研究员或者开发者而言,这个数据集太大了(全部下载大概有100GB左右),而且训练对硬件要求也非常高,通常都是很多块高端显卡并行训练,即使是这样的配置通常还要训练好几天的时间。
二、Mini-ImageNet1
斯坦福大学的Mini-ImageNet数据集是在2016年发布的。这个数据集由Vinyals等人提出,最初是在论文《Matching Networks for One Shot Learning》中使用的。Mini-ImageNet是一个为小样本学习(Few-shot Learning)设计的子集,它从ImageNet中选取了100个类别,每个类别包含600张图像。这个数据集被广泛用于评估少样本学习算法的性能。
数据结构
该数据集的组织方式与原始ImageNet数据集完全相同。你会发现1000个文件夹,每个类别的文件夹名称类似于n10123204,还有一个json文件用于将文件夹名称映射到实际名称。
imagenet_class_index.json
{"0": ["n01440764", "tench"],
"1": ["n01443537", "goldfish"],
"2": ["n01484850", "great_white_shark"],
"3": ["n01491361", "tiger_shark"],
"4": ["n01494475", "hammerhead"],
"5": ["n01496331", "electric_ray"],
"6": ["n01498041", "stingray"],
压缩后总共文件大小约500M。
许可协议
数据库内容许可(DbCL)v1.0
三、Mini-ImageNet2
2016年Google DeepMind团队从Imagnet数据集中抽取的一小部分(大小约3GB)制作了Mini-Imagenet数据集,共有100个类别,每个类别都有600张图片,共60000张(都是.jpg结尾的文件),而且图像的大小并不是固定的。其中80个类用来训练,20类用来测试。
数据集的结构为:
├── mini-imagenet: 数据集根目录 ├── images: 所有的图片都存在这个文件夹中 ├── train.csv: 对应训练集的标签文件 ├── val.csv: 对应验证集的标签文件 └── test.csv: 对应测试集的标签文件
Mini-Imagenet数据集中还包含了train.csv、val.csv以及test.csv三个文件。需要注意的是,当时作者制作这个数据集时主要是针对小样本学习领域的,而且提供的标签文件并不是从每个类别中进行采样的。我自己用pandas包分析了下每个标签文件。
train.csv包含38400张图片,共64个类别。 val.csv包含9600张图片,共16个类别。 test.csv包含12000张图片,共20个类别。 每个csv文件之间的图像以及类别都是相互独立的,即共60000张图片,100个类。
用pandas读取的csv文件数据格式如下,每一行对应一张图片的名称和所属类别:
filename label
0 n0153282900000005.jpg n01532829 1 n0153282900000006.jpg n01532829 2 n0153282900000007.jpg n01532829 3 n0153282900000010.jpg n01532829 4 n0153282900000014.jpg n01532829
至于每个类别对应的实际物体名称,可查看这个json文件,这个文件是Imagenet1000类数据中对应的标签文件。
{“0”: [“n01440764”, “tench”], “1”: [“n01443537”, “goldfish”], “2”: [“n01484850”, “great_white_shark”], … }
制作新的train以及val文件 根据上面分析的,如果想用Mini-Imgenet数据集直接去训练自己的分类网络是不可行的,因为train.csv和val.csv并不是从每个类别中进行采样的,所以我们需要自己去构建一个新的train.csv和val.csv文件。下面是我自己写的一个构建train.csv和val.csv标签文件的脚本,该脚本会从这100个类别中按给定的比例去划分训练集和验证集。
import os import json
import pandas as pd from PIL import Image import matplotlib.pyplot as plt
def read_csv_classes(csv_dir: str, csv_name: str): data = pd.read_csv(os.path.join(csv_dir, csv_name)) # print(data.head(1)) # filename, label
label_set = set(data["label"].drop_duplicates().values)
print("{} have {} images and {} classes.".format(csv_name,
data.shape[0],
len(label_set)))
return data, label_set
def calculate_split_info(path: str, label_dict: dict, rate: float = 0.2): # read all images image_dir = os.path.join(path, “images”) images_list = [i for i in os.listdir(image_dir) if i.endswith(“.jpg”)] print(“find {} images in dataset.”.format(len(images_list)))
train_data, train_label = read_csv_classes(path, "train.csv")
val_data, val_label = read_csv_classes(path, "val.csv")
test_data, test_label = read_csv_classes(path, "test.csv")
# Union operation
labels = (train_label | val_label | test_label)
labels = list(labels)
labels.sort()
print("all classes: {}".format(len(labels)))
# create classes_name.json
classes_label = dict([(label, [index, label_dict[label]]) for index, label in enumerate(labels)])
json_str = json.dumps(classes_label, indent=4)
with open('classes_name.json', 'w') as json_file:
json_file.write(json_str)
# concat csv data
data = pd.concat([train_data, val_data, test_data], axis=0)
print("total data shape: {}".format(data.shape))
# split data on every classes
num_every_classes = []
split_train_data = []
split_val_data = []
for label in labels:
class_data = data[data["label"] == label]
num_every_classes.append(class_data.shape[0])
# shuffle
shuffle_data = class_data.sample(frac=1, random_state=1)
num_train_sample = int(class_data.shape[0] * (1 - rate))
split_train_data.append(shuffle_data[:num_train_sample])
split_val_data.append(shuffle_data[num_train_sample:])
# imshow
imshow_flag = False
if imshow_flag:
img_name, img_label = shuffle_data.iloc[0].values
img = Image.open(os.path.join(image_dir, img_name))
plt.imshow(img)
plt.title("class: " + classes_label[img_label][1])
plt.show()
# plot classes distribution
plot_flag = False
if plot_flag:
plt.bar(range(1, 101), num_every_classes, align='center')
plt.show()
# concatenate data
new_train_data = pd.concat(split_train_data, axis=0)
new_val_data = pd.concat(split_val_data, axis=0)
# save new csv data
new_train_data.to_csv(os.path.join(path, "new_train.csv"))
new_val_data.to_csv(os.path.join(path, "new_val.csv"))
def main(): data_dir = “/home/wz/mini-imagenet/” # 指向数据集的根目录 json_path = “./imagenet_class_index.json” # 指向imagenet的索引标签文件
# load imagenet labels
label_dict = json.load(open(json_path, "r"))
label_dict = dict([(v[0], v[1]) for k, v in label_dict.items()])
calculate_split_info(data_dir, label_dict)
训练自己的网络 项目地址:https://github.com/WZMIAOMIAO/deep-learning-for-image-processing 在pytorch_classification->mini-imagenet文件夹中,里面提供了两个训练脚本,一个是针对单GPU的,一个是针对多GPU的。在这个项目中是以训练ShuffleNetv2为例进行讲解的。训练了100个epoch,达到了78%的准确率。
接着,我拿这个预训练权重去做迁移学习,训练其他的小数据集,确实也有一定帮助。在我测试过程中,如果不使用预训练权重,训练自己的数据集能达到80%的准确率,如果使用预训练权重能达到90%的准确率。当然基于Mini-Imagenet的预训练权重和基于Imagenet的预训练权重还有一些差距,毕竟数据量摆在这。之前使用基于Imagenet的预训练权重准确率可以达到94%。 当然,对于自己新搭的网络,如果想快速验证一下,Mini-Imagenet也是一个不错的选择。 原文链接:https://blog.csdn.net/qq_37541097/article/details/113027489
四、获取案例套装
文件包大小:3.3 GB