Stage 4 of 6v1 · 21bad6ff
Gradient Descent Parameter Update
Apply the optimization update rule w = w - α * ∇w and b = b - α * ∇b to take a step in the direction of steepest descent.
First Principles: Walking Down a Mountain in the Fog
How do a collection of raw numbers actually "learn"? It all comes down to an intuitive geometric insight: gradient descentAn optimization algorithm for finding a local minimum of a differentiable functionView official documentation.
Imagine you are standing on a steep mountainside surrounded by thick fog, with zero visibility beyond your feet. Your mission is to reach the valley floor where elevation (the loss or error) is lowest:
- You cannot see the global valley from where you stand, but you can feel the slope of the ground right under your boots.
- That slope is the derivative or gradient (): it points in the direction of steepest ascent (uphill).
- To walk downhill towards the minimum error, you must take a step in the exact opposite direction (with a negative sign: ).
- The size of the step you take is determined by the learning rate ().
High loss position (error)
\
\ <-- Steps taken opposite to gradient (-α·∇)
\
\____ Valley floor: Minimum loss (optimal learning)
The Learning Rate () Dilemma
- Too small (): Steps are overly conservative; the network requires millions of iterations to learn simple patterns.
- Too large (): You risk leaping entirely over the valley floor, landing on an even steeper opposing cliff (causing divergence).
- Balanced (): The parameters steadily converge toward the minimum loss.
The Parameter Update Rule
Every weight and bias is updated by subtracting the product of the learning rate and its respective gradient:
Your Objective in this Stage
When standard input receives "op": "gradient-step", process:
{
"op": "gradient-step",
"learning_rate": 0.1,
"weights": [0.5, -0.2],
"bias": 0.1,
"grad_weights": [0.2, -0.4],
"grad_bias": 0.05
}
Step-by-Step Walkthrough
- Update the first weight:
- Update the second weight:
- Update the bias:
- Final JSON result:
{"bias":0.095,"weights":[0.48,-0.16]}.
Practical Implementation and Code Advice
- Python Pattern:
if len(weights) != len(grad_weights) or lr <= 0: raise ValueError("Invalid gradient parameters") new_weights = [round_value(w - lr * gw) for w, gw in zip(weights, grad_weights)] new_bias = round_value(bias - lr * grad_bias) # Insert 'bias' first to maintain alphabetical order: return { "bias": new_bias, "weights": new_weights } - TypeScript Pattern:
if (weights.length !== grad_weights.length || lr <= 0) { throw new Error("Invalid gradient parameters"); } const newWeights = weights.map((w, i) => roundValue(w - lr * grad_weights[i]), ); const newBias = roundValue(bias - lr * grad_bias); // Insert 'bias' before 'weights' to ensure alphabetical key order: return { bias: newBias, weights: newWeights, };
Validation and Output Rules
- If
learning_rate <= 0, printerrortostderrand exit with code1. - If
weightsandgrad_weightsdiffer in length, printerrortostderrand exit with code1. - Round each updated number to 4 decimal places with
round_value/roundValue. If integer (including0), serialize as an integer. - Key Ordering: Output keys in strict alphabetical order (
"bias"followed by"weights"):{ "bias": 0.095, "weights": [0.48, -0.16] }