Pytorch 使用torch.nn.嵌入手套:我们应该微调嵌入物还是按原样使用它们?
虽然转移学习/微调最近的语言模型,如BERT和XLNET,到目前为止是一种非常普遍的做法,但这对手套来说又如何呢 基本上,当使用手套获得下游NNs可以使用的密集向量表示时,我看到了两种选择 1) 微调手套嵌入(以pytorch术语表示,启用渐变) 2) 只需使用无梯度的嵌入 例如,给定手套的嵌入矩阵,我会Pytorch 使用torch.nn.嵌入手套:我们应该微调嵌入物还是按原样使用它们?,pytorch,glove,Pytorch,Glove,虽然转移学习/微调最近的语言模型,如BERT和XLNET,到目前为止是一种非常普遍的做法,但这对手套来说又如何呢 基本上,当使用手套获得下游NNs可以使用的密集向量表示时,我看到了两种选择 1) 微调手套嵌入(以pytorch术语表示,启用渐变) 2) 只需使用无梯度的嵌入 例如,给定手套的嵌入矩阵,我会 embed = nn.Embedding.from_pretrained(torch.tensor(embedding_matrix, dtype=torch.float)) ... dens
embed = nn.Embedding.from_pretrained(torch.tensor(embedding_matrix, dtype=torch.float))
...
dense = nn.Linear(...)
最好的做法是单独使用手套来获得矢量表示(并且只训练密集层和潜在的其他层),还是对嵌入矩阵进行微调 没有理由不微调手套嵌入,以便为您的最终任务获得更好的分数,除非您必须与使用原始嵌入的另一个模型保持链接(例如,用于解释您的结果) 为目标函数微调嵌入时,单词嵌入将(可能)失去其初始属性(在单词相似性和类比任务中表现良好) 使用单词嵌入只是一种不使用随机向量初始化的方法,所以保持随机向量固定有意义吗 有几篇文章对单词embedings进行了微调,例如:
我假设你有足够的训练数据。否则,最好让单词嵌入固定下来,因为它需要训练的参数较少,从而避免过度拟合。您应该完全微调单词嵌入矩阵。事情是这样的,当您使用手套单词嵌入来初始化单词嵌入矩阵时,您的单词嵌入将已经捕获数据的大部分语义属性。但是,您希望您的单词嵌入适合您解决的任务,即特定于任务的(检查)。现在,假设您的数据集中没有足够的数据,您无法自己学习单词嵌入矩阵(如果您使用随机向量初始化单词嵌入矩阵)。正因为如此,您希望使用在大型数据集上训练过的、通用的向量对其进行初始化 要记住一件非常重要的事情→ 由于模型的其余部分将随机初始化,当您开始训练单词嵌入矩阵时,可能会遭受灾难性遗忘(检查和的工作),即,梯度将非常大,因为您的模型将严重不适合前几个批次的数据,你会完全失去初始向量。您可以通过以下方式克服此问题:
embeddings=nn.embedding.from\u pretrained(手套向量,freeze=True)
embeddings.weight.requires\u grad=True
,然后继续训练
通过遵循上述步骤,您将两全其美。换句话说,您的单词嵌入仍将捕获语义属性,同时为您自己的下游任务进行定制。最后,有一些作品(例如,检查)表明,立即微调是可以的,但我会选择更安全的选项。如果最佳纪元数相对较小,例如3-5个,那么立即微调嵌入也可能是有意义的,对吗?太棒了!不,一点也不,你可以用冻结的嵌入矩阵训练模型直到收敛(实际上,这是推荐的方法),然后解冻嵌入矩阵,让模型训练几个时代。酷,谢谢!你是否碰巧对这种程序有一个合理的参考?来自(也包括在答案中)的论文是NLP中迁移学习的一个很好的来源。虽然它经历了语言模型微调的过程,但建议的方法适用于其他地方。谢谢,这非常有用!:)