-1

I have a dataset that looks like this:

enter image description here

The labels are basically a list of items (let's say, cars in a parking lot) I am given, where there are 10 of them in total, labeled from 0 to 10. I have 14 classes (let's say, 14 different car brands). Every float point value is just percentage of which class that particular item belongs to. For example, Item 2 is likely class 2 with a probability of 0.995275:

print(set(list(df['label'])))
> {0, 1, 2, 3, 4, 5, 6, 7, 9}

My goal is to train a classifier to output an integer from 0 to 14 to predict what class label x belongs to.

I am trying to build a feedforward NN with 3 hidden layers (+ input and output layers) and takes 15 inputs and outputs a prediction from 0 to 14. This is what I've designed so far:

class NNO(nn.Module):
  def __init__(self):
    super(NNO, self).__init__()
    h= [2,1]
    self.hidden = nn.Linear(h[0], h[1])
    self.hidden = nn.Linear(2,20)
    self.hidden = nn.Linear(20,20)
    self.output = nn.Linear(20,15)

    self.sigmoid = nn.Sigmoid()
    self.softmax = nn.Softmax(dim = 1)
  
  def forward(self, y):
    x = self.hidden(x)
    x = self.sigmoid(x)
    x = self.output(x)
    x = self.softmax(x)

My question is this. How do I feed the dataset to my NN to start training the epochs? I couldn't find any resource that pertains to a dataset like this.

Onur-Andros Ozbek
  • 2,998
  • 2
  • 29
  • 78

1 Answers1

1

Here is the answer:

# First I create some dummy data
label = np.random.randint(0, 14, 1000)
random = np.random.random((1000, 14))
total = pd.DataFrame(data=random, columns=[f'{i}_col' for i in range(14)])
total['label'] = label

'''
From what I understood you need 1 class in output that has the highest probability and hence this is a multi-class classification problem. In my case, I will just use the highest value from `random` as the target class. 
'''
class TDataset(torch.utils.data.Dataset):
    def __init__(self, df):
        self.inputs = df[[f'{i}_col' for i in range(14)] + ['label']].values
        self.outputs = df[[f'{i}_col' for i in range(14)]].values
    
    def __len__(self):
        return len(self.inputs)
    
    def __getitem__(self, idx):
        x = torch.tensor(self.inputs[idx], dtype=torch.float)
        y = torch.tensor(np.argmax(self.outputs[idx]))
        return x, y

ds = TDataset(total)
dl = torch.utils.data.DataLoader(ds, batch_size=64)

# After doing this I will create a model which takes 15 inputs and 
# Give 14 outputs in my case which represent the logits

class NNO(nn.Module):
    def __init__(self):
        super(NNO, self).__init__()
        self.hidden = nn.Linear(15, 20)
        self.relu = nn.ReLU()
        self.output = nn.Linear(20, 14)
  
    def forward(self, x):
        x = self.hidden(x)
        x = self.relu(x)
        x = self.output(x)
        return x

# Now we create the model object
m = NNO()

sample = None
for i in dl:
    sample = i
    break

print(m(sample[0]).shape) # shape = [64, 14] as desired.

# Now we define the loss function and then the optimizer
loss_fn = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(m.parameters())

# Now we define the training loop
for i in range(500): # for 500 epochs
    epoch_loss = 0
    for idx, data in enumerate(dl):
        inputs = data[0]
        targets = data[1] # change accordingly for your data
        preds = m(inputs)
        optimizer.zero_grad()
        loss = loss_fn(preds, targets)
        epoch_loss += loss
        loss.backward()
        optimizer.step()
    
    if (i%50 == 0):
        print('loss: ', epoch_loss.item() / len(dl))

'''
Now at the time of inference, you just need to apply softmax on the results of your model and select the most probable output.
'''

preds = m(sample[0])
predicted_classes = torch.argmax(torch.nn.functional.softmax(preds), axis=1)
# Here the predicted classes are the desired final output.
Abhishek Prajapat
  • 1,793
  • 2
  • 8
  • 19