Accuracy metrics expecting target data type as long but BCElosswithlogistic loss function expecting as float datatype

Hi,

I have created custom dataset in pytorch. I passed custom dataset object to dataloader. Train and validation dataloader objects passed to fastai databunch.

data = DataBunch(train_dataloader, validation_dataloader)

I am using loss_function = torch.nn.BCEWithLogitsLoss()

loss function expecting target should be float. So I am passing input & target as float to the model.

learn = Learner(data,model.cuda(),opt_func=opt_func,loss_func=loss_func, metrics=error_rate)

I am getting error while learn.fit_one_cycle(20,max_lr=1e-02,pct_start=0.3) . Expected object of scalar type Long but got scalar type Float for argument #2 'other’

Now what i understood is i should pass target as float for loss calculation and for accuracy calculation i should pass target as long. Help me to do this

THanks

If you have BCEWithLogitsLoss, you can’t use accuracy, which expects outputs/targets like CrossEntropyLoss. Instead you can use accuracy_thresh and specify which threshold you want to apply to your predictions to consider them as 0s/1s

1 Like

Hi @sgugger ,

Thank you for your reply. As you mentioned i am using accuracy_thresh as a metrics while creating instance of Leaner. In this case i am getting accuracy_thresh = 0.47 always. What does it mean?

one more problem while using learn.fit_one_cycle(2, max_lr=slice(1e-6, 1e-1)). the error is ZeroDivisionError: division by zero . This error is because of slice(1e-6,1e-1). How to resolve it?

The second I would assume comes from your layer groups being singular, and so you can’t do differential learning rates (the two we pass in). I didn’t notice a learn.split() anywhere so this is why I believe so. You can just pass in a singular learning rate and you will be okay.

On the first, think of that as your overall accuracy. If we look at the docs: https://docs.fast.ai/metrics.html#accuracy_thresh

“Computes accuracy when y_pred and y_true are the same size. Predictions are compared to thresh after sigmoid is maybe applied. Then we count the numbers that match the targets.”

So given a certain threshold, after this is applied how close were our predictions to our target. In your case we can say 47% accuracy was achieved. Does this help?

1 Like

Hi @muellerzr ,

In the second case i didn’t use learn.split(). If i use learn.split() it is throwing error object does not support indexing. Below is my model. What should I change in the model creation?

from torch import nn
class ConvRNN(nn.Module):

def __init__(self):
    super(ConvRNN, self).__init__()
    self.layer1 = nn.Sequential(
            nn.Conv2d(in_channels=1, out_channels=32, kernel_size=(5,5), stride=(1,1), padding=(2,2)),
            nn.BatchNorm2d(num_features=32),
            nn.ReLU(),
            nn.Dropout(p=0.25),
            nn.MaxPool2d(kernel_size=(1,5)))

    self.layer2 = nn.Sequential(
            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=(5,5), stride=(1,1), padding=(2,2)),
            nn.BatchNorm2d(num_features=32),
            nn.ReLU(),
            nn.Dropout(p=0.25),
            nn.MaxPool2d(kernel_size=(1,4)))

    self.layer3 = nn.Sequential(
            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=(5,5), stride=(1,1), padding=(2,2)),
            nn.BatchNorm2d(num_features=32),
            nn.ReLU(),
            nn.Dropout(p=0.25),
            nn.MaxPool2d(kernel_size=(1,2)))

    self.rnn = nn.GRU(input_size=32, hidden_size=32, num_layers=1, dropout=0, batch_first=True)
    self.linear1 = nn.Linear(in_features=4768, out_features=1)
    self.sigmoid = nn.Sigmoid()
def forward(self, x):
    out = self.layer1(x)
    out = self.layer2(out)
    out = self.layer3(out)

    out = out.permute(0, 2, 1, 3)
    out = out.view(out.shape[0], out.shape[1], out.shape[2])
    out, _ = self.rnn(out)
    out = out.contiguous().view(out.shape[0], out.shape[1] * out.shape[2])
    out = self.linear1(out)
    out = self.sigmoid(out)

    return out

In the first case, the accuracy_threshold is showing 0.470400 irrespective of training and validation. I don’t think 0.470400 is accuracy.

Hmm… odd on the second but. And to the first let me ask a question: are you doing transfer learning? If not, then one layer group may be all you need.

The same will happen with our tabular models as we don’t use pretrained weights, and so there’s no need to split the layer groups. Instead we only pass in one learning rate into fit_one_cycle

1 Like

I am not doing transfer learning. Okay, I will not use split.