Hello Arthur -



 Arthur_Conmy:

    print(outputs.shape,labels.shape)
    loss = F.cross_entropy(outputs, labels)

which prints
torch.Size([128, 10]) torch.Size([128])

after changing the loss function to MSELoss:
    print(outputs.shape, labels.shape)
    loss_fn = nn.MSELoss()

I get the following output
torch.Size([10, 10]) torch.Size([10])
Loss: 42.0984992980957
...
UserWarning: Using a target size (torch.Size([10])) that is different to the input size (torch.Size([10, 10])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.



cross_entropy() expects outputs of shape [nBatch, nClass] and
labels of shape [nBatch] (no nClass – each single label value is
an integer class label that runs from 0 to nClass - 1).
MSELoss expects outputs of shape [nBatch, nValues] and labels
(which really shouldn’t be called “labels” for MSELoss) also of shape
[nBatch, nValues].
I’m not really sure what the tutorial is looking for here, because if
cross_entropy() makes sense for a model, MSELoss is unlikely
to also make sense.
Having said that, you could either one-hot your integer class labels
to get labels of shape [nBatch, nClass] to match the output of
your model, or you could change your model to output a single
value (instead of nClass values) so that its output for a batch will
be of shape [nBatch] and thus match the shape of your labels.


Exra: in addition, why doesn’t writing loss = nn.MSELoss(outputs, labels) rather than the loss_fn workaround I’ve been using work?


torch.nn.MSELoss is a class, while torch.nn.functional.mse_loss()
is a function.  Thus loss = nn.MSELoss(outputs, labels) is
incorrectly calling the constructor of the MSELoss class with the
wrong arguments.
Instead of:
loss = nn.MSELoss (outputs, labels)   # wrong

you should either write:
loss = nn.MSELoss() (outputs, labels)

(note the extra pair of parentheses), or:
loss = F.mse_loss (outputs, labels)

Good luck.
K. Frank