【问题标题】:Using torch.nn.Embedding for GloVe: should we fine-tune the embeddings or just use them as they are?为 GloVe 使用 torch.nn.Embedding:我们应该微调嵌入还是直接使用它们?
【发布时间】:2021-03-26 19:00:46
【问题描述】:

虽然迁移学习/微调最近的语言模型(例如 BERT 和 XLNET)是一种非常普遍的做法,但这对 GloVe 来说如何?

基本上,当使用 GloVe 获得可供下游 NN 使用的密集向量表示时,我看到了两个选项。

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

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

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

embed = nn.Embedding.from_pretrained(torch.tensor(embedding_matrix, dtype=torch.float))
...
dense = nn.Linear(...)

最好的做法是单独使用 GloVe 来获得向量表示(并且只训练密集层和可能的其他层)还是也可以微调嵌入矩阵?

【问题讨论】:

    标签: pytorch glove


    【解决方案1】:

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

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

    1. 前几个 epoch 不微调词嵌入矩阵,保持原样:embeddings = nn.Embedding.from_pretrained(glove_vectors, freeze=True)

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

    按照上述步骤,您将获得两全其美。换句话说,您的词嵌入仍将捕获语义属性,同时针对您自己的下游任务进行定制。最后,有一些作品(例如检查Ye Zhang)表明可以立即进行微调,但我会选择更安全的选项。

    【讨论】:

    • 如果 epoch 的最佳数量相对较小,例如 3-5,那么立即微调嵌入可能也是有意义的,对吧?
    • 真棒的问题!不,一点也不,你可以用冻结的嵌入矩阵训练模型直到收敛(实际上,这是推荐的方法),然后解冻嵌入矩阵并让模型训练几个时期。
    • 酷,谢谢!您是否碰巧对此类程序有可引用的引用?
    • Howard and Ruder 的论文(也包含在答案中)是 NLP 中迁移学习的一个非常好的来源。虽然经过了语言模型微调的案例,但建议的方法也适用于其他地方。
    • 谢谢,很有用! :)
    【解决方案2】:

    没有理由不微调 GloVe 嵌入以获得更好的最终任务得分,除非您必须与使用原始嵌入的另一个模型保持链接(例如,用于解释您的结果) .

    在为您的目标函数微调嵌入时,单词嵌入将(可能)失去其初始属性(在单词相似性和类比任务中表现良好)。

    使用词嵌入只是一种不使用随机向量进行初始化的方法,那么保持随机向量固定是否有意义?

    有几篇文章对词嵌入进行了微调,例如这篇:https://arxiv.org/abs/1505.07931

    我假设您有足够的训练数据。否则最好让词嵌入固定,因为它涉及的训练参数更少,从而避免过度拟合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-16
      相关资源
      最近更新 更多