Кривая ROC и AUC для задачи с несколькими классами и метками. ValueError: целевые оценки должны быть вероятностями для мультикласса roc_auc

Итак, я хотел бы рассчитать кривую ROC и AUC моего кода, где у меня есть 28 классов, и мои изображения могут быть несколькими одновременно. Например, изображение может одновременно принадлежать к классам 1, 2 и 3. У меня есть вектор из 28 позиций в качестве метки в y_true, и там он отмечен 1 в позиции для класса. Например, если изображение принадлежит классу 2, 3 и 5 в позициях 2, 3 и 5 вектора, они будут отмечены 1 -> [0,0,1,1,0,1,0,0, 0, ..., 0]

def data_validate(samples, loss, network, f1_class):

x, y_true = samples #x-->valor na matriz, y --> label
x = x.cuda() #to GPU
y_true = y_true.cuda() #to GPU
y_pred = network(x) #aqui executa o forward do model.py dos {batch_size} e retorna o fc
y_pred = torch.sigmoid(y_pred)
erro = loss(y_pred, y_true)
f1_class.acumulate(y_pred.cpu().detach(), y_true.cpu().detach(),th=0.5)
print(y_pred)
for i in range(28):
    auc_score = roc_auc_score(y_true[:][i].cpu().detach(), y_pred.cpu().detach(), multi_class='ovr')

return erro, y_pred.cpu().detach(), y_true.cpu().detach()

но я получаю эту ошибку -> ValueError: целевые баллы должны быть вероятностями для многоклассового roc_auc, т.е. они должны в сумме составлять 1,0 по классам


person Tarlison Sander    schedule 02.02.2020    source источник


Ответы (2)


Вы можете увидеть в документации PyTorch, что torch.sigmoid() вывод не гарантируется, что сумма будет равна 1 по классам.

>>> a = torch.randn(4)
>>> a
tensor([ 0.9213,  1.0887, -0.8858, -1.7683])
>>> torch.sigmoid(a)
tensor([ 0.7153,  0.7481,  0.2920,  0.1458])

Для устранения этой ошибки необходимо нормализовать y_pred.

Код для этого можно найти на здесь. Вам понадобится что-то вроде:

row_sums = torch.sum(y_pred, 1) # normalization 
row_sums = row_sums.repeat(1, num_classes) # expand to same size as out
y_pred = torch.div( y_pred , row_sums ) # these should be histograms
person Priya    schedule 02.02.2020
comment
Спасибо, здесь работает, измените мой код на: row_sums = torch.sum (y_pred, 1) row_sums = row_sums.repeat (28) row_sums = row_sums.reshape (y_pred.shape) y_pred = torch.div (y_pred, row_sums) для i в диапазон (len (y_pred)): auc_score = roc_auc_score (y_true [:] [i] .cpu (). detach (), y_pred [:] [i] .cpu (). detach (), multi_class = 'ovr') Думаю, теперь я могу подсчитывать баллы AUC для каждого класса и по партиям - person Tarlison Sander; 02.02.2020

Код изменен на:

def data_validate(samples, loss, network, f1_class):
    x, y_true = samples #x-->valor na matriz, y --> label
    x = x.cuda() #to GPU
    y_true = y_true.cuda() #to GPU
    y_pred = network(x) #aqui executa o forward do model.py dos {batch_size} e retorna o fc
    y_pred = torch.sigmoid(y_pred)
    erro = loss(y_pred, y_true)
    f1_class.acumulate(y_pred.cpu().detach(), y_true.cpu().detach(),th=0.5)

    row_sums = torch.sum(y_pred, 1)
    row_sums = row_sums.repeat(28)
    row_sums = row_sums.reshape(y_pred.shape)
    y_pred = torch.div( y_pred , row_sums ) 

    for i in range(len(y_pred)):
        auc_score = roc_auc_score(y_true[:][i].cpu().detach(), y_pred[:][i].cpu().detach(), multi_class='ovr')

    return erro, y_pred.cpu().detach(), y_true.cpu().detach()

Как сказала Прия.

person Tarlison Sander    schedule 02.02.2020