复现maml论文模型-1

论文为:Finn C, Abbeel P, Levine S, et al. Model-agnostic meta-learning for fast adaptation of deep networks[C]. international conference on machine learning, 2017: 1126-1135.
代码地址(tensorflow版本):https://github.com/cbfinn/maml

复现这个词,有两点不太好,但我暂时想不到更简练的词了。
1.代码不是自己写的,只是按照原论文的参数训练模型和测试,以理解和验证论文;
2.由于个人硬件资源的限制,并没有完全按照原论文的参数,个别参数按照自己的理解与硬件资源适配,做了部分调整。

下面,就把我的经历做下整理。

一、元学习与少次学习
开始看元学习的出发点是面临一个(实体关系抽取任务)数据量较少可能训练模型和测试结果会不太好,的这样一个问题,然后看了清华大学高天宇同学的分享,https://www.bilibili.com/video/BV1GJ411W79k
发现他们解决这一问题(他们是以数据长尾现象的角度切入的),利用少次学习的方法,而其中的一类方法就是元学习的方法,并且元学习方法在近两年特别火,所以就入手看了。
知道这两个概念,并且拿到论文之后,就开始在网上搜,发现这两个概念往往被大家混为一谈,因为可能涉猎未深,有时候虽然觉得博客上说的不对,但自己也想不到一个合理的解释,同时没点积淀,论文也是难啃的,能接受论文里面的说法,但是没有完全被大脑接受。因此,就在各种说法中浮浮沉沉,后来看到台湾大学李宏毅老师的课程,https://www.bilibili.com/video/BV1J4411a7Bz?from=search&seid=8751855545990768949
才简单理解了,下面这段话是我汇报“元学习入门”时自己总结的(看完上面视频才能大致理解这段话)。

少次学习,顾名思义,就是给定少量数据进行训练的任务,或者训练数据很少这样场景下的学习任务。
一个大的观点是说少次学习是元学习在监督学习领域的应用,另一个是说元学习和少次学习是两个不同的东西,元学习更像是一种学习架构,少次学习是一种具体的学习任务。
而从概念本身来看,元学习的训练需要一系列的task,如果我们把其中一个task当作普通的机器学习任务那样,喂给大量的数据,让它很多次地通过迭代计算,这样的方式去训练,有的算法需要耗费几天的时间,而元学习这种多任务的思路,将会变得无法训练,
因此,我门通常以少次学习任务来作为元学习训练的一个个任务,这也是为什么元学习方法被大量应用于少次学习任务中。

二、初跑代码
从readme来看,我最后创建的python虚拟环境为python3.6.7+tensorflow1.15.2。

maml-readme.png

从元学习的论文出发,它实现了三类任务:回归、分类和强化学习。第一个任务用的数据集比较简单,正弦曲线的拟合可以帮助理解元学习算法的过程;第二个任务用的数据集虽然是图像,但是任务类型可以和要做的事情相匹配,所以需要跑下数据,理解分类任务的实现过程;第三个任务目前暂时看来还关系不大,就先没跑实验。
疫情期间,在家只有笔记本,操作系统是windows10,cpu是Intel(R) Core(TM) i7-8550U CPU @1.80GHz 1.99GHz
基于以上内容,就开始跑代码,按照代码主目录下的main.py中给出的命令,训练了正弦曲线的回归模型,这个的训练时间可能就半个小时这样的量级(因为这是一开始稀里糊涂跑的,忘了具体跑了多长时间了,就是比起后来跑图像数据集花的时间少得多得多),但是跑完之后,发现我根本不懂输出内容是啥意思,这真是。。(意料之中吧),所以我接下来就进行了 三 的内容。
三、基于tensorflow-gpu跑maml的回归任务
为了便于理解这个元学习模型,我还是决定先把这个回归任务理解了,所以就找到了这个代码:https://github.com/mari-linhares/tensorflow-maml/blob/master/maml.ipynb
不太妙的是,这个代码的运行环境是tensorflow-gpu==2.0.0-alpha0,因此我就开始了搭建可以使用gpu的环境的历程,这个也是稍微花了点时间的,我的显卡是NVIDIA GeForce 940MX。
GPU型号查看1.png

GPU型号2.png

GPU驱动版本(桌面右键->NVIDIA 控制面板)
查看驱动版本.png

1.看你的显卡是否支持cuda(CUDA is a parallel computing platform and programming model invented by NVIDIA)
https://developer.nvidia.com/cuda-gpus
2.查看tensorflow-gpu、cuda和cudnn(CUDA for Deep Neural Networks)的对应关系
https://tensorflow.google.cn/install/source_windows
tensorflow-gpu_python_cuDNN_CUDA版本对应.png

