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

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

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

阿晨1998 2022-11-24 15:21:24

我不明白为什么我的 BERT 模型在评估期间返回相同的输出。我的模型在训练期间的输出似乎是正确的,因为值不同,但在评估期间完全相同。

http://img3.sycdn.imooc.com/637f1b920001497c08020664.jpg

这是我的 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贡献1526条经验 获得超9个赞

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

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


查看完整回答
反对 回复 6天前
?
慕后森

TA贡献1514条经验 获得超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


查看完整回答
反对 回复 6天前
?
红糖糍粑

TA贡献1546条经验 获得超4个赞

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

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

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


查看完整回答
反对 回复 6天前

添加回答

举报

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