# Classification Fine-Tuning

Adapting a language model for label prediction by attaching a classification head and training on labelled examples.

**Rests on:** Pre-Trained Model Adaptation, Two-Class and Multiclass Classifiers

*LLMs and Generative AI · Fine-Tuning*


## Why learn this

This unlocks the ability to make a trained language model answer 'which category?' questions with confidence — spam vs ham, positive vs negative review, which department an email belongs to, whether a transaction looks fraudulent. It is the mechanism behind nearly every 'smart' feature that sorts or flags things. In the path ahead, this is the bridge between a model that only generates text and a model that acts as a decision engine. It also connects directly to your notes on Instruction Tuning (teaching directions vs teaching classification), Catastrophic Forgetting (what you risk when you tune), and LoRA (the efficient way to do it).


## The intuition

A language model, before any fine-tuning, is a machine that predicts the next word. Given 'The movie was', it might continue 'great', 'boring', or 'unexpected'. That is generative — it produces an open-ended continuation. Classification is different: you have a fixed set of possible answers (labels), and you want the model to pick the correct one. For example, given a review, the fixed answers might be 'positive' and 'negative'. You don't want it to generate a sentence; you want it to output 'positive' if the review is good, 'negative' if bad. Fine-tuning for classification is the process of taking that general word-predictor and turning it into a specialised label-picker. You do this by taking the model, attaching a small new part on top (a classification head), and then showing it many examples of inputs together with their correct labels. Over many examples, the model adjusts its internal numbers so that the head at the top produces the right label for each input. The key idea is that the base model already understands language extremely well — it knows that 'amazing' is a positive word, 'terrible' is negative. Fine-tuning just teaches it to use that understanding in a specific way: to compress the whole input into a single choice. The input might be a whole paragraph; the model sums up its understanding into a final vector at the last token, and the head reads that to decide the label.


## An analogy

Think of a seasoned librarian who is brilliant at understanding text but has never been trained to sort books into categories. She can read a synopsis, follow the plot, know the characters. But if you ask her to put each book into a box labelled 'fiction' or 'non-fiction', she has no idea what system to use. Now, you ask her to read 10,000 books along with their correct categories. After a while, she learns what features in a book's synopsis tend to mean it's fiction — invented names, a quest, dialogue — and what features tend to mean non-fiction — a thesis, references to studies. She doesn't lose her reading ability; she simply adds a new skill of labelling. The librarian is the base language model. The new skill of labelling is the classification head. The 10,000 labelled examples are the fine-tuning dataset. After training, you can hand her a book she has never seen, and she will file it correctly with high confidence. Now, where does the analogy break? A real librarian could reason about the label system and transfer it to novel situations immediately; a fine-tuned model can only classify in ways similar to what it saw. Also, a librarian does not change her brain's wiring when she learns to classify — but a model does, by adjusting millions of numbers (weights). And crucially, the librarian reads the whole book; a language model, in practice, only sees a limited window of context (for example, 512 or 1024 tokens). The model does not 'read' the entire input like a human; it mathematically processes the token sequence to produce a summary vector at the end.


## Definition

Classification fine-tuning is the process of taking a pretrained language model, attaching a small classification head on top of the final token's representation, and training the whole thing on labelled examples so that, for a new input, the head outputs the correct label from a fixed set.


## How it connects

You are coming to this with no prior mastery, so this stands alone here. But in your notes you already have 'Fine-Tuning' as a parent concept, and this is the specific case where the task is label prediction rather than text generation. Contrast with Instruction Tuning: there the output is natural language following a direction; here it is a fixed category. Catastrophic Forgetting is your main risk: if you train on too many classification examples, the model may forget how to write fluent text — a danger to keep in mind even while you are learning the mechanics. The efficient way to do this in practice is with LoRA, where only a small set of extra numbers is trained.


## The mathematics

Classification fine-tuning is a method for taking a model that already knows a lot about language and teaching it to sort text into specific categories, such as 'positive' or 'negative'. The process involves two main parts: calculating scores for each category and then adjusting the model's internal numbers (weights) so those scores become more accurate.

