ARTICLE DETAIL

资讯详情

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

机器学习与深度学习实战必备数学函数:从矩阵乘法到损失函数

机器学习与深度学习实战必备数学函数:从矩阵乘法到损失函数 机器学习 深度学习里真正会用到的全部数学函数干了这么多年机器学习我特别理解一个现象很多人兴冲冲买了“工程数学”“复变函数”的教材咬牙啃完一大堆公式结果打开PyTorch还是不知道torch.matmul和torch.mm到底有什么区别更搞不懂模型里那些函数究竟在做什么。这个问题我一路上见过太多次了所以想写一篇彻底务实的总结把机器学习、深度学习里真正会用到的数学函数挑出来讲清楚它们解决什么问题、长什么样、怎么用顺便排掉一些课本里根本用不上的雷区。这篇内容适合所有准备入门机器学习、正在啃《机器学习》周志华或吴恩达课程、以及被深度学习课本PDF折磨得想放弃的读者看完你会发现——真正要用的数学函数比你想的少得多也远比你想的好懂。1. 从“学了不会用”到“会用不用学”的数学地图1.1 为什么你在课本里学的函数一大半用不上我当年学《工程数学》的时候光复变函数就折腾了小半个学期留数定理、洛朗展开、保角映射背得滚瓜烂熟。后来做第一个深度学习项目才发现这些东西在90%的机器学习场景里压根不会遇到。真正跟ML/DL强相关的数学其实只有三个板块线性代数里的运算函数、概率统计里的分布与估计函数、微积分里的导数与链式法则。剩下的什么偏微分方程、特殊函数、复分析如果你不做通信信号处理、不做流体物理模拟基本就是路人甲。我见过不少初学者在“数学准备阶段”浪费了几个月刷完一堆教材发现没提升然后开始怀疑自己智商。其实问题不在智商在于目标错位。我们学数学是为了能看懂模型、能调参、能定位bug不是去参加数学竞赛。我后来给学生列过一个清单凡是不在这张清单上的数学内容一律不优先看除非你的课题真的踩到了那个领域。这个决定帮我省下大量精力也让学习曲线顺滑很多。1.2 全景图深度学习流水线里到底碰了哪些数学函数先把大局说清楚。一个典型的机器学习流程是这样的拿数据 → 预处理 → 设计模型 → 定义损失函数 → 用优化器迭代训练 → 评估 → 部署。这个流程里数学函数各司其职数据预处理阶段标准化、归一化要么是线性的缩放函数要么是概率分布函数模型结构阶段神经网络每一层都是线性代数运算矩阵乘法、向量点积加激活函数损失函数阶段回归和分类各用各的函数核心就是距离度量和概率度量优化训练阶段梯度下降及其变体背后的数学是导数、偏导数、链式法则评估解释阶段准确率、召回率、F1这些指标本质是概率与统计的计数函数这张图你拿到手之后再看任何一个深度学习项目都不会再慌。因为你知道无论模型叫什么名字、是CNN还是Transformer深挖下去里面能用的数学函数永远不会离开这张图的范围。我建议你把它当作“数学寻宝图”贴在屏幕边遇到看不懂的公式先对号入座看它属于哪个阶段再去针对性学。2. 数值与张量运算一切模型的地基2.1 矩阵乘法所有神经网络都在反复做的事如果你只能记住一个数学函数那必须是矩阵乘法。全连接层的本质就是y Wx b卷积操作在底层实现里也被翻译成矩阵乘法Transformer的注意力机制核心就是QK^T矩阵相乘。可以说深度学习框架里最忙的函数就是矩阵乘法没有之一。拿PyTorch举例你会遇到torch.mm、torch.bmm、torch.matmul、运算符。它们之间最大的差别是维度mm只处理二维矩阵bmm处理带批次的三维张量matmul更灵活能自动处理广播。我开始写代码时用mm报了一堆维度错误后来干脆统一用matmul或世界就清净了。千万别忽视矩阵乘法的维度匹配规则两个矩阵相乘左边矩阵的列数必须等于右边矩阵的行数结果的维度是“左边行数×右边列数”。我见过大量bug比如[32, 10]和[10, 64]相乘没问题得到[32, 64]但[32, 10]和[32, 64]直接乘就会报错。这里建议你每次构建网络结构前先拿笔把输入维度、权重维度、输出维度手算一遍。这是我至今保留的习惯——亲手算过一遍维度比调十次debug高效得多。2.2 范数距离度量与正则化的幕后功臣范数norm在机器学习里的出场频率极高但初学者经常会忽略它。L2范数就是取向量每个分量的平方和再开根号也就是我们熟悉的欧几里得距离L1范数则是绝对值的和。它们差异很大L2计算平滑、处处可导梯度大小和值的大小成正比L1在零点不可导却天然倾向于把稀疏项压缩成0。实际场景中L2正则化也叫权重衰减是训练神经网络时默认的策略它把模型权重压缩到较小范围防止过拟合。L1正则化则常用于特征选择场景比如你要从成百上千个特征里挑出真正有用的那几个L1会自动把无关权重压成0省心省力。我在一个CT图像孔隙三维重构项目里就吃过亏没有正则化时模型在训练集上漂亮得很一到验证集就崩后来加了一层weight_decay1e-4直接稳了一大截。这个参数你现在可能还不熟悉但迟早会用到。代码里对应的就是torch.norm(x, p2)p1就是L1p2就是L2。向量x [3, 4]的L2范数就是5这个勾股定理的直观理解比背公式有用得多。2.3 广播机制想不到的“隐式数学函数”严格来说广播不是数学函数但它本质上是把不同形状的张量自动补齐成相同形状再运算效果上像一个隐式的“扩展函数”。PyTorch里你如果想对一批数据每个样本都减去均值mean通常会写成x - mean其中x是[B, D]mean是[D]。如果没有广播机制你需要手写循环把mean复制B份极其啰嗦。但广播也是一把双刃剑。它太“智能”了一个人初学者最容易踩的坑就是两个张量形状明明不合适广播机制却悄悄帮你“凑合”了一下结果逻辑全错但程序不报错。举个例子[B, 1]和[B, D]相加广播会把前者复制成[B, D]。这本是好事可如果你本意是让[B, 1]分别跟[B, D]的每一列相减最后得到了一个你自己都解释不了的矩阵。我的经验是在关键运算前显式打印形状、显式用unsqueeze标出意图宁可多写两行也别让广播替你“做主”。3. 激活函数神经网络的“呼吸开关”3.1 sigmoid和tanh为什么正在被淘汰在深度学习早期sigmoid几乎是所有神经网络的标配激活函数公式是1 / (1 exp(-x))输出范围落在(0,1)之间。它的优点是便于把输出解释成概率但有两个致命缺点一是饱和区梯度几乎为0深层网络梯度信号传不回去训练直接“卡死”二是输出不是零中心的这会让上层输入的分布产生偏移。tanh把输出范围搬到(-1,1)解决了零中心问题但饱和导致的梯度消失依旧存在。在我实际训练多层网络时凡是用sigmoid做隐藏层激活的基本都失败了不是不收敛就是收敛得极其缓慢。这个教训我觉得每个做深度学习的人都应该亲手体验一次——只有自己踩过才会理解为什么ReLU成了默认选项。3.2 ReLU家族现在的绝对主力ReLURectified Linear Unit实现极其简单max(0, x)正数原样保留负数全部截断为0。它计算快、梯度不饱和、在实践中效果非常好所以成了默认激活函数的第一选择。但它也有个著名的坑神经元“坏死”。如果某个神经元的所有输入都是负数ReLU对它输出永远是0梯度永远是0这个神经元就再也活不过来了。因此在实践里针对ReLU的问题几乎人手一个替代方案Leaky ReLU在负数区给一个小的斜率比如0.01保证梯度不死ELU在负数区用指数曲线平滑过渡GELU结合了ReLU和概率思维输出按输入概率做非线性变形现在在BERT、GPT这些Transformer模型里很常见。做CV项目我会优先试ReLU或者Leaky ReLU做NLP相关模型则直接用GELU省心。3.3 Softmax把分数变成概率的神奇函数分类网络最后一层通常接softmax。它将一组实数logits映射成一组和为1的非负数公式是exp(x_i) / sum(exp(x_j))。它的妙处在于通过指数运算把分数差距拉大让最大的分数获得最高的概率形成一个“概率分布”。你拿电影分类举例模型对《唐人街探案》输出三个判分比如喜剧类4.2、悬疑类5.8、动作类2.1softmax会把它们变成比如[0.18, 0.74, 0.08]加起来等于1这时候取最大概率对应的类别自然就是悬疑。实际工程里有个必须提的细节指数运算在大数值下容易溢出。exp(100)计算机表示不了所以几乎所有框架的softmax实现都先减掉最大值再算指数数学上结果不变数值上稳定得多。你自己手写时也务必做这个“减最大值”操作。3.4 激活函数选型速查表场景推荐激活函数一句话原因默认隐藏层ReLU / Leaky ReLU简单高效梯度不饱和深层网络 残差GELU / Swish平滑训练更稳二分类输出层Sigmoid输出是(0,1)可直接当概率多分类输出层Softmax输出各类概率之和为1回归输出层线性无激活直接输出实数值这张表我自己用了很多年遇到新项目先按表选型再根据实验结果微调。不要一上来就花哨稳定优先。4. 损失函数模型训练方向的指挥棒4.1 回归任务MSE、MAE与Huber的取舍回归任务是预测连续数值比如房价、温度。最常用的损失函数是均方误差MSE公式是mean((y_true - y_pred)^2)。它每个样本误差取平方所以对大误差的惩罚更大这既是优点也是缺点——如果数据里有个离群点MSE会把模型拽向那个异常值整体被带偏。平均绝对误差MAE取的是mean(|y_true - y_pred|)对大误差的惩罚相对温和对离群点没那么敏感训练更稳但它的梯度是常数收敛后期可能来回震荡。我实际工作中遇到过太多次“MSE训练出来的模型被几个异常标签毁掉”的情况后来干脆在自己项目里默认用Huber Loss误差小于阈值δ时表现像MSE平滑可导大于δ时表现像MAE对离群点鲁棒。在PyTorch里对应torch.nn.SmoothL1Loss做回归检测类任务时我第一优先就是它。4.2 分类任务为什么交叉熵是默认选择分类任务的默认损失函数是交叉熵Cross Entropy。它的数学形式是-sum(y_true * log(y_pred))实际框架里通常和softmax组合使用比如PyTorch的nn.CrossEntropyLoss。这个函数的核心是对于正确类别模型给出的预测概率越接近1损失越小越接近0损失爆炸式增大。这背后的原因值得稍微展开你如果把分类模型的输出解释成“概率分布”那么衡量两个分布差距的经典度量就是KL散度而交叉熵正是KL散度去掉常数项后的等价形式。换句话说交差熵不是一个拍脑袋想出来的函数它就是概率论里衡量“预测分布 vs 真实分布”差异的标准答案。这也解释了为什么神经网络分类问题几乎全是它在扛。实际写代码时有个极常见的困惑nn.CrossEntropyLoss内部已经带softmax了所以你的模型最后一层直接输出原始logits就行千万别自己先softmax一遍再传入多此一举还会导致数值不稳定。我在帮人排查代码时这一个问题至少遇到过十几次。4.3 自定义损失函数的通用套路工程到后期大家几乎都会根据自己的任务去定义损失函数。比如在医学图像分割里交叉熵对“前景只占1%像素”的场景极不友好模型很快学会输出“全是背景”拿低损失。这时候就要加Dice Loss它直接度量预测区域与真实区域的交并比公式是2 * |A∩B| / (|A| |B|)对类别不平衡效果好得多。自定义损失函数的一条铁律是只要该函数在你的后端里处处可导或者至少能在绝大部分地方可导、梯度能回传你就可以直接写。神经网络训练靠的是“梯度下降”不是“精确求解”所以哪怕函数带一点不平滑也没关系实践里也都跑得起来。若你正在做口腔疾病图像识别这类医学影像项目一定要多研究Dice Loss和Focal Loss它们在病灶像素只占很小区域的任务里能救你于水火。5. 概率与统计懂分布你才算真懂数据5.1 正态分布机器学习的默认假设数据科学里正态分布高斯分布是绝对的主角公式虽然是个带exp的函数但你不必背诵只需要知道它的两个参数均值μ和标准差σ。很多预处理操作背后都在跟你数据“是不是正态的”较劲。标准化操作z (x - μ) / σ其实就是把一个不确定分布的数据强行对齐到标准正态分布让不同量纲的特征可以公平参与计算。我早年在做图像分类时发现把像素值从[0,255]直接喂给网络训练又慢又不稳改成先减均值再除标准差之后收敛速度明显变快。这个操作的数学本质就是在把数据分布“摆正”。你不妨把每个特征想象成一把尺子有的尺子量程0~1有的尺子量程0~100000标准化的作用就是把它们统统换算成同一个量纲。5.2 极大似然估计理解损失函数的一把钥匙极大似然估计MLE是统计学的核心思想也是理解MSE和交叉熵来源的高级视角。它的逻辑是在给定观测数据的前提下找到一组模型参数使得“这些数据出现的概率”最大。你把这个思想展开对正态分布做MLE推出来就是最小化MSE对伯努利分布二分类做MLE推出来就是二分类交叉熵。所以交叉熵和MSE并非各自独立的规定而是同一条概率原理在不同分布下的具体化身。如果你读文献时看到“最大化对数似然”这个说法别慌它表达的就是我们正在训练模型时的目标本质和最小化损失函数是同义词只是差个负号而已。我曾经在教程里花了整整一章节讲这个推导但最后学生的反馈都一致说想通MLE之后再看所有损失函数都有一种“原来如此”的通透感。5.3 贝叶斯公式的实际角色贝叶斯公式P(A|B) P(B|A)P(A) / P(B)在教科书里地位极高在机器学习实际工程里应用却分两个极端。一方面朴素贝叶斯分类器直接用它做分类尤其在文本分类、垃圾邮件过滤这类场景中简洁有效另一方面在深度学习大行其道的今天贝叶斯的身影更多是“思想”而非“直接计算”——比如贝叶斯优化做超参数调参贝叶斯深度学习做不确定性估计。我在做工程时对贝叶斯公式的定位是不用刻意追求深究但一定要知道它的存在和核心含义——当你看到新证据B时要对旧信念A做修正。这个思维方式比公式本身更有用。遇到数据不均衡问题、冷启动问题时你会自然想到“先验概率”这个概念这就是贝叶斯思维在起作用。6. 优化过程背后的数学核心导数与应用技巧6.1 梯度、偏导数、链式法则反向传播的三件套神经网络训练的数学内核是反向传播而反向传播的三件套就是梯度、偏导数和链式法则。梯度是一个向量它的方向指向函数值上升最快的方向所以我们做梯度下降就是往梯度的反方向迈步让损失变小。偏导数回答的是“如果只动某个权重其他权重不变损失会怎么变”。链式法则回答的是“如果误差传过很多层怎么逐层分配责任”。这三样合起来就是框架自动求导工具backward()背后发生的事情。你不用自己手算链式法则框架都帮你做了。但你必须理解一个最核心的逻辑只有函数处处或几乎处处可导梯度才有定义参数才能更新。这解释了为什么模型里处处是光滑函数——连ReLU这种带一个尖角的函数在0点处不可导也没关系工程上直接指定导数为0或1就行。我在调试自己的模型时最常用的排查手段之一就是“检查梯度”。如果发现某一层权重梯度为nan那几乎必然是前向计算里有数值溢出如果梯度全为0那可能是激活函数饱和、学习率太离谱或者网络真的没在学。理解梯度就是理解模型的命脉这一点我怎么强调都不为过。6.2 学习率、指数移动平均与早停的数学直觉优化过程里除了梯度本身还有几个“数学函数”天天在用。学习率是每次梯度下降迈的步子大小太大直接发散太小半天不收敛。指数移动平均EMA在优化器如Adam里极为重要它本质上是对历史梯度做加权平均公式是v_t β * v_(t-1) (1-β) * g_t越近的梯度影响权重越大β通常取0.9或0.99。这也让模型在梯度噪声大时还能稳定前进不会被单个离谱的梯度带偏。早停Early Stopping则是在验证集损失连续多个epoch不下降时主动结束训练防止过拟合。它虽然没有复杂的数学公式但本质上是在用“验证集上的函数值”做判断。搭配学习率衰减StepLR、CosineAnnealingLR模型的收敛曲线会好看很多。我每次训练都喜欢打印一张“损失-epoch”曲线观察它是不是平滑下降。如果曲线像心电图一样乱跳我会先查学习率是不是过高再查批次大小是不是太小。6.3 优化器的选择思路目前主流优化器就是SGD加动量和Adam两大家族。SGD简单、稳定、需要手动调学习率但对新手不太友好Adam自适应调整每个参数的学习率收敛快、好上手是绝大多数场景的默认选择。如果你想要更高的精度上限往往套路是先Adam快速收敛再切回SGDMomentum精调。这个技巧我在多个图像识别项目里用效果都很好。Adam内部还有β1、β2两个超参数默认0.9和0.999。这几个数字背后涉及一阶矩估计和二阶梯矩估计的指数移动平均。想深入理解的可以去看原始论文但工程上记住“默认值在多数情况下够用不要乱动”就够了。很多初学者喜欢调优化器参数玩我的建议是前期不要碰把精力放在数据质量和模型结构上收益大得多。7. 踩坑与排查数学函数在实战中的事故现场7.1 数值不稳定的四大元凶做机器学习和深度学习最常遇到的“数学”问题几乎都跟数值稳定性有关。我总结成四大元凶一是log(0)交叉熵里预测概率为0时log直接爆炸框架一般会加一个极小的epsilon来防止二是除零在Focal Loss或Dice Loss里分母可能为0务必加平滑项三是大数溢出softmax不先减最大值会出现inf前面已提过四是梯度爆炸深层网络梯度连乘后会极大对应策略是梯度裁剪clip_grad_norm_。每次我遇到loss nan心里默念这四个字数值溢出。绝大多数情况下检查数据里有没有NaN、检查log的输入是不是负数、检查分母是不是0问题就能解决。这套排查顺序我建议你打印在工位前。7.2 常见问题速查表现象可能原因排查/解决方向损失是NaN学习率过大 / log(0) / 分母为0降学习率检查输入数据加epsilon损失不下降学习率过小 / 模型未收敛 / 数据没归一化调大学习率检查数据预处理过拟合严重模型太强 / 数据太少 / 无正则化加weight_decay加Dropout扩数据梯度全为0激活函数死区 / 初始化不好换LeakyReLU检查权重初始化训练震荡剧烈学习率过大 / batch太小降学习率增大batch size验证集突然变差学习率衰减策略不佳 / 过拟合早停降低模型复杂度这张表是我长期调试经验的浓缩版。遇到问题先别慌对号入座一次只改一个变量这是我调试的黄金法则。同时改三个参数还能定位出问题那是奇迹不是常规操作。7.3 我吃过亏的三个实操教训第一个教训是标准化必须在划分训练集和验证集之前只统计训练集的均值和方差然后把这个均值和方差应用到验证集上。我早期写代码图省事整份数据一起算均值方差结果信息泄漏验证集指标虚高模型上线之后彻底翻车。这个错误在Kaggle竞赛里属于“新手必踩经典坑”但做项目时很少有人提醒。第二个教训是自定义损失函数时一定要先在一个很小的batch上跑一次前向和反向看看梯度能不能顺利回传。我做过一个Focal Loss写完之后直接上全量训练三个小时过去loss纹丝不动最后发现是某个分支把梯度截断了。从此之后任何自定义层和损失函数我都会先拿两个样本验证一遍再上全量数据。第三个教训是不要把数学“造轮子”用在工程上。能用框架内置函数就绝不手写。有一次为了让代码看起来“更厉害”我手写了softmax结果忘记做最大值稳定化训练到一半全线NaN。后来我接触的几乎所有大厂代码规范都明确写着优先使用已验证的库函数别自己重造数学轮子。这条规范我往后一直遵守也推荐给你。8. 实操建议我建议你按照这个顺序来用数学函数给刚开始接触的朋友一条可执行路径第一阶段先弄懂矩阵乘法、ReLU、softmax和交叉熵这四样配合一个图像分类小项目比如用CNN识别手写数字。第二阶段再补上损失函数选型和优化器的差异跑一个回归任务比如预测房价练MSE和Huber之间的手感差异。第三阶段回头学概率统计的正态分布和MLE这时候再去看那些损失函数背后的推导会有醍醐灌顶的感觉。第四阶段开始研究自定义损失函数、处理不平衡数据顺便掌握梯度裁剪和正则化。整个过程里你不需要再去碰复变函数也不需要死记硬背任何公式重要的是“看到数学能联想到代码里对应的那个操作”。我个人在实际带项目过程中的体会是机器学习也好、深度学习也好数学真正的作用不是让你“算出来”而是让你“看明白”。矩阵乘法让你理解维度为什么不对链式法则让你理解梯度为什么消失交叉熵让你理解分类为什么这么训练。这些数学函数就像厨师手边的油盐酱醋——用熟了自然而然不必背配料表但少了任何一样菜的味道立刻不对。最后再分享一个小技巧当你面对一篇充满公式的论文时不要从头读先跳到实验部分找到他们用的模型和损失函数然后回来看公式——所有公式都是为这两个函数服务的。看懂它们整篇论文的骨架也就立住了。
返回列表