续接前文: mini_imagenet 数据集生成工具
============================================
前文接受了mini_imagenet数据集的生成,但是few shot learning常用的episode学习方法是在数据集的基础上划分task episode,每个episode相当于是一个task,比如把数据集划分20000个episode就相当于生成
项目页面给出的episode生成方法(demo 版本):
from miniimagenettools.mini_imagenet_dataloader import MiniImageNetDataLoader dataloader = MiniImageNetDataLoader(shot_num=5, way_num=5, episode_test_sample_num=15) dataloader.generate_data_list(phase='train') dataloader.generate_data_list(phase='val') dataloader.generate_data_list(phase='test') dataloader.load_list(phase='all') for idx in range(total_train_step): episode_train_img, episode_train_label, episode_test_img, episode_test_label = \ dataloader.get_batch(phase='train', idx=idx)
=====================================================
不过原始版本的代码感觉不是很好,于是自己就又进行了一定的修改,修改的项目代码如下:
https://gitee.com/devilmaycry812839668/mini-imagenet-tools
生成数据集的方法:
python mini_imagenet_generator.py --tar_path ~/Download/ILSVRC2012_img_train.tar --target_dir ~/project --image_resize 100
从数据集中读取数据的方法:
from mini_imagenet_dataloader import MiniImageNetDataSet minidataset = MiniImageNetDataSet(5,5,15,20000,600,800,'~/processed_images/') train_images, train_labels, test_images, test_labels = minidataset.get_train_batch(100) print(train_images, train_labels, test_images, test_labels) print(train_images.shape) print(train_labels.shape) print(test_images.shape) print(test_labels.shape) for i in range(20000): train_images, train_labels, test_images, test_labels = minidataset.get_train_batch(i) print(i)
虽然自己花时间把代码重构了一下,不过功能都是保持一致的,对于datasetloader部分使用了具体的get_train_batch, get_val_batch, get_test_batch函数,实现了对不同部分数据的读取显示进行。
这个项目中的miniImageNet数据集是从ImageNet2012数据集中抽取出来的,在小样本机器学习领域这个miniImageNet数据集其实不仅仅是图片数据集其实也包括你定义的episode任务数据。
可以看到图片数据集为train, test, val 这三个文件夹, 另外三个pkl文件则是Few shot learning中对episode task的定义文件。
在Few shot learning 中episode task是最为独创的设计,以前在处理小样本问题时都是采用single task,也就是说单一任务的训练。
在single task的手写图片问题中10way 5shot 就是说我们的训练数据集为10x5=50张图片,其中数字类别为0,1,2,3,4,5,6,7,8,9这10类,每一类中我们的图片数量为5,也就是说这50张图片中数字0有5张图片,数字1有5张图片,...... ,数字9有5张图片。
在传统的小样本学习中我们只对这单独的任务进行训练,我们的测试数据集为数字类别为0,1,2,3,4,5,6,7,8,9这10类,每一类中我们的图片数量为100张,我们的机器学习训练目标就是对训练集中的已经知道类别标签的50张图片进行训练然后可以准确的识别出测试集中10x100=1000张图片的分类。这就是最初的小样本问题及其模式,但是这个模式的设定对数据集的要求很高,而且这种单任务的single task训练起来往往手段比较简单而且效果也不是很好,如使用贝叶斯等方法。
由于传统小样本问题的定义局限在single task范畴里面导致这个问题的发展很有限,最后这个问题的发展就源于episode task这个概念的提出。
既然single task有这么多的研究局限性那么使用multi task的方式来进行few shot learning研究就被提出来了。
大家比较熟悉和常见的multi task的方法有多任务学习,多视角学习,多模态学习,甚至有迁移学习,那么为什么最后few shot learning的发展方式选择了episode task的元学习呢???
以下均为个人观点:
多任务学习,多视角学习,多模态学习,甚至有迁移学习都是大数据集下的多个任务间知识复用和融合的学习方法,这些方法一般都是为大数据情况下的学习来提升学习性能的,虽然有多个学习任务的知识但是往往都是数量较少的学习任务,多任务,多视角,多模态往往都是2个,3个任务,而迁移学习往往都是2个任务,而数量这么少的任务之所以也能有性能提升主要原因还是因为单个任务有大数据量。换句话说,2个,3个大数据量的任务来进行学习不适用于few shot learning问题。
few shot learning 问题的定义就是单个任务训练数据要保证数量小,只用单个任务的小数据集训练难以继续发展这个方向那就只能多个任务的小数据集学习,也或者在若干个大数据集下训练然后迁移到小数据集上再训练,也或者在若干个大数据集的多任务下训练然后再迁移到小数据上训练,也就是说单纯的使用多任务训练是不行的,我们最后的落脚点必须保证few shot learning的问题定义,最后都要保证在小数据集的训练数据上训练后在小数据集的测试数据集上获得好的效果。
那么还有什么形式的few shot learning可以存在呢?(single task的形式难以继续发展few shot leanring问题,multi task的形式又该如何选择)
多任务学习的few shot learning => 大数据量任务和小数据量任务混合训练,训练好的小数据量任务再进行对应的测试数据集运行。或 多个小数据量任务混合训练,训练好的小数据量任务再进行对应的测试数据集运行。
多任务学习+迁移学习的few shot learning => 大数据量任务和小数据量任务混合训练,训练好的模型再迁移到小数据量任务再进行对应的测试数据集运行。或 多个小数据量任务混合训练,训练好的模型再迁移到小数据量任务再进行对应的测试数据集运行。
如果不加入迁移学习的话只进行多任务学习,在大数据量任务和小数据量任务混合训练时极有可能因为数据量的不平衡导致算法的泛化性能不高,而多个小数据量任务混合训练在一定程度上是可行的。
===========================================
随便说一下,多任务学习+迁移学习,这个形式如果不考虑学习数据量的问题就和元学习是相同形式了。
由于在few shot learning问题中我们最后想要得到的模型数量为一,也就是说few shot learning的最终求解的是一个模型,而多个任务的训练往往得到多个模型,这样的话就会造成一些训练上的不必要的浪费,那么如果多个任务都是使用相同模型并且共享参数呢,这样这个问题就解决了。多任务训练往往都是共享一部分模型,多模态、多视角往往是完全共用同一个模型。采用这种方式的学习方法如果再最终学习的任务上训练时采用的是小数据样本,那么它就是传统的所谓的“元学习”了。而多个任务共用同一模型往往需要多个任务是强相关的,或者说这多个任务其实是同一任务的不同体现方式,如:多视角、多模态等。而这种多个任务都是相同任务的不同体现方式的这种要求对于few shot learning也是十分有难度的,主要在于数据集难以构建。如果多个任务不是同一任务的不同体现,但是仍然保持这些任务为强相关的,这种方式来构建few shot learning是否可行你???以往的多任务训练如果只保证任务强相关,那么模型只会共用一部分而不是所有模型,那么采用该种方式构建few shot learning就有两种选择:
1. 多任务共用所有模型; 2. 多任务共用一部分模型。
如果多任务共用所有模型,那么在后面的迁移步骤中我们可以直接把整个模型迁移到新的小数据量任务上。
如果多任务共用部分模型,那么在后面的迁移步骤中我们可以直接把共用部分模型迁移到新的小数据量任务上,同时在新的小数据量任务上对没有迁移的那部分模型参数进行随机初始化的重训练。
============================================
那么通过上面的分析我们知道few shot leaning的问题构建形式可以选择下面四种:
1. 不加入迁移学习只进行多任务学习,多个小数据量任务混合训练,多个任务共用相同模型。
2. 不加入迁移学习只进行多任务学习,多个小数据量任务混合训练,多个任务共用部分模型。
3. 进行多任务学习并加入迁移学习,多任务训练中多个小数据量任务混合训练,多个任务共用相同模型。
4. 进行多任务学习并加入迁移学习,多任务训练中多个小数据量任务混合训练,多个任务共用部分模型。
第2,第4种由于在multi task训练阶段使用的是部分相同模型,那么对非共享部分的模型训练是得不到多任务训练的帮助的,在以往的多任务训练中之所以会这样做是因为多个任务即使强相关但是也是不完全相同的任务,必须要为不相同的那部分给出专属的模型部分。如果可以完全共用同一模型自然是要好于只使用部分相同模型的好。
第1,第3种相比较:因为在few shot learning中由于任务的数据量均为小数据量,这时候就需要有数量众多的相关任务;第1种中因为目标任务和辅助任务是共同训练的,往往需要多任务的相关性更强,而第3种由于最后的目标任务是在迁移模型之后进行的,因此可以放松对多任务(辅助任务)和迁移后任务(目标任务)的相关性要求。换句话说,第1种难以找到这样的数据集,由于每个任务的数据量较小,在一定程度上第一种中的多任务(辅助任务)甚至可以看做是目标任务的一种数据增强的方式。第1种中大量的小数量级的相似任务甚至可以退化成一个大数据集的任务的多个batch数据,每个batch中的数据就是一个task。可以说第1中的方式是难以在数据集上实现的,即使是数据集可以满足,这种方式也极有可能退化成一个大数据量任务的多个batch的任务。
===========================================
如果不加入迁移学习的话只进行多任务学习,多个小数据量任务混合训练在一定程度上是可行的。但是这种情况下要求多个任务是强相关的,这种要求现有数据集是难以满足的,而且这种要求也是难以重新构建数据集的,因为这里的多个任务往往需要较大的任务数。
在机器学习领域数据集往往是新问题或新研究方法的推进剂。
=============================================
经过上面的分析,比较好的、可行的方式来进行few shot learning则是:进行多任务学习并加入迁移学习,多任务训练中多个小数据量任务混合训练,多个任务共用相同模型。
但是即使是这种方式多个任务(任务数极多)的这个条件也是很难满足的,也正是因此也就有了episode task这个概念。
也正是因为episode task这个概念才有了miniImageNet数据集及episode task任务定义。
多个相似任务(强相关任务)难以获得,那么我们就从一个大的分类任务(如:60类的分类任务)划分为如:20000个5类的分类任务呢。60个类的分类任务如果排序为5个类的分类任务可以有60*59*58*57*56=655381440 种划分方式,我们在这655381440种划分方式种随机又放回的抽取20000种分类方式,由于我们是进行的排序而不是组合,所以这20000个划分的分类任务中必然存在相同类的分类任务,如A分类任务中标签0,1,2,3,4在B任务种标签就可能是4,2,1,0,3 ,但是我们A类任务中的数据即使和B类任务中的一样都是也是不相同的,因为都是在原始大数据集中对应类下随机抽样出的小数据量的样本。
现在构建的few shot learning 是如何根据episode task训练的呢?
现在的few shot learning在构建的如20000个episode task训练后(这20000个task共享模型),然后迁移到目标数据集(目标episode task)进行再训练,然后测试在目标episode task的测试集中的性能。
episode task的设立使模型可以在保持数据特征的基础上快速根据标签的变化改变映射关系,从而使模型具备从少量样本中快速学习的模型性能。如A、B任务具有相同的分类标签,但是两者对应类下的数据不同并且相同类对应的标签也不同,如:A分类任务中标签0,1,2,3,4,在B任务种标签就可能是4,2,1,0,3 ,在训练时对A、B task轮流训练,最终获得模型可以快速根据少量的训练样本数据知道现在想要的是A任务的映射关系还是B任务的映射关系,如果模型具备了快速识别A、B任务的能力,学会了这种映射关系,那么我们把模型迁移到目标任务上同样进行小样本的训练并获得很好的对目标任务的映射关系,就这是现在的few shot learning 的设定。
few shot learning在episode task的设定下基本可以分为基于优化的和基于度量的两种:
现在的few shot learning中基于优化的方法则是在寻找固定神经网络结构下对多个小样本任务更敏感的参数,在该参数下进行目标任务的小样本数据的训练可以快速学习到对应的映射关系;而基于度量的few shot learning 则是寻找可以在多个小样本任务中更有效的分类度量方式,并把该度量方式迁移到目标的小样本任务中,并快速学习到目标任务中小样本数据和对应标签的映射关系。
========================================================