First, let us look at how the model calculates a score. The model takes the input text and converts it into a list of numbers called a vector. For this explanation, imagine this final vector has just two numbers: [2.0, -1.0]. To decide which category fits best, the model uses a 'classification head'. This is simply a table of weights. Each row in the table corresponds to one possible category (label). Each column corresponds to one number in the input vector.

To get the raw score for a specific label, you perform a dot product between the weight row and the input vector, then add a small adjustment called a bias. The dot product means you multiply corresponding numbers together and sum the results.

Let us define the variables we will use:
- x represents the input vector numbers. Here, x1 = 2.0 and x2 = -1.0.
- w represents the weights in the table for a specific label. For example, w1 is the weight for the first number in the vector, and w2 is the weight for the second number.
- b represents the bias for that label.
- z represents the raw score for that label.

The formula for the raw score z for any given label is:
z = (w1 * x1) + (w2 * x2) + b

This calculation gives a single number. A higher number means the model thinks this label is more likely. However, these raw scores can be negative or very large, which makes them hard to compare directly as probabilities. We need to convert them into probabilities: numbers between 0 and 1 that add up to 1.

To do this, we use a function called softmax. Softmax does two things:
1. It takes each raw score z and raises the mathematical constant e (approximately 2.718) to the power of that score. This ensures all values are positive. We call these exponentiated values 'exponents'.
   exponent = e raised to the power of z.
2. It divides each exponent by the sum of all exponents for all labels. This normalizes the values so they sum to 1.

Let p be the final probability for a label.
p = (e raised to the power of z) / (the sum of e raised to the power of z for all labels)

Once we have the probabilities, we compare the model's prediction to the correct answer. If the correct label was 'positive', but the model gave it a low probability, the model is wrong. We measure this error using a 'loss' function. For classification, the standard loss is called cross-entropy loss. The formula for the loss when the true label is known is:

Loss = - (the natural logarithm of p_correct)

Here, p_correct is the probability the model assigned to the actually correct label. The natural logarithm is a mathematical function that grows slowly; it turns small probabilities into large negative numbers, and large probabilities (close to 1) into numbers close to 0. Because we put a minus sign in front, the loss becomes a positive number. A high loss means the model was very wrong. A low loss means the model was correct.

Finally, fine-tuning adjusts the weights w and biases b. The goal is to change these numbers so that the loss gets smaller. This is done using an algorithm called gradient descent. In simple terms, gradient descent looks at how much each weight contributed to the error and nudges it in the direction that reduces the error. We repeat this process for many examples in the training data until the loss is minimized.


## A worked example

Let us walk through the arithmetic step-by-step with real numbers.

Setup:
- Input vector x = [2.0, -1.0]. So x1 = 2.0 and x2 = -1.0.
- We have three labels: 'positive', 'negative', and 'neutral'.
- Weights for 'positive': w1 = 1.5, w2 = -0.5. Bias b_pos = 0.2.
- Weights for 'negative': w1 = -2.0, w2 = 1.0. Bias b_neg = -0.1.
- Weights for 'neutral': w1 = 0.5, w2 = 0.5. Bias b_neu = 0.0.

Step 1: Calculate the raw score (z) for 'positive'.
Formula: z_pos = (w1 * x1) + (w2 * x2) + b_pos
Calculation: z_pos = (1.5 * 2.0) + (-0.5 * -1.0) + 0.2
Multiplication: 1.5 * 2.0 = 3.0
Multiplication: -0.5 * -1.0 = 0.5
Addition: 3.0 + 0.5 + 0.2 = 3.7
Result: z_pos = 3.7

Step 2: Calculate the raw score (z) for 'negative'.
Formula: z_neg = (w1 * x1) + (w2 * x2) + b_neg
Calculation: z_neg = (-2.0 * 2.0) + (1.0 * -1.0) + (-0.1)
Multiplication: -2.0 * 2.0 = -4.0
Multiplication: 1.0 * -1.0 = -1.0
Addition: -4.0 + (-1.0) + (-0.1) = -5.1
Result: z_neg = -5.1

Step 3: Calculate the raw score (z) for 'neutral'.
Formula: z_neu = (w1 * x1) + (w2 * x2) + b_neu
Calculation: z_neu = (0.5 * 2.0) + (0.5 * -1.0) + 0.0
Multiplication: 0.5 * 2.0 = 1.0
Multiplication: 0.5 * -1.0 = -0.5
Addition: 1.0 + (-0.5) + 0.0 = 0.5
Result: z_neu = 0.5

