calculate the loss in pytorch cnn 1d model

Viewed 21

I have a dataset in shape n*65 where each sample contains the actual output in the first index and 64 feature in the rest, I loaded the data and applied the 1D CNN to predict the output based on the 64 feature, and I got an issue in CrossEntropyLoss() while the outputs = model(points) gives an array with protection

tensor([ 0.1098, -0.1144,  0.0992, -0.1076, -0.1019,  0.1185,  0.1309, -0.0208,
         0.1109,  0.0791], device='cuda:0', grad_fn=<AddBackward0>)

the labels are one number between 1-10

tensor([7.], device='cuda:0')

and for that I'm getting a RuntimeError: size mismatch (got input: [10], target: [1]) error I know If we want to apply nn.CrossEntropyLoss we don't need to add a softmax layer and y "the output" should be one number like the labels. I guess that I'm missing a layer some ware before applying to lose function.

So how can I solve mismatch (got input: [10], target: [1])?

And when I tried to make set the batch size bigger than one a got a Given groups=1, weight of size [8, 1, 3], expected input[1, 4, 64] to have 1 channels, but got 4 channels instead error ?

import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from torch.utils.data import Dataset, DataLoader
import sys


class HandDataset(Dataset):
    def __init__(self,data):
        xy = np.loadtxt(data,dtype=np.float32) 
        self.n_samples = xy.shape[0]
        # here the first column is the class label, the rest are the features
        self.x_data = torch.from_numpy(xy[:, 1:])  # size [n_samples, n_features]
        self.y_data = torch.from_numpy(xy[:, 0]) # size [n_samples, 1]
    # support indexing such that dataset[i] can be used to get i-th sample
    def __getitem__(self, index):
        return self.x_data[index], self.y_data[index]

    # we can call len(dataset) to return the size
    def __len__(self):
        return self.n_samples


class ConvNet1D(nn.Module):
      def __init__(self):
          super(ConvNet1D, self).__init__()
          self.conv1  = nn.Conv1d(1,8,3,padding=1)
          self.conv2  = nn.Conv1d(8,16,5,padding=2)
          self.pool   = nn.MaxPool1d(2, 2)
          self.conv3  = nn.Conv1d(16,32,3,padding=1)
          self.conv4  = nn.Conv1d(32,64,5,padding=2)
          self.fc1    = nn.Linear(1024, 128) # 64*12
          self.fc2    = nn.Linear(128, 64)
          self.fc3    = nn.Linear(64, 10)

      def forward(self, x):
        x = F.relu(self.conv1(x))            
        x = F.relu(self.conv2(x))
        x = self.pool(x)      
        x = F.relu(self.conv3(x))            
        x = F.relu(self.conv4(x))
        x = self.pool(x)  
        x = x.view(1024)            
        x = F.relu(self.fc1(x))                
        x = F.relu(self.fc2(x))                
        x = self.fc3(x)                       
        return x



data = ".data.txt"
# create dataset
dataset = HandDataset(data=data)
# Device configuration
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# Hyper-parameters 
num_epochs = 5
batch_size = 4
learning_rate = 0.001
train_loader = DataLoader(dataset=dataset,
                          batch_size=1,
                          shuffle=True,
                          num_workers=2)

model = ConvNet1D().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

n_total_steps = len(train_loader)

for epoch in range(num_epochs):
    for i, (points, labels) in enumerate(train_loader):

        points = points.to(device)
        labels = labels.to(device)
        # Forward pass
        outputs = model(points)
        loss = criterion(outputs, labels)

        # Backward and optimize
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if (i+1) % 2000 == 0:
            print (f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{n_total_steps}], Loss: {loss.item():.4f}')

print('Finished Training')
PATH = './model.pth'
torch.save(model.state_dict(), PATH)
1 Answers

According to your code, you must feed your network with a tensor of shape (N, 1, L_in), where L_in is the sequence length and N the batch size. Secondly, CrossEntropyLoss expects a prediction tensor shaped (N, *, C) and target tensor (N, *), here (N, C) and (N,) respectively since you have a single predicted value per sequence.

In your example you have a single element per batch, the input should therefore be of the shape (1, L_in) and the model would output (1, C), which means the target tensor must be (1,).

Related