CNN RunTime Error

skyfail_ufg: <p>I’m trying to build a CNN for a 100 class 3 channel images, but I’m getting the error: “RuntimeError: only batches of spatial targets supported (3D tensors) but got targets of dimension: 1”<br>
I tried to flatten the output with dim_start=1, but the loss was increasing with each mini-batch until NaN.<br>
Code:</p>
<p>import os<br>
import sys<br>
from google.colab import drive<br>
import torch<br>
from torch import nn<br>
from torch.utils.data import DataLoader<br>
import torchvision as tv<br>
from torchvision.transforms import v2</p>
<p>DRIVE_DEFAULT_PATH = ‘/content/drive’<br>
if not os.path.exists(DRIVE_DEFAULT_PATH):<br>
drive.mount(DRIVE_DEFAULT_PATH)</p>
<p>DRIVE_DEFAULT_PATH = DRIVE_DEFAULT_PATH + ‘/MyDrive’<br>
CLASS_DEFAULT_PATH = ‘/RNP’<br>
ASSIGNMENT_PATH = ‘/Trabalho 01/Sports’<br>
WORK_PATH = DRIVE_DEFAULT_PATH + CLASS_DEFAULT_PATH + ASSIGNMENT_PATH</p>
<p>def setLoader(path, batch_size, train):<br>
if(train):<br>
transforms = v2.Compose([v2.ToImage(),<br>
v2.ToDtype(torch.float32, scale=True),<br>
v2.Normalize(mean=[0.4713, 0.4699, 0.4548], std=[0.3081, 0.3020, 0.2961])])<br>
return torch.utils.data.DataLoader(tv.datasets.ImageFolder(WORK_PATH + path, transform=transforms),<br>
batch_size=batch_size,<br>
shuffle=True,<br>
num_workers=0)</p>
<p>class CNN(nn.Module):<br>
def <strong>init</strong>(self):<br>
super().<strong>init</strong>()<br>
self.step1 = nn.Sequential(nn.Conv2d(3,400,3,padding=1),<br>
nn.ReLU(),<br>
<span class="hashtag-raw">#2nd</span><br>
nn.Conv2d(400,400,5,padding=2),<br>
nn.ReLU(),<br>
nn.MaxPool2d(3),<br>
<span class="hashtag-raw">#3rd</span><br>
nn.Conv2d(400,400,3,padding=1),<br>
nn.ReLU(),<br>
nn.MaxPool2d(2),<br>
<span class="hashtag-raw">#4th</span><br>
nn.Conv2d(400,200,7),<br>
nn.ReLU(),<br>
nn.MaxPool2d(2),<br>
<span class="hashtag-raw">#5th</span><br>
nn.Conv2d(200,100,5,padding=2),<br>
nn.ReLU(),<br>
nn.MaxPool2d(5)<br>
)</p>
<p>def forward(self, x):<br>
return self.step1(x)</p>
<p>def train():<br>
lr = 0.3<br>
num_epochs = 1</p>
<p>model = CNN()<br>
loss_fn = nn.CrossEntropyLoss()<br>
optim = torch.optim.SGD(model.parameters(), lr=lr)</p>
<p>for epoch in range(num_epochs):<br>
train_loader = setLoader(“/train”, 2, True)<br>
for batch, (X,y) in enumerate(train_loader):<br>
optim.zero_grad()<br>
y_hat = model(X)<br>
print(y_hat.shape)<br>
print(‘-’)<br>
print(y)<br>
loss =  loss_fn(y_hat,y)<br>
print(f’Batch: {batch}, Loss: {loss}')<br>
loss.backward()<br>
optim.step()</p>
<p>train()</p>

ptrblck: <p>The common approach would be the flatten the conv activations and pass it to a linear layer (or a few of them with non-linearilies between them) which would act as a classifier. Currently these layers are missing and your model would output logits for a spatial output, which could be used in e.g. a segmentation use case.</p>

skyfail_ufg: <p>When I flatten with start_dim =1 I get shape [2 900], which should be right, since it’s 2 mini-batch, but now, which Linear Layer I pass my model to, I tried to softmax, even if Cross Entropy Loss already have it, but since it doesn’t have any output layer, I thought i wasn’t going to work, and indeed all my losses were increasing by mini-batch.</p>
<p>Can you elaborate more? I’m following the Dive into Deep Learning Book, currently at chapter 7.</p>
<p>Also, do I need to init my weights, on when I define my model using nn.Module inheritance it already do the Xavier Initialization?</p>
<p>Edit:<br>
Tried to add nn.LazyLinear(100) and torch.flatten(start_dim=1), but my losses keep increasing! I’m not sure what I’m doing wrong.</p>
<h2><a name="torchsize2-100-1" class="anchor" href="#torchsize2-100-1"></a>torch.Size([2, 100])</h2>
<h2><a name="tensor21-91-batch-0-loss-4575193881988525-torchsize2-100-2" class="anchor" href="#tensor21-91-batch-0-loss-4575193881988525-torchsize2-100-2"></a>tensor([21, 91])<br>
Batch: 0, Loss: 4.575193881988525<br>
torch.Size([2, 100])</h2>
<h2><a name="tensor-7-32-batch-1-loss-8151891708374023-torchsize2-100-3" class="anchor" href="#tensor-7-32-batch-1-loss-8151891708374023-torchsize2-100-3"></a>tensor([ 7, 32])<br>
Batch: 1, Loss: 8.151891708374023<br>
torch.Size([2, 100])</h2>
<p>tensor([33, 78])<br>
Batch: 2, Loss: 12.540384292602539</p>