Step 4: Convert raw scores to exponents using e^z.
We use the constant e ≈ 2.71828.
Exponent for positive: e^3.7 ≈ 40.447
Exponent for negative: e^-5.1 ≈ 0.006
Exponent for neutral: e^0.5 ≈ 1.649

Step 5: Sum the exponents.
Sum = 40.447 + 0.006 + 1.649 = 42.102

Step 6: Calculate probabilities (p) by dividing each exponent by the sum.
Probability for positive (p_pos) = 40.447 / 42.102 ≈ 0.9607
Probability for negative (p_neg) = 0.006 / 42.102 ≈ 0.00014
Probability for neutral (p_neu) = 1.649 / 42.102 ≈ 0.0392

Check: 0.9607 + 0.00014 + 0.0392 ≈ 1.00004 (rounding errors account for the slight excess).

Step 7: Calculate the loss if the true label was 'positive'.
Formula: Loss = - ln(p_correct)
Here, p_correct = p_pos = 0.9607.
Natural logarithm of 0.9607 ≈ -0.0401
Loss = - (-0.0401) = 0.0401

Interpretation:
The model predicted 'positive' with approximately 96% confidence. Since the true label was indeed 'positive', the loss is very low (0.04). If the true label had been 'negative', p_correct would have been 0.00014, and the loss would have been -ln(0.00014) ≈ 8.86, which is a high error signal. The fine-tuning process would then adjust the weights w and biases b to increase the score for 'negative' and decrease the score for 'positive' in future similar inputs.


## From scratch, in Python

```python
import math

# Our 'language model' produces a final token vector for an input.
# In reality this would be the output of the base transformer.
# Here, we make one up for illustration.
final_token_vector = [2.0, -1.0]

# Classification head: a list of (weights, bias) for each label.
# Labels: index 0 = positive, 1 = negative, 2 = neutral
head = [
    ([1.5, -0.5], 0.2),  # positive
    ([-2.0, 1.0], -0.1), # negative
    ([0.5, 0.5], 0.0),    # neutral
]

# Step 1: Compute raw scores (dot product + bias) for each label.
def dot_product(a, b):
    total = 0.0
    for i in range(len(a)):
        total += a[i] * b[i]
    return total

raw_scores = []
for weights, bias in head:
    score = dot_product(weights, final_token_vector) + bias
    raw_scores.append(score)

print("Raw scores:", raw_scores)

# Step 2: Apply softmax to get probabilities.
exp_scores = [math.exp(s) for s in raw_scores]
sum_exp = sum(exp_scores)
probabilities = [e / sum_exp for e in exp_scores]

print("Probabilities:", probabilities)

# Step 3: The predicted label is the one with the highest probability.
predicted_index = probabilities.index(max(probabilities))
labels = ["positive", "negative", "neutral"]
print("Predicted label:", labels[predicted_index])
```


## The same thing, with a framework

In PyTorch, the same thing is done with a `nn.Linear` layer on top of the base model. The base model, say a `DistilBertForSequenceClassification`, already includes the head. You would do:
```python
from transformers import AutoModelForSequenceClassification, AutoTokenizer
model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased", num_labels=3)
# The model takes input_ids and returns logits, which you pass to loss function with labels.
# This is a shortcut for the arithmetic you just did manually.
```
The advantage: the library does everything we just wrote in three lines, including the softmax and the loss calculation.


## What the code does

The code starts by taking the final token vector — in practice this is what the base model outputs after processing the whole input. The classification head is a list of tuples, each containing a set of weights and a bias for one label. The function `dot_product` performs the multiply-and-add operation you learned manually: multiply every pair, sum them all. For each label, we compute a raw score. Next, we exponentiate each score using `math.exp` — that makes all scores positive — and then divide by their sum to get probabilities that add to 1. Finally, we pick the label with the highest probability. The PyTorch version wraps all of this behind a familiar API: loading a pretrained model with `num_labels=3` automatically adds a linear head; when you feed it tokenised input and labels, it computes the softmax cross-entropy loss internally. Under the hood, it is doing exactly the same multiply-add and exponentiation we did by hand.


## Common misconceptions

