CBOW Model › CBOW Gradient Derivation

Michael BrenndoerferApril 3, 20256 min read
Language AI HandbookAll chapters
Part 4 of 67Word Embeddings
Chapter 20CBOW Model › CBOW Gradient Derivation
Reading section 6 of 15 · CBOW Gradient Derivation · 6 minSection 6 of 15 · 6 min

Book contents

Section 6 of 15 · 6 min read

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 W\mathbf{W} and the output matrix W′\mathbf{W}'. 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 W′\mathbf{W}'

The loss for one training example is L=−log⁡P(wt∣C)L = -\log P(w_t \mid C). Expanding this through the softmax, the gradient with respect to the output score zwz_w (before softmax) is the prediction error:

∂L∂zw=P(w∣C)−1[w=wt]\frac{\partial L}{\partial z_w} = P(w \mid C) - \mathbf{1}[w = w_t]

where:

  • P(w∣C)P(w \mid C): the model's predicted probability for word ww
  • 1[w=wt]\mathbf{1}[w = w_t]: 1 if ww is the true center word, 0 otherwise

This is the standard softmax gradient, and it has a beautiful interpretation. The model is right when P(wt∣C)≈1P(w_t \mid C) \approx 1 (error near 0), and wrong when P(wt∣C)≈0P(w_t \mid C) \approx 0 (error near 1). For all non-target words, the error is P(w∣C)−0=P(w∣C)P(w \mid C) - 0 = P(w \mid C), 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 zw=ww′⊤hˉz_w = \mathbf{w}_w'^{\top} \bar{\mathbf{h}}, the gradient with respect to the output column vector ww′\mathbf{w}_w' is:

∂L∂ww′=(P(w∣C)−1[w=wt])hˉ\frac{\partial L}{\partial \mathbf{w}_w'} = \left(P(w \mid C) - \mathbf{1}[w = w_t]\right) \bar{\mathbf{h}}

In matrix form, the full gradient for W′\mathbf{W}' is the outer product of the prediction error vector and the hidden representation:

∂L∂W′=hˉ⋅e⊤\frac{\partial L}{\partial \mathbf{W}'} = \bar{\mathbf{h}} \cdot \mathbf{e}^{\top}

where e=p−y\mathbf{e} = \mathbf{p} - \mathbf{y} is the error vector (p\mathbf{p} is the softmax probability vector and y\mathbf{y} is the one-hot target vector).

The key insight here is that the update to W′\mathbf{W}' 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 hˉ\bar{\mathbf{h}}, and every other word's column is pushed slightly away from hˉ\bar{\mathbf{h}} (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 hˉ\bar{\mathbf{h}}:

∂L∂hˉ=W′e\frac{\partial L}{\partial \bar{\mathbf{h}}} = \mathbf{W}' \mathbf{e}

where:

  • W′\mathbf{W}': the output weight matrix of shape d×Vd \times V
  • e\mathbf{e}: the prediction error vector of shape V×1V \times 1

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 P(wt)−1P(w_t) - 1, which is negative) pull hˉ\bar{\mathbf{h}} toward their output vectors.

The gradient ∂L∂hˉ\frac{\partial L}{\partial \bar{\mathbf{h}}} 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 hˉ\bar{\mathbf{h}} in this direction makes "fox" more predictable from the current context.

Gradient with Respect to the Embedding Matrix W\mathbf{W}

Since hˉ=1C∑i=1Cwci\bar{\mathbf{h}} = \frac{1}{C} \sum_{i=1}^{C} \mathbf{w}_{c_i}, and each context word embedding wci\mathbf{w}_{c_i} contributes equally to the average, the gradient with respect to each context word's embedding is:

∂L∂wci=1C⋅∂L∂hˉ\frac{\partial L}{\partial \mathbf{w}_{c_i}} = \frac{1}{C} \cdot \frac{\partial L}{\partial \bar{\mathbf{h}}}

The 1C\frac{1}{C} factor is the derivative of the average with respect to one component. Each context word receives the same gradient signal, scaled by 1C\frac{1}{C}. 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 W\mathbf{W} 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 2m2m rows of W\mathbf{W} (where mm is the window size), regardless of vocabulary size.

In[13]:
Code
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)
Out[14]:
Console
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).