Hi all,
I have been designing a Hyperspectral image classifier with 150 colour bands. The network breaks on the loss function with this error message
only batches of spatial targets supported (non-empty 3D tensors) but got targets of size: : [4]
What i can surmise is that the targets of size 4 comes from my dataloader batch size being 4. But i can’t understand what i have done wrong to have this issue. Shouldn’t it be this way when you set a batch size.
My train function looks like
def train(self, net,
optimizer,
loss,
data_loader,
epoch = x["HYPERPARAMETERS"]["epoch"],
scheduler=None,
display_iter=100, display=None,
val_loader=None):
"""
Training loop to optimize a network for several epochs and a specified loss
Args:
net: a PyTorch model
optimizer: a PyTorch optimizer
data_loader: a PyTorch dataset loader
epoch: int specifying the number of training epochs
criterion: a PyTorch-compatible loss function, e.g. nn.CrossEntropyLoss
device (optional): torch device to use (defaults to CPU)
display_iter (optional): number of iterations before refreshing the
display (False/None to switch off).
scheduler (optional): PyTorch scheduler
val_loader (optional): validation dataset
supervision (optional): 'full' or 'semi'
"""
if criterion is None:
raise Exception("Missing criterion. You must specify a loss function.")
net.to(self.device)
save_epoch = epoch // 20 if epoch > 20 else 1
losses = np.zeros(1000000)
mean_losses = np.zeros(100000000)
iter_ = 1
loss_win, val_win = None, None
val_accuracies = []
for e in tqdm(range(1, epoch + 1), desc="Training the network"):
# Set the network to training mode
net.train()
avg_loss = 0.
# Run the training loop for one epoch
for batch_idx, (data, target) in enumerate(data_loader):
# Load the data into the GPU if required
data = data.permute(0,3,1,2) #reshape f
target = target
data, target = data.to(self.device), target.to(self.device)
optimizer.zero_grad()
output = net(data)
loss = loss(output, target)
loss.backward()
optimizer.step()
avg_loss += loss.item()
losses[iter_] = loss.item()
mean_losses[iter_] = np.mean(losses[max(0, iter_ - 100):iter_ + 1])
if display_iter and iter_ % display_iter == 0:
string = 'Train (epoch {}/{}) [{}/{} ({:.0f}%)]\tLoss: {:.6f}'
string = string.format(
e, epoch, batch_idx *
len(data), len(data) * len(data_loader),
100. * batch_idx / len(data_loader), mean_losses[iter_])
update = None if loss_win is None else 'append'
loss_win = display.line(
X=np.arange(iter_ - display_iter, iter_),
Y=mean_losses[iter_ - display_iter:iter_],
win=loss_win,
update=update,
opts={'title': "Training loss",
'xlabel': "Iterations",
'ylabel': "Loss"
}
)
tqdm.write(string)
if len(val_accuracies) > 0:
val_win = display.line(Y=np.array(val_accuracies),
X=np.arange(len(val_accuracies)),
win=val_win,
opts={'title': "Validation accuracy",
'xlabel': "Epochs",
'ylabel': "Accuracy"
})
iter_ += 1
del(data, target, loss, output)