如题,比如我用vgg16作为预训练模型,除了修改最后的全连接层,我还想让第一层的卷积层参数进行更新。为什么一般没有人进行这么做呢,前层和后层的区别在哪里?

我自己做了个实验,发现修改第一层参数后的模型,它的准确率和只修改最终全连接层不相上下(有时候低比较多)。

我想改第一层的原因是因为我导师的方向是模型安全,所以想找出一种方法来防御一种攻击。


迁移学习一般针对的是目标任务训练数据较少的情况,因为如果目标任务训练数据较多,直接训练就可以了。目标训练集的训练样本少,就要注意避免过拟合的问题。如果开放全部的网路参数进行训练,那么就很容易陷入对目标训练集的过拟合状态,从而降低模型的泛化性能。网路的前几层一般都是来进行特征的提取和抽像的,如果源任务和目标任务差别不是很大,而且模型在源任务中已经取得了较好的效果,那么就没有必要再对其进行训练了。关于fine-tune的时候,固定哪些层,训练哪些层有著比较广泛的讨论,在CVPR2019有一篇文章,使用增强学习的方法来生成fine-tune策略,想法很不错,可能会对题主有一些帮助,如果感兴趣可以浏览一下。

SpotTune: Transfer Learning through Adaptive Fine-tuning


这是实践中检验的结果吧,我记得语音处理领域中的的迁移学习控制的是后面层的,前面层进行训练。


不请自来,说说我的看法,嘻嘻

1.首先之所以叫迁移学习,那肯定是需要将以前学习到的知识迁移到新的问题上,才叫迁移学习。而网路所学习到的知识体现在网路参数上面(如果你用nas的话,网路结构也算),如果你把高层-底层的全训练了,那就不叫迁移了。

2. 在「how transferable are features in deep neural networks」这篇论文中,yosinski他们用实验证明了,旧网路学习到的底层特征是比较通用的(比如第一层学习到的特征与garbor滤波器很像,这种底层滤波器是通用的),恰当的利用会提高网路的泛化性能,而高层特征是比较task-specific的,所以需要根据任务变化来进行微调。


那不然做迁移学习的意义在哪(手动狗头),可以参考ACL2019的一篇文章《what does BERT learn 。。。》就是揭示了BERT网路架构从低层到深层,低层学习的是图片的通用特征(比如线条边缘啥的)或者文本的通用单词特征,再往里面走就是学比如句子语义特征,最深层就是学的段落特征。我觉得这也是迁移学习的一个驱动点所在吧,既然现在面临的很多时候都是小样本或者需要学习的参数很多,而低层的特征对于同一个任务里面来说又都相似,所以直接用训练好的模型然后针对具体任务场景修改深层参数能够更快更高效的完成任务。至于题主说的模型安全我也不是很了解,好像AAAI和ICLR2019都有关于图神经网路来对抗攻击的文章题主可以看一下~


我自己的理解是,神经网路实际最终就是表示学习,一层层的最终提取表示对象的特征,一般第一层的提取是最初的提取,还是属于对原对象的初步抽象,所以不会有太大差别,后面几层才是抽象出来足以区别类别的特征,所以,调节第一层的参数对于最后结果的影响必定不大。哈,缺乏理论公式表示的直观理解。


对于计算机视觉应用而言, 模型提取的底层特征是图像的低级特征, 如边缘等, 这些特征是通用的; 模型提取的高层特征则具有特定的语义, 是与具体任务相关的.

迁移学习一般是将大规模数据训练的模型向相关任务上迁移, 且这个相关任务只有少量的训练数据. 因为大规模数据训练的模型提取的底层特征的泛化能力更高, 所以一般冻结底层权重, 又因为是不同的任务, 所以要放开高层权重.


神经网路可以理解为复合函数,你训练的话,肯定是需要用反向传播演算法的:

如果你的梯度是逐层传播的,很有可能梯度传到前面,梯度就消失了,这样就难以训练这个神经网路了;

如果你直接把梯度作用于前面的层的话,前面参数比较小的变化就会引起最后的损失爆炸,有点像蝴蝶效应的感觉,同样也难以训练。

有的迁移学习,比如原来100个分类,现在变成120个分类,那么就直接改最后一层的节点——从100个节点变为120个节点,并计算新的交叉熵损失。


对迁移学习了解较少,在此分享自己的看法,同时向大家请教。

如果把网路学习过程看成从低级特征提取到高级特征提取的过程的话。那么不改变前面层参数,就是保持学习到的低级特征不变。

就计算机视觉而言,低级特征就是点、线、面。可以粗略的认为视觉对象都是由点、线、面构成的。所以,不训练前面层参数可以认为这些较为简单的低级特征可以被很好的掌握,而我们只需要改变他们的组合方式从而形成不同的高级语义(迁移)就好了。另一方面就是避免过拟合,因为一般迁移学习是因为目标域样本不多,所以如果我们过分学习目标域的点、线、面,很可能导致这不完备的点线面没法儿组合成更丰富的视觉对象。

那如果就语音来说,是不是应该去微调前面几层呢?在此抛出我的疑问,向大家请教。举个例子,中文的「苹果」和英文的「apple」表达同一个高级语义,但是他们的表达方式不同。如果这里做一个语言的迁移,是否应该保持高级语义不变,而去微调表达方式呢?


神经网路前面的层和后面的层可以分别看作特征提取器和分类器,它们的参数可以看作模型学到的知识,前者的知识通用性更好。一般用迁移学习的任务是数据量不充分的,此时如果训练整个模型会导致过拟合。那为什么一般不训练前面的参数而不是不训练后面的参数呢?

相似的任务可以使用相似的特征,只要分类器重新训练就好。比如对人划分为贫穷、小康、富裕三类时,特征提取器学到了年龄、性别、职业、工作单位、月均消费、家庭地址等特征(举这几个例子是为了人容易理解,实际上神经网路学到的是人很难直观理解的特征,但本质都是特征),分类器可以根据这些特征进行分类。这个模型训练好之后,如果我想对人的学历进行分类,比如研究生、本科、高中及以下,同样可以使用刚刚的特征提取器,因为它提取的特征依然有用。但是刚刚的分类器知识跟具体任务关联紧密,所以需要重新训练。


迁移学习的目的是用大数据集训练好的模型参数来微调新的任务,vgg这种前面几层的参数在大数据集上训练好的参数已经具备良好的特征提取的功能了,所以只需要修改后面几层针对新任务进行少量数据训练就能取得不错的结果


前面层的神经网路用来特征提取,一般情况是当你训练集比较小是用迁移学习,可以防止过拟合。假如原来网路在之前训练的数据集上能有不错的结果,而你的数据集特征包含在之前数据集的特征里面,那特征提取部分就可以拿过来直接用,只训练分类部分的参数即可。


基于参数的迁移学习就是要利用源域和目标域的共同参数,先用源域数据只训练网路前面几层或者后面几层,然后用目标域数据对其他层进行优化,都是可以的。但是针对不同数据效果差别可能比较大。


我说说我的个人理解,不一定准确。首先迁移学习本身就是在相似的任务之间进行知识的迁移;更形象地,可以把知识看作是「砖」,这些「砖」通过不同的组合可以变为不同风格的建筑。而神经网路的学习其实就是通过各种参数来拟合输入对应的真实值,且它的学习是循序渐进的,从最简单的特征(抽象的特征)逐渐到复杂的特征(具象的特征),例如CNN对图像的处理;这些最简单的特征有时候是通用的,尤其是在相似任务之间表现的更加明显。最后,我一直觉得图像处理时的预训练+微调其实就是迁移学习。


推荐阅读:
相关文章