Thanks for Your answer KFrank
So after I did a switch to BCEWithLogits another question comes to my mind
How to evaluate this problem. I wrote metrics function:
from torchmetrics.classification import (
MultilabelAccuracy, MultilabelAveragePrecision, MultilabelF1Score,
)
def multilabel_metrics(predictions: torch.Tensor, target: torch.Tensor) -> dict:
"""Calculate multilabel classification various metrics"""
num_outputs = target.shape[1]
# change targets to binary [0,1] for metrics
th_target = torch.as_tensor((target - 0.5) > 0, dtype=torch.int64)
multilabel_acc = MultilabelAccuracy(num_labels=num_outputs, average='macro')
multilabel_ap = MultilabelAveragePrecision(num_labels=num_outputs, average="macro")
multilabel_f1 = MultilabelF1Score(num_labels=num_outputs, average='macro')
return {
'multilabel-acc': multilabel_acc(predictions, th_target).item(),
'multilabel-ap': multilabel_ap(predictions, th_target).item(),
'multilabel-f1': multilabel_f1(predictions, th_target).item(),
}
and validation loop
model.eval()
test_loss = 0
preds = torch.tensor([])
targets = torch.tensor([])
loop = tqdm(test_loader, leave=True)
with torch.no_grad():
for (inputs, labels) in loop:
inputs = inputs.to(envi_builder.config.device)
labels = labels.to(envi_builder.config.device)
outputs = model(inputs=inputs)
logits = outputs.logits
# call binary_cross_entropy_with_logits (logits, labels)
loss = call_task_loss(envi_builder.config.task)(logits, labels)
test_loss += loss.item()
#concat all preds and target to use later on metrics
preds = torch.cat((preds, logits.detach().cpu()), 0)
targets = torch.cat((targets, labels.detach().cpu()), 0)
test_loss = test_loss / len(test_loader)
metrics = call_task_metrics(envi_builder.config.task)(preds, targets)
and metrics seems to be very strange ( after first 5 epoch )
Metric multilabel-acc: 0.925
Metric multilabel-ap: 0.177
Metric multilabel-f1: 0.000
example:
from torchmetrics.classification import MultilabelAccuracy
target = tensor([[0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0]])
preds = tensor([[-0.8832, -1.3300, -1.2242, -1.1196, -0.6935, -0.7516, -0.4022], [-0.8940, -1.2300, -1.2766, -1.1840, -0.8486, -0.6994, -0.4034]])
metric = MultilabelF1Score(num_labels=7)
metric(preds, target)
>>tensor(0.9286)
--------------------
from torchmetrics.classification import MultilabelF1Score
target = tensor([[0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0]])
preds = tensor([[-0.8832, -1.3300, -1.2242, -1.1196, -0.6935, -0.7516, -0.4022], [-0.8940, -1.2300, -1.2766, -1.1840, -0.8486, -0.6994, -0.4034]])
metric = MultilabelF1Score(num_labels=7)
metric(preds, target)
>>tensor(0.)
Is there something that I missing ?