ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

最大似然估计、梯度下降、EM算法与坐标上升:一条链路看懂机器学习优化

最大似然估计、梯度下降、EM算法与坐标上升:一条链路看懂机器学习优化 最近有朋友问我一个挺有意思的问题最大似然估计、梯度下降、EM算法、坐标上升这四个看起来有关联但到底是怎么串在一起的说实话很多初学者学到这里都会卡住因为这四个概念在书里往往被分在不同的章节最大似然估计是统计学的内容梯度下降是优化理论的内容EM算法是概率图模型里的经典方法坐标上升则经常在SVM、矩阵分解这类项目中突然冒出来。但如果你真正做过机器学习项目就会发现它们本质上是一条完整的链路先通过最大似然估计构造出目标函数再选择合适的优化算法去求解而EM算法和坐标上升都是这种求解思路的特殊变体。这篇文章想把这条主线理清楚。我尽量用大白话讲少堆公式但关键的数学推导会保留——毕竟是做算法的公式本身就是最精炼的语言。希望读完你能建立一张自己的“地图”以后遇到新的模型能够一眼看出它在这条链路的哪个环节应该用什么样的思路去求解。1. 最大似然估计建模的起点几乎所有损失函数的亲爹1.1 最大似然估计在干什么一个硬币的例子先从一个最朴素的问题开始你有一枚不知道是否公平的硬币抛了10次结果是7次正面3次反面。请问这枚硬币正面朝上的概率p是多少凭直觉几乎所有人都会回答p0.7。但为什么是0.7最大似然估计Maximum Likelihood EstimationMLE给了一个严谨的回答因为p0.7时我们观测到“7正3反”这一组结果的可能性最大。这个“可能性”就是似然函数。假设单次正面概率为p抛10次出现7次正面的概率是L(p) C(10,7) * p^7 * (1-p)^3我们想知道的是p取什么值时上面这个数最大。求导令导数等于零解出p0.7。这就是最大似然估计的核心思想——在参数的所有可能取值中找一组让当前观测数据出现概率最大的参数。这个思想看起来简单到近乎废话但它几乎构成了机器学习中所有有监督损失函数的基础。回归问题里你用MSE当损失函数本质上是在假设误差服从高斯分布的前提下做最大似然估计分类问题里你用交叉熵当损失函数本质上是在假设输出服从伯努利分布或多项式分布的前提下做最大似然估计。换句话说你平时在训练模型时调的每一个参数背后都站着最大似然估计这个“亲爹”。1.2 为什么对数和负号从数学便利到损失函数实际操作中我们一般不会直接优化似然函数L(θ)而是优化对数似然函数log L(θ)。原因有两层。第一层是数学上的便利。似然函数通常是很多概率密度相乘的形式样本一多连乘的结果会小到浮点数都表示不出来而且求导极其麻烦。取对数之后连乘变成连加求导变成了逐项求导的和方便得多。第二层是优化习惯的问题。我们习惯做最小化而非最大化所以通常会取负号把“最大化对数似然”变成“最小化负对数似然”NLL。这就是很多深度学习框架里损失函数为什么长成那样的原因。你打开PyTorchCrossEntropyLoss的文档里写的就是“This criterion computes the cross entropy loss between input and target”但它的本质就是在做负对数似然的最小化。注意这里有个很容易被忽视的点——常数项在MLE中可以随便丢。比如高斯分布的概率密度前面有1/(σ√(2π))这种常数在最大化过程中它们不影响参数的解所以推导MLE和MSE关系的时候经常看到一堆项被“莫名其妙”丢掉了初学者容易懵。其实只要记住“常数不进求导结果不影响极值点位置”就够了。1.3 MLE变成损失函数之后一个必须掌握的高斯-最小二乘推导说MLE是损失函数层面的“亲爹”最好用一个经典推导来证明在高斯噪声假设下最大化似然函数等价于最小化均方误差。假设我们有输入特征x和输出y真实关系是y f(x; θ) ε其中ε服从均值为0、方差为σ²的高斯分布。那么对于给定的参数θ观测到y的概率是p(y|x; θ) (1/(σ√(2π))) * exp(-(y - f(x; θ))² / (2σ²))把一组独立样本的似然函数写出来取对数log L(θ) -n*log(σ√(2π)) - (1/(2σ²)) * Σ(y_i - f(x_i; θ))²第一项是常数扔掉最大化log L(θ)等价于最小化Σ(y_i - f(x_i; θ))²。这就得到了MSE。同样的套路把高斯分布换成伯努利分布推导出的就是交叉熵损失。所以说理解了MLE你就理解了回归和分类两大任务的损失函数来源。以后看到一个模型的损失函数不要死记硬背试着从“这个模型假设了什么分布”出发去推导大概率都能推出来。2. 梯度下降从大山上下来的笨办法但有效2.1 为什么要有梯度下降解析解不是万能的有了目标函数之后最理想的情况是像求硬币概率那样直接令导数等于零解出参数的解析解。线性回归的闭式解就是这样求出来的θ (X^T X)^(-1) X^T y一行代码解决。但是现实很骨感。神经网络的目标函数是成千上万层非线性复合函数求导等于零之后根本解不出解析解只能通过迭代的方式一点一点逼近最优点。梯度下降就是最经典的迭代优化方法。这里补充一个非常基础但重要的背景为什么深度学习总用梯度下降而不是牛顿法、共轭梯度法这些其他优化算法答案是规模。深度模型的参数量动辄百万千万牛顿法需要计算海森矩阵的逆这在计算量上是不可实现的。梯度下降只需要一阶导数每次迭代的代价仅仅是反向传播一次计算复杂度与参数量线性相关所以在超大模型场景下几乎是唯一现实的选择。2.2 梯度方向为什么是对的用“山里的盲人”理解想象你在一个被浓雾包裹的山里想要下到山谷最低点。你看不到整座山的地形只能感受到脚下和附近一小块区域的坡度。怎么才能最快下到谷底当然是朝“最陡的下坡方向”迈出一步然后重新感受坡度再迈下一步。这个“最陡的下坡方向”在数学上就是梯度的反方向。梯度向量指向的是函数值增大最快的方向所以负梯度方向就是函数值减小最快的方向。梯度下降的迭代公式就是θ_{t1} θ_t - η * ∇L(θ_t)其中η是学习率步长决定了一次迈多大步子。这个公式简单到看似没有任何技术含量但它却是目前整个人工智能领域最核心的基石——从最简单的逻辑回归到万亿参数的GPT训练过程的底层逻辑都是这个公式。2.3 学习率、动量、Adam为什么不能一步走太远学习率可能是整个机器学习里最敏感的超参数。设大了参数会在最优点附近来回震荡甚至直接发散——好比下山时步子迈太大从这一侧坡直接跨到对面更高的坡上去了设小了训练过程慢得让人怀疑人生而且容易困在局部最优点周围。实际的工程做法是用带动量的梯度下降Momentum、RMSProp或Adam这些改进版。动量做的事情很直觉这次移动的方向不仅考虑当前梯度还累积了之前几步的移动惯性。还是用下山类比如果你在一条比较平缓的坡上累积的动量会让你加速滑过如果你遇到了一个小坑局部极小值惯性能帮你继续往前冲出去一段有机会脱离这个小坑。但要说清楚这些方法本质上都是“一阶优化方法”的变体只是在“如何选方向、如何定步长”上做了更聪明的策略核心的迭代框架依然是梯度下降。Adam这么大行其道就是因为它把动量思想一阶矩和自适应学习率二阶矩结合在了一起在大多数任务上都不太需要手动调学习率策略属于“开了挂的梯度下降”。2.4 反向传播能解决局部最小值问题吗一次精度校正目前网上有一个讨论度很高的题目“反向传播可以解决梯度下降局部最小值的问题吗”这个问题本身混进去了几个概念值得掰开了说。反向传播Backpropagation是一套计算梯度的算法。它解决的是“梯度怎么算出来”的问题——从输出层到输入层逐层应用链式法则高效地求复合函数对每个参数的偏导。梯度下降是使用梯度的优化框架。两者不是一个层面的东西所以严格来说反向传播本身不负责解决局部最小值。但是反向传播带来的高效梯度计算确实间接帮助了训练过程。为什么因为能轻松、廉价地计算出梯度我们才可以频繁地迭代、用大量样本的随机估计来引入噪声、在训练过程中频繁地调整参数而这些操作组合在一起恰恰是帮助模型逃离局部极小值的真正推手。但如果你问“反传本身能不能保证不陷入局部最优”答案是不能。实操心得这几年有不少实验表明在高维空间中我们担心的“局部极小值”其实远没有想象中那么多。真正讨厌的而是“鞍点”——在一个方向上是最小值、在另一个方向上是最大值的点。梯度下降在鞍点附近的收敛速度会变得极慢因为梯度几乎为零。这也是为什么动量方法在很多任务中表现更好的原因之一惯性可以帮助模型“冲过”鞍点区域。3. EM算法当数据“看得见摸不着”时3.1 为什么需要EM隐变量的困局和梯度下降处理“可观测量”的优化不同EM算法解决的是另一类经典问题——含有隐变量latent variable模型的参数估计。举个例子一个班级里男女身高服从不同的高斯分布现在你手里只有每个学生的身高数据却不知道每个学生是男是女。这时候如果你想估计男生身高的均值μ1、女生身高的均值μ2你发现一个尴尬的循环依赖如果知道哪些样本来自男生就可以用MLE直接估计μ1和μ2如果知道μ1和μ2就可以根据身高反推每个样本更可能来自哪个群体。但现在什么都不知道。这种问题没法直接用梯度下降去解。因为目标函数中要对隐变量的所有可能取值做求和/积分边缘化这往往导致目标函数没有好的解析形式直接对参数求梯度也极其困难。高斯混合模型GMM就是这类问题的典型代表。K个高斯分布叠加在一起每个样本由某个高斯分布生成但生成它的那个“编号”是隐变量。你看到的只是混合后的数据分布看不到数据来源。3.2 E步和M步分别做了什么一个“先猜后优化”的游戏EM算法的思路非常巧妙它把这个循环依赖通过迭代拆开了。E步期望步固定当前参数计算每个样本属于各个隐类别的后验概率。在GMM中就是给定当前均值、方差和混合系数计算每个样本属于第k个高斯分量的概率γ_ik。这些γ_ik不做决策——不是硬性说“这个样本属于第一类”而是给出一个软分配比如“这个样本0.8的概率属于第一类0.2的概率属于第二类”。M步最大化步用这些软分配作为权重重新估计参数。在GMM中更新每个分量的均值时不是简单地对所有样本求平均而是加上了γ_ik作为权重——属于该分量的概率越大的样本对均值估计的贡献越大。E步和M步交替进行每轮迭代都能保证似然函数的值单调不减最终收敛到一个局部最优解。这个“保证单调不减”是EM最漂亮的理论性质也是它比盲目梯度下降在带隐变量问题上更受青睐的原因。用大白话讲EM就像一个打靶游戏E步是“根据当前枪的准星位置推测弹孔更可能是谁打的”M步是“根据推测结果调整准星”。重复这两步准星会一点点逼近靶心。3.3 从MLE到EM换个视角搞定“残缺”的数据如果你想用一句话来概括EM可以这么说EM算法是一种用于含隐变量模型的特殊求解框架它的目标是最大化“不完整数据”的对数似然方法是交替地进行对隐变量的后验推断E步和参数的标准极大似然更新M步。关键点是M步本质上就是在做一个局部的最优化——只不过它优化的不是原始似然函数而是“考虑了隐变量后验分布后的期望似然”数学上叫Q函数。因为这个Q函数在形式上是“参数和隐变量联合对数似然”在隐变量后验分布下的期望处理起来比原始边缘似然简单得多。有意思的是在GMM这种模型上M步往往能写出闭式解——就是加权平均、加权方差这一套。而在另一些模型比如LDA主题模型中M步可能又需要借助梯度上升或其他迭代优化来完成。这时候EM作为一个外部框架内部还嵌套着其他优化方法。理解了这个嵌套关系再看各类模型的求解流程就豁然开朗了。3.4 EM算法的典型应用场景EM算法在业界最常见到的几个应用场景高斯混合模型聚类这是EM最经典的舞台。和K-Means相比GMM能给出软分配能适应椭球形聚类而且能给出数据生成概率因此被广泛用于异常检测、图像分割、用户分群等场景。K-Means其实可以看作高斯混合模型里协方差矩阵趋近于零、分配趋于硬分配的极限特例。缺失数据处理真实业务数据经常有缺失值直接把有缺失的样本删掉太浪费EM可以通过迭代方式一边推断缺失值的最可能取值一边估计模型参数。这个用途在用户行为分析和金融风控数据清洗中非常实用。隐马尔可夫模型HMM的参数估计Baum-Welch算法本质上是EM在HMM上的特例前向-后向算法对应E步计算隐状态后验更新转移矩阵和发射概率对应M步。语音识别、词性标注、生物序列分析中大量使用这套框架。主题模型LDA的求解虽然如今主流是用变分推断和吉布斯采样但EM的思维方式在理解这些算法时依然非常有帮助——它们都在隐变量框架下做事。4. 坐标上升一次只调一个旋钮4.1 坐标上升的基本思想和梯度下降不同的“拧螺丝”策略坐标上升Coordinate Ascent是另一种优化方法。它和梯度下降有一个很核心的区别。梯度下降每次迭代都会同时更新所有参数你把θ看作一个整体沿着负梯度方向“斜着”迈一步。而坐标上升每次只在一个坐标方向上优化其他坐标全部固定不动一轮迭代之后再换下一个坐标方向。打个比方。你在调试一台仪器仪器上有N个旋钮它们共同决定输出效果。坐标上升的思路是先把其他N-1个旋钮固定只拧第一个旋钮拧到当前设定下最优的位置然后固定其他旋钮只拧第二个旋钮以此类推。一轮结束回到第一个旋钮再来一遍直到所有旋钮都“拧不动”了。对应到坐标上升的迭代公式每次只更新θ的第j个分量让目标函数在这个分量上达到最优其余分量保持最近一次更新的值不动。在函数可微且约束简单的情况下第j个分量的更新往往可以从“对该分量求导并令其等于零”解出来。4.2 EM和坐标上升的关系很多人忽略的等价性很多人把EM和坐标上升当成两个独立知识点来学但实际上EM算法中交替执行的E步和M步可以看成是在以参数和隐变量后验分布组成的扩展空间中做坐标上升。如果你把E步和M步视为两个“坐标块”E步固定参数θ更新隐变量的后验分布qM步固定q更新参数θ。那么EM算法就是块坐标上升Block Coordinate Ascent——只不过它优化的不是原始似然函数而是似然的一个下界ELBO证据下界。每一轮迭代看到的一切都在比上一轮更好最终收敛到局部最优。这也是为什么EM能保证对数似然单调不减的原因ELBO是似然的下界你对下界做坐标上升下界提升它就越来越贴近真实似然两层效果叠加在一起似然自然只增不减。理解“优化一个下界”这个视角特别重要。后来做变分推断VI的时候会发现变分推断和EM的关系就像是“同门师兄弟”——都用ELBO做框架区别在于EM的推断步可以精确计算后验而变分推断在推断步用一个更简单的分布族去近似后验。把坐标上升的思维方式搞清楚了后面学变分自编码器VAE的时候会省一半力气。4.3 坐标下降的实用价值为什么现在还能见到它可能有人会问现在自动微分工具这么发达还有什么场景需要手工推导坐标更新的公式实际答案是不仅还用而且很常用。一个非常重要的理由是计算效率。在稀疏高维问题中——比如推荐系统里的矩阵分解、带L1正则的回归模型、大规模线性SVM——坐标下降可以只更新当前非零坐标对应的参数其余参数连碰都不用碰。如果目标函数本身能在单坐标更新上写出解析解那整个算法的每一步都极快甚至不需要计算梯度向量。相比之下梯度下降每次都需要更新全量参数即使在多轮冻结稀疏矩阵的情况下也还是要遍历相关的参数。另一个理由是可以处理非平滑目标函数。比如带L1正则的目标函数包含绝对值项它在零点不可导标准的梯度下降没法直接用次梯度法实现起来又慢精度又差。坐标下降在这个问题上有天生的优势把目标函数看作单变量的函数之后可以利用软阈值算子直接写出解析更新解一步到位。这个技巧在Lasso回归的坐标下降解法里体现得淋漓尽致。4.4 随机坐标上升/下降更容易逃出局部最优和梯度下降有随机梯度下降SGD一样坐标上升也有随机坐标上升Random Coordinate Ascent。每次迭代随机选择一个坐标方向进行优化配合适当的学习率调度。随机化带来的第一个好处是打破循环依赖。在一些高度耦合的参数空间中如果固定顺序轮流更新可能会陷入一种“循环踩点”的困境每次都以固定的节奏走入终点而不是向谷底前进。随机化之后这种规律性被打破收敛行为反而更稳健。第二个好处是逃离局部最优。坐标上升的一个固有缺陷是在非凸问题上特别容易被“卡死”——因为每次只沿坐标方向优化很多方向上看起来都动不了了但实际上如果在所有方向同时调整就像梯度下降那样明明还能继续下降。随机地、偶尔地沿着某个方向“用力过猛”跳一下有时就能跳出局部陷阱继续下滑到更好的解。5. 四者关系全景图与实战排查经验5.1 一条主线串起来从模型假设到算法落地聊到这里四个概念之间的关系应该比较立体了。我用一条完整的主线把它们串起来拿到一批数据和你的建模假设分布假设、网络结构假设第一步永远是构造目标函数。这一步的指导思想就是最大似然估计——你的损失函数几乎总是负对数似然的某种等价形式。有了目标函数接下来要选择优化算法。如果目标是光滑的、参数维度适中且导数容易计算那你直接用梯度下降或其变体就可以了。如果你的模型含有隐变量直接优化似然函数太难那就把参数空间扩展一下参数θ加隐变量q一起优化。这时候EM算法登场它通过交替更新q和θ来最大化似然的下界。从优化视角看这一交替过程就是坐标上升/块坐标下降在特殊目标函数上的应用。而坐标上升作为更底层的优化策略本身还有广阔的应用场景Lasso回归、矩阵分解、带约束的凸优化问题……它和梯度下降都是数值优化的子领域只是坐标上升选择了“逐个旋钮拧到最优”的路子。这四者的关系用一句话概括就是最大似然估计是建模层面的目标梯度下降和坐标上升是参数优化层面的手段EM算法则是为含隐变量模型量身定制的一个基于坐标上升思想的求解框架。5.2 常见误区避坑指南这些年看过的面试和项目中对这四者最常见的混淆主要有几个整理出来提醒一下把EM和梯度下降对立起来。这两个并不是非此即彼的关系。EM的内部M步完全可以使用梯度上升来求解Q函数的最大值。反过来说梯度下降也可以用来求解含隐变量的目标函数只是直接对边缘似然求导的计算量通常不可接受因此实际很少这么做。误以为坐标上升和梯度下降收敛到同一个解。在凸问题上它们会收敛到相同的全局最优但在非凸问题上坐标上升更容易困在局部最优里而且跟坐标选择的顺序有关。很多人在实现矩阵分解时发现结果忽好忽坏就是因为没有固定坐标访问顺序或者没有引入随机性。把MLE和优化算法混为一谈。MLE回答的是“最优参数是什么”——这是一个目标定义梯度下降回答的是“怎么找到最优参数”——这是手段。很多人说“用MLE训练模型”这里严谨的说法是“用MLE定义目标函数再用梯度下降来优化这个目标”。5.3 实战调试经验从损失函数不下降说起我自己在实际项目中遇到最多的一类问题是定义好负对数似然作为损失函数之后训练过程中loss不下降、震荡或者下降极慢。很多人第一反应是调学习率或加大模型但这里有一个更值得先检查的方向——先确认目标函数本身有没有写对。一个非常经典的坑是在实现GMM的负对数似然损失时忘了考虑数值稳定性。计算log-sum-exp的时候直接先算exp再取log中间值可能变成inf或者NaN导致梯度消失或变成NaN。正确的做法是用log-sum-exp的平滑形式把最大的项提出来减去它再取exp最后加回来。这个细节直接决定了模型能不能训练起来。另一个坑是关于收敛判定的。用EM算法时很多人习惯看参数的变化量——比如参数更新前后差值的绝对值小于某个阈值就认为收敛。但在GMM这种场景下参数的某个分量例如某个高斯分量的混合系数在收敛后期可能变化极小而似然值其实还在缓慢提升。更好的做法是同时监控完整的对数似然值。如果算出来的似然值在某个迭代后开始下降基本可以断定实现有bug因为理论上EM保证单调不减。在我做推荐系统矩阵分解项目的时候坐标下降的调试中有个特别影响精度的细节参数的更新顺序会改变收敛速度。固定顺序一轮一轮更新时如果第一轮更新的参数恰好是影响最大的主方向后期收敛会很快如果顺序反过来可能要跑很多轮才能达到同样的精度。后来我索性改成随机顺序每一轮随机打乱参数的更新次序实测下来收敛速度更稳定最终损失也更低。5.4 学习建议从一个代码项目同时吃透四个概念如果让我给你一个可操作的学习路径我会建议直接手写一个高斯混合模型——不要用sklearn从零开始实现。第一步实现它的目标函数写出负对数似然也就是“数据”和“对数高斯混合概率密度”对比的误差这就是MLE层面的功夫。第二步实现随机初始化参数均值、协方差、混合系数然后用EM算法迭代更新参数这就同时练了E步的后验概率计算和M步的加权参数估计。第三步试着手写一个梯度上升来最大化Q函数替换掉解析的M步更新公式体会一下EM框架内嵌其他优化算法的嵌套结构。第四步试着把E步和M步当成两个坐标块在一个更大的循环里做块坐标上升再和标准EM做对比看看似然提升的轨迹有什么不同。这套练习做下来你对四个概念的理解会完全不一样。纸上得来终觉浅绝知此事要躬行——这句话在机器学习里尤其成立。所有看似抽象的算法手推一遍、手写一遍、调试一遍就都是你自己的东西了。
返回列表