查看全课大纲(第 17 / 82 节)
- 1.函数与数据泛化
- 2.向量:从几何直觉到高维空间
- 3.矩阵与张量
- 4.特征值与特征向量:矩阵变换的不动方向
- 5.凸函数:从向量求导的矩阵记号到好优化的函数形状
- 6.概率与统计:机器学习的数学基础
- 7.独立性与随机变量:贝叶斯公式与二项分布
- 8.期望、方差与协方差:随机变量的数字画像
- 9.联合概率:当一条轴不够用的时候
- 10.概率分布(一):从伯努利到伽马函数
- 11.概率分布(二):贝塔、泊松、正态与两个贝叶斯故事
- 12.机器学习的模型:找输入与输出的关系
- 13.机器学习的应用
- 14.过拟合
- 15.机器学习的分类
- 16.有监督学习:从房价预测说起
- 17.损失函数
- 18.梯度下降(上):更新规则与学习速率
- 19.梯度下降(2)
- 20.牛顿方法
- 21.KNN简介
- 22.距离测算
- 23.朴素贝叶斯
- 24.朴素贝叶斯的实际应用
- 25.信息熵:决策树构建的度量基础
- 26.信息增益与决策树的构建
- 27.ID3算法
- 28.决策树节点的划分
- 29.CART树
- 30.Bagging
- 31.Boosting:自适应提升算法
- 32.Gradient Boosting
- 33.线性模型:回归与分类的同一副骨架
- 34.最小二乘:把最优参数直接解出来
- 35.最小二乘法的几何与概率视角
- 36.极大似然:给最小二乘一个概率出身
- 37.逻辑回归(1):把线性模型接到分类上
- 38.逻辑回归(2):损失函数与多分类
- 39.---- 手造数据: 5 个样本, 2 个特征; x2 几乎 = 2*x1 (偏差手工指定, 无随机) ----
- 40.讲师例: 向量 "23014" -- 三把范数尺子量同一个向量
- 41.优化方法(1):坐标下降与前向选择
- 42.优化方法(2):前向策略与最小角回归
- 43.拉格朗日乘子法(1):从无约束到等式约束
- 44.拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
- 45.拉格朗日乘子法(3):不等式约束与 KKT 条件
- 46.最大间隔:把分类问题变成优化问题
- 47.拉格朗日对偶问题:把 w 和 b 全部换成 α
- 48.支持向量:边界上的少数派
- 49.SVM 计算过程:一笔到底算完,再走进核方法
- 50.贝叶斯公式:概率即信念
- 51.隐含变量和概率模型:给看不见的原因建模
- 52.EM 算法:期望与最大化的迭代
- 53.琴生不等式:EM 的数学钥匙
- 54.三个硬币问题:EM 的复盘与衔接
- 55.高斯混合模型:用隐变量解释双峰数据
- 56.隐马尔可夫模型
- 57.隐马尔可夫模型(2):前向算法与动态混合模型
- 58.隐马尔可夫模型在 NLP 中的运用
- 59.EM 算法:把「为什么收敛」推到底
- 60.HMM 在 NLP 中的运用:从分词到机器翻译
- 61.HMM 参数估计:Baum-Welch 的三块拉格朗日
- 62.高维下的高斯模型
- 63.主题模型:从词袋到隐含主题
- 64.Dirichlet 分布(1)
- 65.Dirichlet 分布(2)
- 66.统计学习内容回顾
- 67.K-means 算法
- 68.PCA 降维
- 69.SVD 降维
- 70.从聚类到流形
- 71.局部线性嵌入
- 72.随机邻域嵌入:SNE 与 t-SNE
- 73.无参模型:让数据自己说话
- 74.高斯过程:函数空间里的正态分布
- 75.高斯过程(2):噪声、正则化与核的线性组合
- 76.神经网络简介:从感知器到自编码器
- 77.反向传播:把误差一层层传回去
- 78.卷积神经网络(CNN):让特征自己学出来
- 79.循环神经网络(RNN):给网络装上记忆
- 80.深度学习回顾:静态一类,动态一类
- 81.增强学习(1):蒙特卡洛、树搜索与 Q-learning
- 82.强化学习(2):从乌鸦吃核桃到井字棋的 value 回传
损失函数
约 11 分钟
小象实战讲义 · 机器学习算法精讲
上一节结尾我们留了一个问题:把”误差大小”写成一个严格的数学函数,需要什么要素?——正负号怎么处理、多个样本的误差怎么合并?本节就来兑现这个预告,正式引入损失函数(Loss Function,也常叫 cost function,代价函数):它是衡量模型好坏的”评分员”,把”找一条好的拟合线”这个模糊愿望,精确转化为”最小化一个关于参数的函数”。我们仍然从那个最简单的三点例子出发。
💡 核心导读
- 为什么需要损失函数:计算机没有眼睛,判断模型好坏需要明确的、可计算的指标。
- 平方误差的构造:正负误差用平方统一处理,多样本误差求和取均值——两个构造要素一次讲清。
- 手算三个 θ:亲手算出 J(0.5)=7/12、J(0)=7/3、J(1)=0,感受损失随参数的变化。
- 碗形曲线:J(θ) 是一只开口向上的”碗”,碗底就是最优参数——这正是下一节梯度下降的舞台。
从”眼睛看”到”算得出”:为什么需要损失函数
先别忘了:我们手里这个三点例子,是被简化到极致的玩具。真实的数据经常是这样的——最完美的那条线既不通过原点,也不太可能把所有点都连成一条直线。我们能追求的,是找到一条线,使所有点到它的误差最小——这就是我们的学习目标。但讲师选择从这个最简单的问题出发,看能不能找到更好的结果。
回顾上一节的设定:三个训练点 、、,假设函数取最简形式 (暂不学截距,只学一个参数 )。我们试过三条线:
- :绿色直线 ;
- :橘黄色直线 ;
- :紫色直线 ,其实就是横轴。
眼睛一看就知道绿色的最好。但计算机没有眼睛——它需要一个明确的、可计算的指标来判断好坏。这个指标,就是损失函数。
构造损失函数:把”误差大小”写成一个严格的函数
好的线是什么?上一节说过:所有的点到这条线的距离最短。麻烦在于,有的点在线上方、有的在线下方——误差有正有负,直接相加会互相抵消。所以求这个”距离”的时候,要么用绝对值,要么用平方。本课选择平方,于是有了下面的构造:
其中 是训练样本数(本例 ), 是模型对第 个样本的预测值, 是真实值。它做的事直白得很:把每个点到当前直线的距离平方加起来,再取均值(把误差平方求和再平均,正是大家常说的均方误差 MSE 一族;本课在它前面再乘了 )。
损失函数的意义在于它的操作语义:我们调整 hypothesis 里的参数,每调一次,都希望 变小——这样就知道 该往哪个方向调。换句话说,我们给 设定了一个目标,而这个目标一定是关于 的函数。 等于多少的时候最好?等于 最小的时候。
那个 1/2 是干什么的
为什么均值前面还挂一个 ?这是故意构造的:整个函数的大小不会因为乘一个常数而变化,而带着 ,以后对平方项求导时,2 和 恰好约掉,梯度表达式更干净。用讲师的原话说:for mathematical convenience——纯粹为了数学上的方便。
顺带一提:有的人构造的损失函数就是直接把 累加,不带 ——本质上没有任何区别,都是求误差最小;本课采用这个形式,是因为它”特别好看和漂亮,用起来特别方便”。
手算三个 θ:损失到底差多少
现在回到三条线,把 一个个算出来。
情况一:(橘黄色直线)。逐点代入: 时 ,误差 ; 时 ,误差 ; 时 ,误差 。于是
(较真的同学会问:误差是 还是 ?无所谓——平方会把正负号消掉,两者殊途同归。)
情况二:(紫色直线,横轴)。三个误差是 、、:
情况三:(绿色直线)。三个误差全是 0,所以 ——而且说句实话,这是碰巧(accidentally):这个被给定的简单问题,竟然所有的点都正好落在 上。真实数据不会这么客气。
三个数一摆,好坏立判:。
碗形曲线:J(θ) 长什么样
现在换个视角:把 当自变量、 当因变量,我们已经知道曲线上的三个点—— 时 ; 时 (比 0.5 略大一点的位置); 时 (二点多的位置)。把整条曲线画出来,它是一只开口向上的碗(bowl shape)——讲师形容它”像一个碗、或者一条船”,有一个最低点。碗底就在 :最好的 ,就是让损失函数最小的 ,记作 。用代码把这只碗亲眼看一遍,顺便对账刚才的三个手算值:
# 把 J(θ) 的"碗"亲眼看一遍:先对账三个手算值,再扫描不同的 θ
data = [(1, 1), (2, 2), (3, 3)]
def cost(theta):
"""本节的损失函数 J(θ) = 1/(2N) * Σ(h(x) - y)^2,其中 h(x) = θx"""
total = 0.0
for x, y in data:
h = theta * x
total += (h - y) ** 2
return total / (2 * len(data))
print(f"J(0.5) = {cost(0.5):.4f} # 手算 7/12 ≈ 0.5833")
print(f"J(0.0) = {cost(0.0):.4f} # 手算 7/3 ≈ 2.3333")
print(f"J(1.0) = {cost(1.0):.4f} # 手算 0")
print()
print("theta | J(theta)")
print("-" * 22)
for t in [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5]:
print(f" {t:4.2f} | {cost(t):.4f}")J(0.5) = 0.5833 # 手算 7/12 ≈ 0.5833
J(0.0) = 2.3333 # 手算 7/3 ≈ 2.3333
J(1.0) = 0.0000 # 手算 0
theta | J(theta)
----------------------
0.00 | 2.3333
0.25 | 1.3125
0.50 | 0.5833
0.75 | 0.1458
1.00 | 0.0000
1.25 | 0.1458
1.50 | 0.5833扫描表里有两处耐人寻味。其一, 从两侧向 一路下滑、在碗底归零——这只碗其实还有个看得见的结构:误差恰好是 ,所以 ,单参数的碗就是一条抛物线。其二, 与 的损失同为 、 与 同为 ——离碗底等距的两侧,损失相同。
这只碗正是第 1 章我们亲手验证过的凸函数:没有局部坑洼,只要往低处走,就一定能走到全局最低点。也呼应上一章”在假设空间里搜索”的说法——现在搜索有了评分标准:在假设空间中,找使损失函数最小的那个参数。
不过,刚才的一切都只是”随机代几个值进去试”。真实的模型参数动辄成千上万,靠枚举不可能找到碗底。我们需要一套完整的算法:从随机给定的 出发,一步步走到最优点。这套算法就叫梯度下降(Gradient Descent)——下一节的主角。
📝 动手练一练
- 概念辨析:如果把损失函数定义中的 改成 ,即 ,那么对同一个 , 和 是什么关系?这会影响我们找到的最优参数 吗?为什么?
👉 点击查看参考答案
:只是整体乘了一个常数因子 2。
这不会影响最优参数 。求最小值只关心”哪里最低”,对函数整体乘以正常数,图像形状不变、只是纵向拉伸,最低点的横坐标不变。所以两种定义下,使损失最小的 是同一个——这也正印证了讲师说的:那个 是 for mathematical convenience,为数学上的方便而设,不改变优化问题的本质。
- 动手计算:假设训练数据变为 、、,假设函数仍为 。请手算 和 对应的损失函数值(用讲义中的定义)。哪个 θ 在这个小数据集上损失更小?
👉 点击查看参考答案
,分母 。
当 时:预测 ,误差 ,。
当 时:预测 ,误差 ,。
,所以在这一小撮数据上 更好。注意:这组数据没有哪个 θ 能让损失为 0——三个点不在过原点的同一条直线上,这正是本节开头说的”真实数据不会这么客气”。
本章小结
本节我们把上一节”试线靠手感”的直觉,升级成了一个严格的数学对象:损失函数 。它用平方统一了误差的正负号,用求和取均值合并了多个样本,用 为将来求导留了方便。手算三个 θ 让我们看到损失如何随参数变化,而它呈现的碗形(凸性)保证了”往低处走就能到最低点”。找碗底的系统方法——梯度下降,就是下一节的内容。
📋 行动清单
学完本节,你可以立即:
- 复述要素:不看讲义,说出损失函数定义里每一部分(平方、求和、均值、1/2)分别解决什么问题。
- 换数据再算:自己编三个数据点,手算两个不同 θ 的损失,体会”评分员”怎么打分。
- 预习下一节:站在碗边想一个问题——不知道碗在哪、也画不出整只碗时,怎么找到碗底?(提示:脚下的坡度。)
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。