3.安装visual stdudio2015(因为一点混乱,我没有按照上面查出来的安装2017版,但是2015也成功跑起来了)
4.安装cuda
安装指南:https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/#axzz4Vh7B32MZ
下载地址:https://developer.nvidia.com/cuda-downloads?target_os=Windows&target_arch=x86_64&target_version=10
安装位置如下图:
cuda安装位置.png

查看环境变量(安装完成之后自动添加上去的,位于顶部)
cuda对应的环境变量.png

5.查看cuda信息
cuda信息.png

6.安装cudnn(CUDA for Deep Neural Networks,这个需要登录)
https://developer.nvidia.com/cudnn
下载下来之后,解压是个cuda的目录,改为cudnn即可,放置位置如图:
cudnn放置位置.png

配置环境变量,同样让其位于顶部
cudnn对应的环境变量.png

7.pip安装tensorflow-gpu==2.0.0-alpha0,并且尝试import,会出现_pywrap_tensorflow_internal cannot find dll这样的错误
7.1使用vs developer command prompt中的dumpbin.exe查看依赖的dll
dumpbin /dependents E:\desktop\mamlregression\Lib\site-packages\tensorflow\python\_pywrap_tensorflow_internal.pyd
7.2用where查找这些dll是否都可以找到,把没在环境变量的dll的路径加上,没有的下载。主要是这三个dll根本没有,cublas64_100.dll,cusolver64_100.dll,cudart64_100.dll
7.3下载dll,放到cuda的bin目录下
下载地址来源:https://medium.com/@iitbguha/tensorflow-with-gpu-installation-made-easy-659f88c0309b
这个博客里的link,是个谷歌云盘
上面博客里下载地址怎么找(ctrl+f,找link这个关键字).png

放置好之后如下图:
dll放置位置.png

7.4检查
import tensorflow as tf
检查.png

四、元学习概念
刚才说由于元学习训练过程的特殊性,所以元学习使用的数据往往是少次学习数据,因此后面描述遵循几个少次学习中的定义。
元学习,就是通过训练任务训练得到一个最好的初始化值。
按照少次学习的说法,这个训练任务中包含支持集和测试集两种数据,同时,少次学习中惯用一个设定:Nway-Kshot,从分类角度来说,Nway指的是N中类别,Kshot指的是每个类别的样本数。如果说,要处理的问题是5分类,那么N=5,K的值由你真实的数据集来确定,也就是实际可以获取到的每类样本的样本数。这里假设每类可以获取到6个样本。那么某一类别中的6个样本,就可以分为两部分,一部分做支持集,一部分做测试集。再次假设,支持集中有5个样本,测试集有1个样本,那么按照少次学习任务的设定,这里的假设任务就可以下定义为5way5shot任务。
按照上面的假设,结合李宏毅老师课程的介绍(如下图),元学习的过程就是指,将这5个分类的5个样本输入一个基础网络,经过梯度下降的计算过程,更新模型中的参数,直到得到最好的参数(这个更新次数,原论文中只更新一次,原因有二:1是我们面对的数据不多,如果更新次数过多会导致过拟合;2我们要做到高效,即只通过一次更新就能很快地找到最好的参数,而到了我们的测试数据上我们可以迭代更新不止一次,直到拿到最好的参数)。再将测试数据输入这个最好的参数对应的模型,得到loss,再进行计算梯度,此时进行那个基础网络参数的更新。
元学习过程.png

此时,我们找到一个在这5个分类上最好的模型(参数,因为参数确定,模型确定),但是我们最终的目的是做到任意数据的5分类问题都能得到很好的解决。因此类比机器学习的训练过程,我们需要大量的这种5分类的任务,从这些大量5分类任务中学会学习,而不仅仅是会学习(能做好一个特定的5分类任务),这也是元学习的核心之处。
有了大量的不同类别的5分类任务,用同样的方法,都得到一个最好的模型(参数)。我们按照输入模型的任务顺序,任务1拿到的最好参数更新基础网络,接下来,任务2也拿到了自己的最好的参数,在任务1的更新的基础上再次更新,如此重复下去,直到所有任务进行完,就得到最终的参数作为初始化参数。(这些任务也可以作为一个任务batch,按照batch来更新参数,只是这里假设是一个任务一个任务来更新,好像是叫做online梯度下降,而那个batch级的更新叫一定程度上的offline梯度下降,这个offline的程度取决于一次更新参数所能看到的任务数量。这段话有点碎,但是不影响括号外面的理解。)
下面这张图是李宏毅老师课程上的参数更新过程。
参数更新.png

你可能感兴趣的:(复现maml论文模型-1)