Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in Binary Classification in NeuralNetBinaryClassifier. #502

Closed
kaihhe opened this issue Jul 31, 2019 · 6 comments · Fixed by #515
Closed

Error in Binary Classification in NeuralNetBinaryClassifier. #502

kaihhe opened this issue Jul 31, 2019 · 6 comments · Fixed by #515

Comments

@kaihhe
Copy link

kaihhe commented Jul 31, 2019

When I use BinaryClassifer, and there is always an error ValueError: The target data should be 1-dimensional..

I change my target data into 1-dimensional with array.ravel(), it show ValueError: Target size (torch.Size([128])) must be the same as input size (torch.Size([128, 1])).

When I use set criterion=nn.BCEWithLogitsLoss, it run successfully.

I thinks there is wrong in classifier.check_data().

@BenjaminBossan
Copy link
Collaborator

Can you tell us what criterion you are using if not BCEWithLogitsLoss?

As a workaround, you could override check_data and see if that works.

@kaihhe
Copy link
Author

kaihhe commented Aug 4, 2019

Yes I use BCEWithLogitsLoss. I use BCELoss and it works. I wish you could fix that problem about BCEWithLogitsLoss.

@BenjaminBossan
Copy link
Collaborator

I cannot reproduce the error. Can you please post what kind of data you use, i.e.

  • type
  • dtype
  • shape

of X and y? Also, the code for the module would help.

@kaihhe
Copy link
Author

kaihhe commented Aug 5, 2019

I write a case for the error.

import numpy as np
import torch as torch
import torch.nn as nn
import torch.nn.functional as F
from skorch import NeuralNetBinaryClassifier
torch.set_default_dtype(torch.float64)


class MyNet(nn.Module):
    def __init__(self):
        super(MyNet, self).__init__()
        self.linear = nn.Linear(100, 50)
        self.output = nn.Linear(50, 1)

    def forward(self, input):
        out = input
        out = self.linear(out)
        out = F.relu(out)
        out = self.output(out)
        return out


X = np.random.normal(size=(200, 100))
y = np.zeros((200,1))
y[100:] = 1
net = NeuralNetBinaryClassifier(MyNet)
net.fit(X, y) # ValueError: The target data should be 1-dimensional.
net.fit(X, y.ravel()) # ValueError: X and y have inconsistent lengths.

I change the loss into BCELoss and add sigmoid function in MyNet. It works.

out = torch.sigmoid(out)

net = NeuralNetBinaryClassifier(MyNet, criterion=nn.BCELoss)
net.fit(X, y.ravel())

@thomasjpfan
Copy link
Member

The output of the Module needs to be 1-D:

import torch.nn as nn
import numpy as np
from skorch import NeuralNetBinaryClassifier
from torch.nn.functional import relu

class MyNet(nn.Module):
    def __init__(self):
        super(MyNet, self).__init__()
        self.linear = nn.Linear(100, 50)
        self.output = nn.Linear(50, 1)

    def forward(self, input):
        out = input
        out = self.linear(out)
        out = relu(out)
        out = self.output(out)
        return out.squeeze(-1)


X = np.random.normal(size=(200, 100)).astype('float32')
y = np.zeros(200).astype('float32')
y[:100] = 1
net = NeuralNetBinaryClassifier(MyNet)

@kaihhe
Copy link
Author

kaihhe commented Aug 6, 2019

Ok, thank you.

@kaihhe kaihhe closed this as completed Aug 6, 2019
BenjaminBossan added a commit that referenced this issue Aug 25, 2019
* more fit runs because of flaky output (fixes #514)
* add a classes_ attribute for things like
  CalibratedClassifierCV (fixes #465)
* make y_proba 2-dim, which works better with certain sklearn
  metrics (fixes #442)
* automatically squeezes output if module returns (n,1) shape (fixes
  #502)

This could break backwards compatibility if someone relies on
y_proba to be 1d.
ottonemo pushed a commit that referenced this issue Sep 27, 2019
* Several improvements to NeuralNetBinaryClassifier

* more fit runs because of flaky output (fixes #514)
* add a classes_ attribute for things like
  CalibratedClassifierCV (fixes #465)
* make y_proba 2-dim, which works better with certain sklearn
  metrics (fixes #442)
* automatically squeezes output if module returns (n,1) shape (fixes
  #502)

This could break backwards compatibility if someone relies on
y_proba to be 1d.

* Address reviewer comments

Check shapes more precisely

* Add PR number to CHANGES

* Use better hyperparameters to reduce flakyness of binary classifer

* Remove obsolote line in test

Co-Authored-By: ottonemo <[email protected]>

* Update infer method in NeuralNetBinaryClassifier

* add a docstring
* correct error message when output dim > 2
* also works when more than 1 output is returned
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants