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个数。
我正在尝试使用序列到序列模型进行命名实体识别。我的输出是简单的 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个数。