【问题标题】:Building a Neural Network for Binary Classification on Top of Pre-Trained Embeddings Not Working?在预训练嵌入的基础上构建用于二进制分类的神经网络不起作用?
【发布时间】:2021-09-17 13:05:40
【问题描述】:

我正在尝试在预训练模型输出的嵌入之上构建神经网络。具体来说:我将基本模型的 logits 保存到磁盘,其中每个示例都是形状为 512 的数组(最初对应于图像),并带有关联的标签(0 或 1)。这就是我现在正在做的事情:

这是我的模型定义和训练循环。现在它是一个简单的线性层,只是为了确保它可以正常工作,但是,当我运行这个脚本时,损失从 0.4 开始,而不是 ~.7,这是二进制分类的标准。谁能发现我哪里出错了?

from transformers.modeling_outputs import SequenceClassifierOutput
class ClassNet(nn.Module):
    def __init__(self, num_labels=2):
        super(ClassNet, self).__init__()
        self.num_labels = num_labels
        self.classifier = nn.Linear(512, num_labels) if num_labels > 0 else nn.Identity()
    def forward(self, inputs):
    
    logits = self.classifier(inputs)
    loss_fct = nn.CrossEntropyLoss()
    loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
    return SequenceClassifierOutput(
            loss=loss,
            logits=logits
        )


model = ClassNet()
optimizer = optim.Adam(model.parameters(), lr=1e-4,weight_decay=5e-3) #  L2 regularization
loss_fct=nn.CrossEntropyLoss()



for epoch in range(2):  # loop over the dataset multiple times

running_loss = 0.0
for i, data in enumerate(train_loader, 0):
    # get the inputs; data is a list of [inputs, labels]
    #data['embeddings'] -> torch.Size([1, 512])
    #data['labels'] -> torch.Size([1])
    inputs, labels = data['embeddings'], data['labels']

    # zero the parameter gradients
    optimizer.zero_grad()

    # forward + backward + optimize
    outputs = model(inputs)
    loss = loss_fct(outputs.logits.squeeze(1), labels.squeeze())
    loss.backward()
    optimizer.step()

    # print statistics
    running_loss += loss.item()
    if i % 2000 == 1:    # print every 2000 mini-batches
        print('[%d, %5d] loss: %.3f' %
              (epoch + 1, i + 1, running_loss / 2000))
        running_loss = 0.0

打印outputs.logits.squeeze(1)labels.squeeze() 的示例:

#outputs.logits.squeeze(1)
tensor([[-0.2214,  0.2187],
        [ 0.3838, -0.3608],
        [ 0.9043, -0.9065],
        [-0.3324,  0.4836],
        [ 0.6775, -0.5908],
        [-0.8017,  0.9044],
        [ 0.6669, -0.6488],
        [ 0.4253, -0.5357],
        [-1.1670,  1.1966],
        [-0.0630, -0.1150],
        [ 0.6025, -0.4755],
        [ 1.8047, -1.7424],
        [-1.5618,  1.5331],
        [ 0.0802, -0.3321],
        [-0.2813,  0.1259],
        [ 1.3357, -1.2737]], grad_fn=<SqueezeBackward1>)
#labels.squeeze()
tensor([1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0])
#loss
tensor(0.4512, grad_fn=<NllLossBackward>)

【问题讨论】:

    标签: python machine-learning deep-learning neural-network pytorch


    【解决方案1】:

    您只是从第二次迭代开始打印。以上将有效地打印每个200k+1 步骤,但i0 开始

    if i % 2000 == 1:    # print every 2000 mini-batches
        print('[%d, %5d] loss: %.3f' %
              (epoch + 1, i + 1, running_loss / 2000))
    

    已经发生了一个梯度下降步骤。这可能足以从初始损失值 -log(1/2) = ~0.69 变为您观察到的损失值 ~0.45

    【讨论】:

    • 太棒了,它现在可以工作了!只是想知道,我将如何从 logits 中获取类的预测?我是否取 [1,2] 张量的最大值? IE。如果第 0 个预测更高,那么它属于第 0 类,否则属于第 1 类?
    • 例如,您可以通过outputs.logits.argmax(1) (docs) 获取每个批次元素的类标签。
    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 2019-05-24
    • 2016-04-03
    • 1970-01-01
    • 2013-08-24
    • 2017-11-27
    • 2017-05-23
    • 2020-10-19
    相关资源
    最近更新 更多