EncoderDecoderModel 转换decoder的classifier层

EncoderDecoderModel converts classifier layer of decoder

我正在尝试使用序列到序列模型进行命名实体识别。我的输出是简单的 IOB 标签,因此我只想预测每个标记 (IOB) 的 3 个标签的概率。

我正在尝试使用 HuggingFace 实现的 EncoderDecoderModel,DistilBert 作为我的编码器,BertForTokenClassification 作为我的解码器。

首先,我导入我的编码器和解码器:

encoder = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased")
encoder.save_pretrained("Encoder")

decoder = BertForTokenClassification.from_pretrained('bert-base-uncased',
                                                     num_labels=3,
                                                     output_hidden_states=False,
                                                     output_attentions=False)
decoder.save_pretrained("Decoder")
decoder

当我检查我的解码器模型时,我可以清楚地看到具有 out_features=3:

的线性分类层
## sample of output:
  )
  (dropout): Dropout(p=0.1, inplace=False)
  (classifier): Linear(in_features=768, out_features=3, bias=True)
)

然而,当我在我的 EncoderDecoderModel 中组合这两个模型时,解码器似乎被转换成另一种分类器 - 现在 out_features 作为我词汇量的大小:

bert2bert = EncoderDecoderModel.from_encoder_decoder_pretrained("./Encoder","./Decoder")
bert2bert

## sample of output:
(cls): BertOnlyMLMHead(
      (predictions): BertLMPredictionHead(
        (transform): BertPredictionHeadTransform(
          (dense): Linear(in_features=768, out_features=768, bias=True)
          (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
        )
        (decoder): Linear(in_features=768, out_features=30522, bias=True)
      )
    )

这是为什么?我怎样才能在我的模型中保持 out_features = 3?

Huggingface 为其模型使用不同的头部(取决于网络和任务)。虽然这些模型的一部分是相同的(例如上下文编码器模块),但它们在最后一层即头部本身有所不同。

例如,对于 class化问题,他们使用 XForSequenceClassification 头,其中 X 是语言模型的名称,例如 Bert、Bart 等。

话虽如此,EncoderDecoderModel模型使用语言建模头,而您已经存储的解码器使用class化头。由于 EncoderDecoderModel 看到这些差异,它使用自己的 LMhead 这是一个线性层,其中 in_features 的 768 映射到 30522 作为词汇表的数量。

为了避免这个问题,你可以使用 vanilla BERTModel class 来输出隐藏的表示,然后为 classification 添加一个线性层,它接收与 [CLS] BERT的token,形状为768,然后通过线性层映射到输出向量3,也就是你的labels个数。