将 torch.nn.Embedding 用于 GloVe:我们应该微调嵌入还是按原样使用它们?

ped*_*jjj 2 pytorch glove

虽然迁移学习/微调最近的语言模型,例如 BERT 和 XLNET,是迄今为止非常普遍的做法,但对于 GloVe 来说如何?

基本上,在使用 GloVe 来获得下游神经网络可以使用的密集向量表示时,我看到了两个选项。

1) 微调 GloVe 嵌入(在 pytorch 术语中,启用梯度)

2)只使用没有梯度的嵌入。

例如,给定 GloVe 的嵌入矩阵,我做

embed = nn.Embedding.from_pretrained(torch.tensor(embedding_matrix, dtype=torch.float))
...
dense = nn.Linear(...)
Run Code Online (Sandbox Code Playgroud)

仅使用 GloVe 来获得向量表示(并且只训练密集层和潜在的其他层)是最佳实践,还是也可以微调嵌入矩阵?

gor*_*jan 8

你绝对应该微调你的词嵌入矩阵。事情是这样的,当您使用 GloVe 词嵌入初始化词嵌入矩阵时,您的词嵌入将已经捕获了数据的大部分语义属性。但是,您希望您的词嵌入适合您解决的任务,即特定于任务的(Check Yang)。现在,假设你的数据集中没有足够的数据,你不能自己学习词嵌入矩阵(如果你用随机向量初始化词嵌入矩阵)。正因为如此,你想用在大型数据集上训练过的向量来初始化它,并且是通用的。

要记住一件非常重要的事情?因为模型的其余部分将随机初始化,当您开始训练时,您的词嵌入矩阵可能会遭受灾难性遗忘(查看Howard 和 Ruder以及Kirkpatrick 等人的工作),即梯度会很大,因为您的模型将严重欠拟合前几批的数据,并且您将完全丢失初始向量。您可以通过以下方式克服此问题:

  1. 对于前几个时期,不要微调词嵌入矩阵,只需保持原样:embeddings = nn.Embedding.from_pretrained(glove_vectors, freeze=True)

  2. 在模型的其余部分学会拟合您的训练数据后,降低学习率,解冻嵌入模块embeddings.weight.requires_grad = True,然后继续训练。

通过遵循上述步骤,您将获得两全其美的效果。换句话说,您的词嵌入在为您自己的下游任务量身定制时仍将捕获语义属性。最后,有作品(例如检查叶章)表明立即微调是可以的,但我会选择更安全的选项。

  • [Howard 和 Ruder](https://arxiv.org/abs/1801.06146) 的论文(也包含在答案中)是 NLP 中迁移学习的非常好的来源。尽管它经历了语言模型微调的情况,但建议的方法也适用于其他地方。 (2认同)
  • 谢谢,这非常有用!:) (2认同)