**Fine-tuning makes the model smarter** — If I fine-tune a model, it learns new facts and becomes generally more intelligent.

Fine-tuning reshapes its behaviour for a narrow task; it does not add knowledge. The base model's world knowledge is frozen; the head learns a mapping from the model's existing understanding to labels. It will not learn facts it didn't already know; it will just learn to label things using what it already knows. In fact: Fine-tuning repurposes existing language understanding for a specific classification decision. It doesn't add new knowledge; it adds a new skill.

**The head is the only part that matters** — I can just train the classification head and ignore the base model — the head does all the work.

The head is only a simple linear mapping. The power comes from the base model's rich representations that the head reads. Without a good base model, the head has nothing to work with; the base model's representations carry the meaning, and the head just reads the summary. In fact: The head is a thin decision layer. Almost all the intelligence is in the trained base model's representation of the input, which the head interprets.

**Bias in a model means unfairness** — If a model has a bias, it means it is discriminated against a group of people.

In this context, 'bias' is a mathematical constant in each linear operation — it shifts the score up or down regardless of input. It is a technical term, not a social one. Unfairness can arise from training data, but the word 'bias' in the math is neutral. In fact: What this page calls bias is a learned number that shifts a score to help the model make a decision. Unfairness is a separate, serious issue caused by imbalanced or prejudiced training data, but it is not this bias.

**More labels always help** — Adding more label categories will make the model more capable and precise.

Adding more labels makes the classification problem harder: each label needs enough examples, and labels must be distinguishable. With too many labels and few examples per label, the model will struggle and accuracy falls. In fact: Keep the number of labels minimal and ensure each has sufficient training data. If you can solve with a binary classifier, do so. Adding labels increases complexity without guaranteeing performance gain.

**Fine-tuning always improves the model** — Any fine-tuning will make the model better for my task, and I can keep doing it indefinitely.

Fine-tuning can go wrong: if you use too few examples, you overfit; if you use too many or too narrow data, you get catastrophic forgetting — the model loses its original general capabilities. There is a sweet spot; it's not a monotonic improvement. In fact: Fine-tuning is a trade-off. Monitor for overfitting and forgetting. Use techniques like LoRA and mixing in general data to mitigate degradation. It's not automatically better; it's a route to a specialised model that must be managed.


## In short

Classification fine-tuning attaches a small linear head to a language model's final token, trains it on pairs of inputs and labels to output a probability distribution over fixed categories, and adjusts both head and base weights by gradient descent. It is the mechanism behind task-specific label prediction, is cheap relative to full pretraining, and requires careful data preparation — the final token position must align with the label signal. The mathematics is a dot product plus softmax; the code is a linear layer on top of the base model. The risk of catastrophic forgetting is mitigated by adding adapters like LoRA and by mixing general data.


## Where this is used

This concept is the backbone of a huge swath of applied AI. In large language models, any time a model must decide between predefined categories — for example, whether a prompt is a question or a command, or which of 100 intents a user's message falls into — classification fine-tuning is the mechanism. For a model like ChatGPT, parts of its safety system are fine-tuned classifiers that flag toxic content or jailbreak attempts. In small language models that run on phones or embedded devices, classification fine-tuning is a go-to because it is so lightweight: the base model can be small, and the classification head adds only a few thousand parameters, making it feasible to run real-time. For retrieval-augmented generation (RAG), a fine-tuned classifier often decides which documents to retrieve: it might classify a query as 'factual', 'spatial', or 'conversational' to route it to the right index. In agentic systems that plan and act, a classifier can be the component that decides which tool to call next. In everyday applied ML — fraud detection, sentiment analysis, email filtering, medical diagnosis from notes — this is the standard architecture. A developer's workflow is straightforward: they finetune a model like BERT or GPT on a labelled dataset, then integrate the model against a REST endpoint. A typical failure: if you don't freeze the base or use LoRA, catastrophic forgetting can destroy the model's general language understanding. Also, a developer must ensure the final token's position actually carries the signal — this is why the input is formatted with a special token at the end (e.g., [CLS] in BERT). Done badly — with label imbalance or too few examples — the model will predict the majority class every time, which is worse than a simple word-count heuristic.


---

Read this on the web: https://basavapurushottam.com/learn-ai/classification-fine-tuning
