{
  "id": "ml-basics",
  "module": "math-ml",
  "level": 1,
  "minutes": 18,
  "audiences": [
    "beginner",
    "developer",
    "researcher"
  ],
  "software": [
    "uv"
  ],
  "text": {
    "en": {
      "title": "How Machines Learn: Loss Functions and Gradient Descent Explained",
      "description": "The core loop behind all modern AI training — model, loss function, gradient and update — explained with one tiny worked example and a few lines of Python.",
      "updated": "2026-10-10",
      "takeaways": [
        "Machine learning means adjusting a model's parameters so that a loss (a number measuring how wrong it is) goes down on example data.",
        "The gradient tells you which direction each parameter should move to reduce the loss; gradient descent takes many small steps in that direction.",
        "LLM training is the same loop at enormous scale: the loss is cross-entropy on the next token, and there are billions of parameters.",
        "Doing well on training data is not the goal; doing well on new data (generalisation) is."
      ],
      "faq": [
        {
          "q": "What is a loss function in simple terms?",
          "a": "A loss function is a formula that turns the model's mistakes into a single number. Zero means perfect predictions; bigger means worse. Training is the search for parameters that make this number small."
        },
        {
          "q": "What is the learning rate?",
          "a": "The learning rate is the size of each step in gradient descent. Too large and training overshoots and diverges; too small and it takes forever. Modern training changes it over time (warm-up, then decay)."
        },
        {
          "q": "Why is it called stochastic gradient descent?",
          "a": "Because each step estimates the gradient from a small random batch of examples instead of the whole dataset. It is noisier but far cheaper, and the noise often helps."
        }
      ],
      "sources": [
        {
          "title": "Goodfellow, Bengio & Courville, Deep Learning (MIT Press, 2016), chapters 4–5",
          "url": "https://www.deeplearningbook.org/"
        },
        {
          "title": "Google, Machine Learning Crash Course",
          "url": "https://developers.google.com/machine-learning/crash-course"
        },
        {
          "title": "Kingma & Ba (2014), Adam: A Method for Stochastic Optimization",
          "url": "https://arxiv.org/abs/1412.6980"
        },
        {
          "title": "Ruder (2016), An overview of gradient descent optimization algorithms",
          "url": "https://arxiv.org/abs/1609.04747"
        },
        {
          "title": "Stanford CS229 Machine Learning lecture notes",
          "url": "https://cs229.stanford.edu/main_notes.pdf"
        }
      ],
      "url": "https://aimap.page/en/learn/math-ml/ml-basics/",
      "markdown": "## Learning = making a number go down\n\nTraditional software is written as rules: *if this, then that*. Machine learning flips it around: you supply **examples** and a **model with adjustable numbers (parameters)**, and an algorithm adjusts the numbers until the model's outputs match the examples well.\n\nTo make \"match well\" precise you need a **loss function**: a formula that measures how wrong the model is on the examples. Training is simply the search for parameter values that make the loss small. Every AI system you have heard of — image classifiers, recommendation engines, ChatGPT — is trained this way.\n\n## A tiny worked example\n\nSuppose you want to predict a flat's price from its size. Your model is a straight line:\n\n`price = w × size + b`\n\n`w` and `b` are the two parameters. You have three examples: 50 m² → 100, 80 m² → 160, 100 m² → 200 (in thousands). A common loss for numbers is **mean squared error**: average of (prediction − truth)².\n\nStart with random guesses, say `w = 1, b = 0`. Predictions are 50, 80, 100 — far too low — so the loss is large. Now ask: *if I increase `w` a little, does the loss go up or down?* That rate of change is the **derivative** of the loss with respect to `w`; collected for all parameters it is called the **gradient**. Here it says \"increase `w`\". Take a small step in that direction, recompute, repeat. After enough steps you reach `w ≈ 2, b ≈ 0`, which fits the data exactly.\n\n```mermaid\nflowchart LR\n  A[\"Parameters (random at first)\"] --> B[\"Predict on a batch of examples\"]\n  B --> C[\"Loss: how wrong?\"]\n  C --> D[\"Gradient: which way reduces loss?\"]\n  D --> E[\"Update: step a little downhill\"]\n  E --> A\n```\n\nThe same loop in a few lines of Python (NumPy):\n\n```python\nimport numpy as np\nx = np.array([50, 80, 100.]); y = np.array([100, 160, 200.])\nw, b, lr = 1.0, 0.0, 1e-4\nfor step in range(2000):\n    pred = w * x + b\n    err = pred - y\n    loss = (err ** 2).mean()\n    dw = 2 * (err * x).mean()   # d loss / d w\n    db = 2 * err.mean()         # d loss / d b\n    w, b = w - lr * dw, b - lr * db\nprint(round(w, 3), round(b, 3), round(loss, 4))\n```\n\nThe size of each step, `lr`, is the **learning rate**. Too big and the updates overshoot and blow up; too small and learning crawls.\n\n## The picture: walking downhill in fog\n\nImagine the loss as a landscape where every location is a combination of parameter values and height is the loss. You stand somewhere in thick fog and can only feel the slope under your feet. Gradient descent means: *feel the slope, take a small step downhill, repeat.* With two parameters the landscape is a 3-D surface; with an LLM it has billions of dimensions — but the rule is identical.\n\nThree refinements make this practical at scale:\n\n- **Stochastic (mini-batch) gradient descent** estimates the slope from a small random batch of examples rather than the full dataset, which is much cheaper ([Ruder, 2016](https://arxiv.org/abs/1609.04747)).\n- **Better optimisers** such as **Adam** ([Kingma & Ba, 2014](https://arxiv.org/abs/1412.6980)) adapt the step size per parameter and add momentum. Adam and its variant AdamW are the default for training LLMs.\n- **Backpropagation** computes the gradient for millions of parameters efficiently using the chain rule — covered in [Neural Networks and Backpropagation](/learn/neural-networks).\n\n## From a straight line to an LLM\n\nFor a language model, the setup is the same with three changes:\n\n| | Flat prices | Large language model |\n|---|---|---|\n| Model | `w × size + b` | Transformer with billions of parameters |\n| Example | (size, price) | (text so far, actual next token) |\n| Loss | squared error | **cross-entropy**: −log(probability given to the correct next token) |\n\nCross-entropy is low when the model gave the true next token a high probability and high when it was surprised. Pre-training an LLM is literally running the loop above over trillions of tokens. See [How LLMs Learn](/learn/how-llms-learn).\n\n## The real goal: generalisation\n\nA model can drive the training loss to zero by memorising examples and still be useless on new inputs — this is **overfitting**. That is why practitioners split data into training, validation and test sets and judge models on data they never trained on. Large models trained on huge, diverse datasets generalise surprisingly well, but evaluation on fresh, uncontaminated data remains essential ([How to Evaluate LLMs](/learn/llm-evaluation)).\n\n## Try it yourself\n\nRun the Python snippet above (install Python tools quickly with [uv](/apps/uv): `uv run --with numpy python script.py`). Then try `lr = 1e-3` and watch the loss explode — you have just experienced the most common training failure."
    },
    "zh-hans": {
      "title": "机器是怎么“学习”的：一文讲懂损失函数与梯度下降",
      "description": "所有现代 AI 训练背后的核心循环：模型、损失函数、梯度、更新。用一个小例子和几行 Python 讲清楚，零基础可读。",
      "updated": "2026-10-10",
      "takeaways": [
        "机器学习就是调整模型的参数，让“损失”（衡量错得有多厉害的一个数）在示例数据上变小。",
        "梯度告诉你每个参数该往哪个方向动才能让损失下降；梯度下降就是沿着这个方向走很多小步。",
        "大模型训练是同一个循环的超大规模版本：损失是“下一个 token”的交叉熵，参数有几十亿个。",
        "目标不是在训练数据上考满分，而是在没见过的新数据上表现好（泛化）。"
      ],
      "faq": [
        {
          "q": "损失函数用一句话怎么解释？",
          "a": "损失函数是一个公式，把模型犯的错变成一个数字：0 表示完全预测正确，越大表示越差。训练就是寻找让这个数尽量小的参数。"
        },
        {
          "q": "学习率是什么？",
          "a": "学习率是梯度下降每一步的步长。太大，训练会冲过头甚至发散；太小，训练慢得没法用。现代训练会随时间调整学习率（先预热，再衰减）。"
        },
        {
          "q": "为什么叫“随机”梯度下降？",
          "a": "因为每一步只用随机抽取的一小批样本来估计梯度，而不是用全部数据。这样噪声更大，但便宜得多，而且噪声往往还有好处。"
        }
      ],
      "sources": [
        {
          "title": "Goodfellow、Bengio、Courville，《深度学习》（MIT Press，2016）第 4–5 章",
          "url": "https://www.deeplearningbook.org/"
        },
        {
          "title": "Google，机器学习速成课程",
          "url": "https://developers.google.com/machine-learning/crash-course"
        },
        {
          "title": "Kingma & Ba（2014），Adam: A Method for Stochastic Optimization",
          "url": "https://arxiv.org/abs/1412.6980"
        },
        {
          "title": "Ruder（2016），An overview of gradient descent optimization algorithms",
          "url": "https://arxiv.org/abs/1609.04747"
        },
        {
          "title": "斯坦福 CS229 机器学习讲义",
          "url": "https://cs229.stanford.edu/main_notes.pdf"
        }
      ],
      "url": "https://aimap.page/zh-hans/learn/math-ml/ml-basics/",
      "markdown": "## 学习 = 让一个数字变小\n\n传统软件是写规则：*如果这样，就那样*。机器学习反过来：你提供**示例**和一个**带可调数字（参数）的模型**，由算法去调这些数字，直到模型的输出和示例对得上。\n\n“对得上”需要一个精确的标准，这就是**损失函数**：一个衡量模型在示例上错得有多厉害的公式。训练，就是寻找让损失尽量小的参数。你听说过的所有 AI 系统，图像识别、推荐系统、ChatGPT，都是这样训练出来的。\n\n## 一个小例子\n\n假设要根据面积预测房价，模型是一条直线：\n\n`房价 = w × 面积 + b`\n\n`w` 和 `b` 是两个参数。手上有三个样本：50 平方米 → 100 万，80 平方米 → 160 万，100 平方米 → 200 万。预测数值时常用的损失是**均方误差**：（预测值 − 真实值）² 的平均。\n\n先随便猜，比如 `w = 1, b = 0`。预测出 50、80、100，都太低了，损失很大。接着问：*如果把 `w` 调大一点，损失是变大还是变小？* 这个变化率就是损失对 `w` 的**导数**；所有参数的导数合在一起叫**梯度**。这里梯度告诉我们“该把 `w` 调大”。朝这个方向走一小步，重新计算，再重复。走够多步之后，会到达 `w ≈ 2, b ≈ 0`，正好拟合数据。\n\n```mermaid\nflowchart LR\n  A[\"参数（一开始是随机的）\"] --> B[\"对一批样本做预测\"]\n  B --> C[\"损失：错了多少？\"]\n  C --> D[\"梯度：往哪边走损失会降？\"]\n  D --> E[\"更新：往下坡走一小步\"]\n  E --> A\n```\n\n同样的循环，用几行 Python（NumPy）写出来：\n\n```python\nimport numpy as np\nx = np.array([50, 80, 100.]); y = np.array([100, 160, 200.])\nw, b, lr = 1.0, 0.0, 1e-4\nfor step in range(2000):\n    pred = w * x + b\n    err = pred - y\n    loss = (err ** 2).mean()\n    dw = 2 * (err * x).mean()   # 损失对 w 的导数\n    db = 2 * err.mean()         # 损失对 b 的导数\n    w, b = w - lr * dw, b - lr * db\nprint(round(w, 3), round(b, 3), round(loss, 4))\n```\n\n每一步的大小 `lr` 叫**学习率**。太大，更新会冲过头、数值爆炸；太小，学得像蜗牛。\n\n## 直观图景：在大雾里下山\n\n把损失想象成一片地形：每个位置是一组参数取值，高度是损失。你站在浓雾里，只能感觉到脚下的坡度。梯度下降就是：*感受坡度，往下坡迈一小步，再重复。* 两个参数时，地形是一个三维曲面；大模型的地形有几十亿个维度，但规则完全一样。\n\n要在大规模上用起来，还有三个改进：\n\n- **随机（小批量）梯度下降**：用随机抽取的一小批样本估计坡度，而不是用全部数据，便宜得多（[Ruder，2016](https://arxiv.org/abs/1609.04747)）。\n- **更好的优化器**：例如 **Adam**（[Kingma & Ba，2014](https://arxiv.org/abs/1412.6980)），为每个参数自适应步长，并加入动量。Adam 及其变体 AdamW 是训练大模型的默认选择。\n- **反向传播**：用链式法则高效算出数百万个参数的梯度，见 [神经网络与反向传播](/learn/neural-networks)。\n\n## 从一条直线到大模型\n\n换成语言模型，套路一样，只改三处：\n\n| | 房价预测 | 大语言模型 |\n|---|---|---|\n| 模型 | `w × 面积 + b` | 几十亿参数的 Transformer |\n| 样本 | （面积，房价） | （前面的文本，真正的下一个 token） |\n| 损失 | 均方误差 | **交叉熵**：−log（模型给正确的下一个 token 的概率） |\n\n如果模型给真正的下一个 token 分配了很高的概率，交叉熵就低；如果模型很“意外”，交叉熵就高。大模型的预训练，字面意义上就是在数万亿个 token 上跑上面这个循环，见 [大模型如何学习](/learn/how-llms-learn)。\n\n## 真正的目标：泛化\n\n模型完全可以靠死记硬背把训练损失降到 0，但面对新输入却毫无用处，这叫**过拟合**。所以实践中会把数据分成训练集、验证集和测试集，用模型没训练过的数据来评判它。在海量、多样的数据上训练的大模型泛化得出奇地好，但用新鲜、未被污染的数据做评测依然必不可少（[怎样评测大模型](/learn/llm-evaluation)）。\n\n## 动手试试\n\n运行上面的 Python 代码（可以用 [uv](/apps/uv) 快速准备环境：`uv run --with numpy python script.py`）。再把 `lr` 改成 `1e-3`，看损失爆炸，你就亲身体验了最常见的训练失败。"
    }
  }
}