为了账号安全,请及时绑定邮箱和手机立即绑定

BERT 编码层在评估期间为所有输入生成相同的输出 (PyTorch)

BERT 编码层在评估期间为所有输入生成相同的输出 (PyTorch)

阿晨1998 2022-11-24 15:21:24
我不明白为什么我的 BERT 模型在评估期间返回相同的输出。我的模型在训练期间的输出似乎是正确的,因为值不同,但在评估期间完全相同。这是我的 BERT 模型类class BERTBaseUncased(nn.Module):    def __init__(self):        super(BERTBaseUncased, self).__init__()        self.bert = BertModel.from_pretrained("bert-base-uncased")        self.bert_drop = nn.Dropout(0.3)        self.out = nn.Linear(768, 4)    def forward(self, ids, mask, token_type_ids):        _, o2 = self.bert(ids, attention_mask=mask, token_type_ids=token_type_ids) # Use one of the outputs        bo = self.bert_drop(o2)        return self.out(bo)我的数据集类class BERTDataset:    def __init__(self, review, target, tokenizer, classes=4):        self.review = review        self.target = target        self.tokenizer = tokenizer        self.max_len = max_len        self.classes = classes    def __len__(self):        return len(self.review)    def __getitem__(self, item):        review = str(self.review)        review = " ".join(review.split())        inputs = self.tokenizer.encode_plus(review, None, add_special_tokens=True, max_length= self.max_len,                                            pad_to_max_length=True, return_token_type_ids=True,                                            return_attention_masks=True)        ids = inputs["input_ids"]        mask = inputs["attention_mask"]        token_type_ids = inputs["token_type_ids"]        return {            'ids': torch.tensor(ids, dtype=torch.long),            'mask': torch.tensor(mask, dtype=torch.long),            'token_type_ids': torch.tensor(token_type_ids, dtype=torch.long),            'targets': torch.tensor(to_categorical(self.target[item], self.classes), dtype=torch.float)        }
查看完整描述

3 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

万一其他人遇到问题,也许您忘记使用官方论文中推荐的学习率之一:5e-5、3e-5、2e-5

如果学习率太高(例如 0.01),梯度似乎会极化,从而导致 val 集重复出现相同的 logits。


查看完整回答
反对 回复 2022-11-24
?
慕后森

TA贡献1802条经验 获得超5个赞

在您的培训代码中,您不会返回经过培训的模型。


看来您正在一个函数内训练您的模型而不返回它。函数结束后权重将丢失。因此,在评估部分,模型输出随机值。


def train_fn(data_loader, model, optimizer, device, scheduler):

    model.train()


    total_loss = 0.0


    for bi, d in tqdm(enumerate(data_loader), total=len(data_loader)):

        ids = d['ids']

        token_type_ids = d['token_type_ids']

        mask = d['mask']

        targets = d['targets']


        ids = ids.to(device, dtype=torch.long)

        token_type_ids = token_type_ids.to(device, dtype=torch.long)

        mask = mask.to(device, dtype=torch.long)

        targets = targets.to(device, dtype=torch.float)


        optimizer.zero_grad()


        outputs = model(

            ids=ids,

            mask=mask,

            token_type_ids=token_type_ids

        )


        loss = loss_fn(outputs, targets)

        total_loss += loss.item()

        loss.backward()


        optimizer.step()

        scheduler.step()


    return model, total_loss/len(data_loader) # this will help


查看完整回答
反对 回复 2022-11-24
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

问题出在我的数据加载器类中。我传递了整个数据集,而不仅仅是一行。

def __getitem__(self, item):
        review = str(self.review[item])
        review = " ".join(review.split())

这解决了它。感谢 Zabir Al Nazi 的协助。


查看完整回答
反对 回复 2022-11-24
  • 3 回答
  • 0 关注
  • 228 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信