预训练的bert模型中的冻结层

时间:2019-10-22 19:00:16

标签: pytorch

Pre Trained BERT Model

如何冻结以上预训练模型的最后两层(辍学和分类器层)?这样,在运行模型时,我将获得一个密集层作为输出。

2 个答案:

答案 0 :(得分:2)

您已经具有密集层作为输出(Linear)。

无需冻结dropout,因为它只会在训练过程中扩展激活范围。 您可以通过发出以下命令将其设置为evaluation模式(此后该层基本上什么也不做):

model.dropout.eval()

尽管通过train将整个模型设置为model.train()会改变它,所以请注意这一点。

要冻结最后一层的权重,可以发出:

model.classifier.weight.requires_grad_(False)

(或bias(如果您要这样做的话)

如果您想将最后一层更改为另一种形状而不是(768, 2),则只需用另一个模块覆盖它即可,例如

model.classifier = torch.nn.Linear(768, 10)

对于大小为10的输出张量(输入形状必须与模型中指定的形状完全相同,因此为768

答案 1 :(得分:2)

我想向您指出BertForSequenceClassification的定义,您可以使用以下方法轻松避免辍学和分类:

model = BertForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=2)
model.bert() # this will give you the dense layer output

为什么您可以执行上述操作?如果您看一下BertForSequenceClassification的构造函数:

def __init__(self, config):
    super(BertForSequenceClassification, self).__init__(config)
    self.num_labels = config.num_labels

    self.bert = BertModel(config)
    self.dropout = nn.Dropout(config.hidden_dropout_prob)
    self.classifier = nn.Linear(config.hidden_size, self.config.num_labels)

    self.init_weights()

如您所见,您只想忽略dropoutclassifier层。

另一件事,冻结一个层和删除一个层是两个不同的事情。在您的问题中,您提到要冻结分类器层,但是冻结层将无法避免它。冻结意味着您不想训练该层。