Concepts / Understanding Logits and Class Scores

Understanding Logits and Class Scores

Argmax on raw logits is a direct route to class labels. Softmax can be added for interpretability when you want probabilities, but it does not change which position wins.

  • Programming

Why a Classifier Needs a Single Label

A classifier rarely answers with a class name. For each input it produces a row of numbers, one number for each possible class. Each number describes how strongly the model leans toward that class. A row might say that the first class is the most likely, but before anyone can count how many predictions were right, that row has to be turned into one decision. This article follows the step that makes that decision: picking the position of the largest value in each row.

What do you think happens?

Given a row of three scores such as [2.0, 0.5, -1.0], which position would a function that picks the largest value report?

  • Position 0

  • Position 1

  • Position 2

  • The value 2.0 itself

Reveal answer
Answer:

Position 0, because 2.0 is the largest value and it sits at index 0.

Argmax returns the position (index) of the largest value, not the value itself. Positions start counting at 0, so the first entry is position 0.

Reading One Row at a Time

The function torch.argmax with dim=1 returns the index of the highest value in each row. Each row of scores becomes a single integer, and that integer is the class label for that row. The dim argument decides the direction of the search. With dim=1 the function scans each row from left to right and reports where its largest value sits.

python
Output (expected)
tensor([0, 1, 1])
Notes on the code
  • logits has three rows (samples) and three columns (classes)
  • dim=1 tells argmax to scan across each row
  • The result has one integer per row, so it has three entries

Read the output row by row. Row 0 has its largest score, 2.0, at position 0, so its label is 0. Row 1 has its largest score, 3.0, at position 1, so its label is 1. Row 2 has its largest score, 1.5, at position 1, so its label is 1. The third row shows that two different samples can share the same label, which is normal for a classifier.

2.0index 0label 0argmax result0.5index 1-1.0index 2largest value wins
Which position in row 0 wins, and how does that position become the class label for that row?
Worked example

Finding the label for row 1

Row 1 of logits is [0.1, 3.0, 0.2]. What class label does argmax with dim=1 return for this row?

  1. 1
    List the scores

    The row holds three scores: 0.1 at position 0, 3.0 at position 1, and 0.2 at position 2.

  2. 2
    Find the largest value

    The largest value is 3.0.

  3. 3
    Report its position

    3.0 sits at position 1, so argmax returns 1 for this row.

Result

The class label for row 1 is 1.

Choosing the Axis with dim

Changing dim from 1 to 0 changes the question entirely. With dim=0 the function scans down each column instead of across each row, and it returns, for every column, the row position of its largest value. That second result answers a different question. It does not give one label per sample, so using the wrong dimension is one of the most common ways to get label predictions that look plausible but mean something else.

python
Output (expected)
tensor([0, 1, 2])
Notes on the code
  • The same logits tensor is used, but the scan now runs down columns
  • The output has three entries, one per column, not one per sample
  • These numbers are row positions inside each column, so they are not class labels for the samples

Skipping Softmax for Labels

The same argmax operation applies to probabilities and to the raw outputs of the network. Computing softmax first and then calling argmax is a valid path. It is not required, however, because the position of the largest value is the same whether you look at the logits or at the probabilities computed from them. Softmax changes the numbers, but it keeps their order within a row, so the winning position does not move.

python
Output (expected)
tensor([0, 1, 1])
tensor([0, 1, 1])
Notes on the code
  • probs contains values between 0 and 1 that sum to 1 within each row
  • argmax on the probabilities and argmax on the logits give the same labels
  • Softmax is therefore optional when the goal is only the predicted label
logits row 10.1, 3.0, 0.2probabilities row 1softmax of the logitsargmax result 1largest logit at position 1argmax result 1largest probability atposition 1argmax dim=1argmax dim=1
If softmax changes the values but keeps their order, why does the largest logit still point to the same class?
Key point

Argmax on raw logits is a direct route to class labels. Softmax can be added for interpretability when you want probabilities, but it does not change which position wins.

Matching Predictions to True Labels

Once you have predicted labels, the next question is whether they match the true labels. For a small set you could compare the two tensors by eye. The equality operator makes this exact. The == operator compares two tensors element by element and returns a tensor of booleans, one for each position. True means the prediction at that position matched the true label.

