CBOW Model › CBOW Gradient Derivation
Language AI HandbookAll chapters CBOW Model › CBOW Gradient DerivationOne section · Sections in this chapter6 / 15 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
To train CBOW with gradient descent, we need to compute how the loss changes with respect to every parameter. The parameters are the embedding matrix and the output matrix . Understanding these gradients is important for implementing the model and for developing intuition about what happens during training and why the averaging operation produces the regularizing effect we described earlier.
Gradient with Respect to the Output Matrix
The loss for one training example is . Expanding this through the softmax, the gradient with respect to the output score (before softmax) is the prediction error:
where:
- : the model's predicted probability for word
- : 1 if is the true center word, 0 otherwise
This is the standard softmax gradient, and it has a beautiful interpretation. The model is right when (error near 0), and wrong when (error near 1). For all non-target words, the error is , meaning the model is penalized for assigning any probability to wrong words. The gradient is zero only when the model assigns probability 1 to the correct word and 0 to all others, an ideal that is never achieved in practice.
This prediction-error form has a deep connection to maximum likelihood estimation. The gradient of the negative log-likelihood with respect to the pre-softmax logits is exactly the difference between the predicted distribution and the one-hot target distribution. This clean form is one reason softmax cross-entropy is the standard objective for multiclass classification.
Since , the gradient with respect to the output column vector is:
In matrix form, the full gradient for is the outer product of the prediction error vector and the hidden representation:
where is the error vector ( is the softmax probability vector and is the one-hot target vector).
The key insight here is that the update to touches every column. Every column is updated, rather than only the target word.s column. Every vocabulary word's output vector is updated at every training step: the target word's column is pushed toward , and every other word's column is pushed slightly away from (because their prediction errors are positive). This global coupling is what makes the vocabulary's output representations mutually competitive: they cannot all be similar to every context average.
Gradient with Respect to the Hidden Representation
To propagate gradients back to the embedding matrix, we first need the gradient with respect to :
where:
- : the output weight matrix of shape
- : the prediction error vector of shape
This is a weighted sum of all the output column vectors, weighted by the prediction errors. Words with large positive errors contribute their output vectors in the direction that increases the score for those words. Words with large negative errors (the true target word with error , which is negative) pull toward their output vectors.
The gradient can be interpreted as "the direction in which the averaged context embedding should move to reduce the loss." If the model currently assigns high probability to the wrong word "dog" and low probability to the correct word "fox," this gradient will point toward the output vector for "fox" and away from the output vector for "dog." Moving in this direction makes "fox" more predictable from the current context.
Gradient with Respect to the Embedding Matrix
Since , and each context word embedding contributes equally to the average, the gradient with respect to each context word's embedding is:
The factor is the derivative of the average with respect to one component. Each context word receives the same gradient signal, scaled by . This is the "bag" property in action: all context words are treated identically, and the gradient for each is the same averaged signal.
This equal sharing of gradients has a regularizing effect. If the model makes an error, the blame is distributed equally across all context words. A single context word cannot receive a large, unstable gradient update because it must share the blame with all its neighbors. This dampening makes CBOW more stable during training than a model that attributes prediction errors to individual context words.
Importantly, the only rows of that receive gradient updates for a given training example are the rows corresponding to the context words present in that example. Words not in the context window receive zero gradient for this example. This sparsity is computationally advantageous: even though the vocabulary may contain 100,000 words, a given training step touches at most rows of (where is the window size), regardless of vocabulary size.
def cbow_backward(
context_words, target_word, h_bar, probs, W, W_prime, word_to_idx
):
"""
CBOW backward pass. Returns parameter gradients.
"""
V = W_prime.shape[1]
target_idx = word_to_idx[target_word]
# Step 1: Prediction error (softmax gradient)
e = probs.copy()
e[target_idx] -= 1.0 # Subtract 1 from the correct word
# Step 2: Gradient for W_prime
dW_prime = np.outer(h_bar, e) # shape: (d, V)
# Step 3: Gradient for hidden representation
dh_bar = W_prime @ e # shape: (d,)
# Step 4: Gradient for embedding matrix (distribute equally to all context words)
dW = np.zeros_like(W)
C = len(context_words)
for word in context_words:
dW[word_to_idx[word]] += dh_bar / C
return dW, dW_prime
def compute_loss(target_word, probs, word_to_idx):
"""Negative log-likelihood loss."""
return -np.log(probs[word_to_idx[target_word]] + 1e-10)
# Compute gradients for our example
dW, dW_prime = cbow_backward(
context, "fox", h_bar, probs, W, W_prime, word_to_idx
)
loss = compute_loss("fox", probs, word_to_idx)CBOW Backward Pass: -------------------------------------------------- Loss (before gradient step): 2.0879 Prediction error vector (e = p - y): the : +0.1255 quick : +0.1249 brown : +0.1244 fox : -0.8761 <<< target jumps : +0.1248 over : +0.1250 lazy : +0.1257 dog : +0.1258 Gradient norms: dW norm: 0.07822 dW_prime norm: 0.06071
The prediction error is largest for "fox" (the target), where the model needs to increase probability the most. The gradients flow back through the output matrix and distribute equally across all context word embeddings. Notice that the target word "fox" has a negative error (the model should increase its probability), while all other words have small positive errors (the model should decrease their probabilities slightly).