nn.CrossEntropyLoss() and incongruent train and test labels

username: localh
cooked: <p>I am wondering how to deal with incongruent training and test labels with nn.CrossEntropyLoss.</p>
<p>For an ultra minimal example say we have:</p>
<pre><code class="lang-auto">logits = torch.tensor([-0.3080, -0.2961]).reshape(1, 2)
y = torch.tensor([0])
y_test = torch.tensor([2])
F.cross_entropy(logits, y)
F.cross_entropy(logits, y_test)  # target is out of bounds
</code></pre>
<p>How can I deal with labels found in the test data that never occurred in the training?</p>

username: KFrank
cooked: <p>Hi Andrew!</p>
<aside class="quote no-group" data-username="localh" data-post="1" data-topic="102590" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/localh/48/18991_2.png" class="avatar"> localh:</div>
<blockquote>
<p>How can I deal with labels found in the test data that never occurred in the training?</p>
</blockquote>
</aside>
<p>The short answer:</p>
<p>Make sure that the classification model you build has outputs for all<br>
classes in your classification problem.</p>
<p>An important note:</p>
<p>If your test set includes classes (“test labels”) that do not occur in<br>
your training set (“training labels”), it will not be possible for your<br>
model to learn to predict those missing classes correctly.</p>
<p>Some further explanation:</p>
<p><code>CrossEntropyLoss</code> expects an <code>input</code> (the output of your model)<br>
that has shape <code>[nBatch, nClass]</code>, and a <code>target</code> (the labels) that<br>
has shape <code>[nBatch]</code> and whose values are integer class labels that<br>
run from <code>[0, nClass - 1]</code> (inclusive).</p>
<p>In your example your <code>logits</code> (the <code>input</code>) has shape <code>[1, 2]</code>.<br>
Therefore this example mimics a two-class classification problem,<br>
so your <code>y_test</code> (the test <code>target</code>) values should be <code>0</code> or <code>1</code>.  The value<br>
<code>2</code> is “out of bounds,” and would be the label for the third class in a<br>
three-class (or more) classification problem.  (Your <code>y_test</code> has shape<br>
<code>[1]</code>, which is correct.)</p>
<p>To reiterate, if you a performing an <code>nClass</code> classification problem,<br>
you must build a model that has <code>nClass</code> outputs, and your <code>target</code><br>
(label) values must run from <code>0</code> to <code>nClass - 1</code>.  Your model can’t<br>
determine from the data, on the fly, how many classes you have.<br>
That has to be baked into your model (and consistent with the<br>
<code>target</code> values).</p>
<p>Best.</p>
<p>K. Frank</p>

username: localh
cooked: <aside class="quote no-group" data-username="localh" data-post="1" data-topic="102590">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/localh/48/18991_2.png" class="avatar"> localh:</div>
<blockquote>
<pre><code class="lang-auto">logits = torch.tensor([-0.3080, -0.2961]).reshape(1, 2)
y = torch.tensor([0])
y_test = torch.tensor([2])
F.cross_entropy(logits, y)
F.cross_entropy(logits, y_test)  # target is out of bounds
</code></pre>
</blockquote>
</aside>
<p>Ah I see – the question seems silly now. I should have just made a tweak and played around a bit more. Thank you for your time and help!</p>