Как модель BERT выбирает порядок этикеток?

Я тренирую BertForSequenceClassification для задачи классификации. Мой набор данных состоит из «содержит побочные эффекты» (1) и «не содержит побочных эффектов» (0). Набор данных содержит все единицы, а затем нули после (данные не перемешиваются). Для обучения я перетасовал свои данные и получил логиты. Насколько я понял, логиты - это распределения вероятностей до softmax. Пример логита: [-4,673831, 4,7095485]. Соответствует ли первое значение метке 1 (содержит AE), потому что оно появляется первым в наборе данных, или метке 0. Любая помощь будет принята с благодарностью.

1 ответ

Первое значение соответствует метке 0, а второе значение соответствует метке 1. Что делает это вывод пула на линейный уровень (после выпадения, которое я проигнорирую в этом ответе). Давайте посмотрим на следующий пример:

      from torch import nn
from transformers import BertModel, BertTokenizer
t = BertTokenizer.from_pretrained('bert-base-uncased')
m = BertModel.from_pretrained('bert-base-uncased')
i = t.encode_plus('This is an example.', return_tensors='pt')
o = m(**i)
print(o.pooler_output.shape)

Выход:

      torch.Size([1, 768])

Pooled_output - это тензор формы [batch_size,hidden_size] и представляет контекстуализированный (т.е. было применено внимание) [CLS]токен ваших входных последовательностей. Этот тензор на линейный слой для вычисления подаетсялогитов вашей последовательности:

      classificationLayer = nn.Linear(768,2)
logits = classificationLayer(o.pooler_output)

Когда мы нормализуем эти логиты, мы видим, что линейный слой предсказывает, что наш ввод должен принадлежать метке 1:

      print(nn.functional.softmax(logits,dim=-1))

Вывод (будет отличаться, так как линейный слой инициализируется случайным образом):


Линейный слой применяет линейное преобразование: y=xA^T+bи вы уже можете видеть, что линейный слой не знает ваших меток. Он «только» имеет матрицу весов размером [2,768] для создания логитов размера [1,2] (то есть: первая строка соответствует первому значению, а вторая строка - второму):

      import torch:

logitsOwnCalculation = torch.matmul(o.pooler_output,  classificationLayer.weight.transpose(0,1))+classificationLayer.bias
print(nn.functional.softmax(logitsOwnCalculation,dim=-1))

Выход:

      tensor([[0.1679, 0.8321]], grad_fn=<SoftmaxBackward>)

Модель BertForSequenceClassification, такBertForSequenceClassificationподает обучается путем применения . Эта функция потерь дает небольшую потерю, когда логиты для определенного класса (метка в вашем случае) лишь незначительно отклоняются от ожидаемого. Это означает, что CrossEntropyLossCrossEntropyLoss - это тот, который позволяет вашей модели узнать, что первый логит должен быть высоким, когда вход does not contain adverse effect или маленький, когда это contains adverse effect. Вы можете проверить это на нашем примере следующим образом:

      loss_fct = nn.CrossEntropyLoss()
label0 = torch.tensor([0]) #does not contain adverse effect
label1 = torch.tensor([1]) #contains adverse effect
print(loss_fct(logits, label0))
print(loss_fct(logits, label1))

Выход:

      tensor(1.7845, grad_fn=<NllLossBackward>)
tensor(0.1838, grad_fn=<NllLossBackward>)
Другие вопросы по тегам