使用Mini

您所在的位置:网站首页 imagenet预训练模型迁移到其他数据集 使用Mini

使用Mini

2024-02-03 23:44| 来源: 网络整理| 查看: 265

文章目录 数据集下载链接数据集简介制作新的train以及val文件训练自己的网络

数据集下载链接

百度网盘下载: 链接: https://pan.baidu.com/s/1Uro6RuEbRGGCQ8iXvF2SAQ 密码: hl31

数据集简介

提到Imagenet大家都知道,是一个非常大型、有名的开源数据集。一般设计一个新的分类网络就会在Imagenet 1000类的数据上进行训练以及验证。包括常见的目标检测网络等,所使用的backbone一般都会先基于Imagenet进行预训练。但对于普通研究员或者开发者而言,这个数据集太大了(全部下载大概有100GB左右),而且训练对硬件要求也非常高,通常都是很多块高端显卡并行训练,即使是这样的配置通常还要训练好几天的时间。所以让很多人望而却步(我就是其中之一,关键太大,而且国内下载很慢)。

2016年google DeepMind团队从Imagnet数据集中抽取的一小部分(大小约3GB)制作了Mini-Imagenet数据集,共有100个类别,每个类别都有600张图片,共60000张(都是.jpg结尾的文件),而且图像的大小并不是固定的。

数据集的结构为:

├── 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) if __name__ == '__main__': main() 训练自己的网络

项目地址:https://github.com/WZMIAOMIAO/deep-learning-for-image-processing 在pytorch_classification->mini-imagenet文件夹中,里面提供了两个训练脚本,一个是针对单GPU的,一个是针对多GPU的。在这个项目中是以训练ShuffleNetv2为例进行讲解的。训练了100个epoch,达到了78%的准确率。

shufflenetv2

接着,我拿这个预训练权重去做迁移学习,训练其他的小数据集,确实也有一定帮助。在我测试过程中,如果不使用预训练权重,训练自己的数据集能达到80%的准确率,如果使用预训练权重能达到90%的准确率。当然基于Mini-Imagenet的预训练权重和基于Imagenet的预训练权重还有一些差距,毕竟数据量摆在这。之前使用基于Imagenet的预训练权重准确率可以达到94%。 当然,对于自己新搭的网络,如果想快速验证一下,Mini-Imagenet也是一个不错的选择。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3