python
Output (expected)
tensor([ True,  True, False])
tensor(2)
Notes on the code
  • predicted is tensor([0, 1, 1]) and true_labels is tensor([0, 1, 0])
  • The third position is False because 1 does not equal 0
  • torch.sum counts the True entries, giving 2
predicted labelstensor([0, 1, 1])== element-wiseone boolean per positionmatchesTrue, True, Falsetorch.sumcounts the True entries2 correctnumber of matchestrue labelstensor([0, 1, 0])left sideright sideboolean tensorTrue entriestotal
How does an element-wise equality check turn a list of predicted and true labels into a count of correct predictions?

From Count to Accuracy

The count of correct predictions becomes accuracy by dividing it by the total number of examples and multiplying by 100 to express the result as a percentage. The rule is the same for any dataset.

Rule

Worked example

Accuracy for the small batch

The comparison produced two True values out of three examples. What is the accuracy?

  1. 1
    Count correct predictions

    torch.sum returned 2, so there are 2 correct predictions.

  2. 2
    Count total examples

    There are 3 entries in the true labels, so there are 3 examples.

  3. 3
    Divide

    $2 / 3$ is about 0.6667.

  4. 4
    Convert to a percentage

    Multiply by 100 to get about 66.67 percent.

Result

The accuracy is about 66.67 percent.

The source's own training set has five examples, and all five predictions are correct. Five correct out of five gives an accuracy of 100 percent. If a comparison had produced three matches out of four positions, the accuracy would be three quarters, or 75 percent.

Tracing a Surprising Accuracy

When an accuracy number surprises you, the mistake almost always sits in one of three places: the dimension passed to argmax, the tensor passed into argmax, or the true labels it is compared against. Work through the chain in that order, because each step depends on the one before it.

logitscheck the tensor passed inargmax dim=1check the dimensionpredicted labelsone integer per example== true labelslength matches examplestorch.sum countread only after the checksaccuracycount divided by total1st check2nd check3rd checkthen countthen divide
Where in the chain from logits to labels to comparison to count to accuracy could a wrong result have entered?
  • Common mistake

    Using dim=0 when you want one label per sample

    What it looks like

    torch.argmax(logits, dim=0) returns tensor([0, 1, 2]) for the logits above, which has three entries but is not one label per row.

    Why it fails

    dim=0 scans down columns, so it reports row positions inside each column.

    Do this instead

    Use dim=1 when each row is one sample and each column is one class.

  • Common mistake

    Reading the count before checking the predicted labels

    Why it fails

    A wrong count is usually a symptom of a wrong label tensor upstream, so the count alone cannot show where the error started.

    Do this instead

    Print the predicted labels first and confirm there is exactly one integer per example. Then print the comparison and confirm its length matches the number of examples.

  • Common mistake

    Thinking softmax is required before argmax

    Why it fails

    Softmax keeps the order of values within a row, so the position of the largest value does not change.

    Do this instead

    Apply argmax directly to the logits when you only need class labels.

Practice on a New Batch

MEDIUM

Given logits = torch.tensor([[0.2, 1.8, -0.5], [2.4, 0.1, 0.3], [-1.0, 0.7, 0.9]]) and true_labels = torch.tensor([1, 2, 1]), predict the predicted labels with argmax dim=1, then determine how many predictions match and what the accuracy is as a percentage.

Hints
  • Find the largest value in each row and note its position. Row 0's largest is 1.8 at position 1.
  • Compare the three predicted labels with the three true labels position by position, then count the True entries.
  • Divide the count by 3 and multiply by 100.

Key Takeaways

  • torch.argmax with dim=1 returns the index of the highest value in each row, turning a row of class scores into one class label.
  • Argmax can be applied directly to logits; softmax is not needed to get labels because it preserves the order of values within a row.
  • The == operator compares predicted and true labels element by element, and torch.sum counts the True entries.
  • Accuracy equals the number of correct predictions divided by the total number of examples, expressed as a percentage.
  • When accuracy looks wrong, check the dim argument, then the predicted labels, then the comparison, before trusting the count.

Related concepts

More concepts starting with U