机器学习入门必知:损失函数、树模型与训练迭代全解读

发布时间:2026/10/17 2:26:35
机器学习入门必知:损失函数、树模型与训练迭代全解读
很多小白入门机器学习时总会被三件事卡住一是面对一堆损失函数不知道挑哪个二是看着决策树、随机森林的树状结构似懂非懂不清楚训练时到底在“学”什么三是训练日志里epoch、batch、iteration、lr挨个蹦出来符号全是英文但意思对不上号。我当初也是这样踩过不少坑之后把这三块内容揉成了一篇笔记。这篇不会堆公式吓人而是把概念放到实际场景里说清楚适合刚入门、想快速建立直观理解的读者也适合那些理论看了几遍但动手时还是会卡壳的人。1. 损失函数模型靠什么“认错”1.1 损失函数的本质给预测打分损失函数英文叫loss function是一个评价模型预测得好不好的函数。它输出一个数值数值越小代表预测越接近真实答案数值越大代表模型错得越离谱。模型训练的过程本质就是不断调整参数让这个数值不断下降。可以把它想象成考试评分。学生做一套题每道题都有标准答案评分规则告诉学生错多少、扣几分。模型也一样每个样本都有真实标签损失函数就是评分规则。只不过学生靠改错题提高成绩模型靠梯度下降调整参数来降低loss。选择损失函数并不是随便挑一个就行。分类、回归、排序、生成等不同任务优化目标不一样评测口径也不一样。用错损失函数轻则训练慢重则模型根本不收敛。过去我见过一个同学做二分类输出层用了sigmoid但损失函数直接套了均方误差结果训练半天loss下降缓慢准确率卡在60%附近上不去。这就是典型的“输出层与损失函数不匹配”。1.2 分类任务交叉熵为什么是默认选择分类任务里最常用的损失函数是交叉熵cross entropy。二分类场景下模型输出一个概率p表示样本属于正类的概率真实标签y是0或1。交叉熵公式长这样L -[y·log(p) (1-y)·log(1-p)]。你不需要硬记只需要看懂它的脾气当真实标签为1时p越接近1loss越接近0当真实标签为0时p越接近0loss越接近0。如果某个样本被分错了而且模型特别自信loss会变得非常大相当于重点扣分。很多新手会问为什么分类不用均方误差MSE原因有两点。第一分类模型的输出通常经过softmax或sigmoid处理带概率语义而MSE假设误差服从正态分布并不适合“概率有多大”这种约束。第二更关键的是梯度形状问题。用MSE加sigmoid误差较大时梯度反而可能很小模型学习得特别慢用交叉熵梯度项直接正比于预测与真实标签的差(p-y)误差越大修正力度越大。所以交叉熵成了分类任务的默认选择。多分类场景更常见的是softmax加交叉熵。网络输出logits也就是未归一化的得分先经过softmax转成各个类别的概率分布再计算真实标签分布与预测分布之间的交叉熵。逻辑上和二分类一脉相承只是把单个概率p扩展成一组概率。实际代码里尽量使用框架自带的高层接口而不是手动先算softmax再算交叉熵因为计算log时会遇到数值稳定性问题容易产生NaN。1.3 回归任务MSE、MAE、Huber怎么选回归任务的常见选择有三类MSE、MAE、Huber损失。先看MSE均方误差的形式是L (y - ŷ)^2。它对大误差特别敏感误差翻倍损失变成四倍适合需要重点惩罚大偏差的场景比如尺寸测量、坐标回归。缺点是数据里有离群点时单个异常点就能把模型拉偏。MAE平均绝对误差的形式是L |y - ŷ|。它对离群点的反应温和很多梯度恒定。但同样也存在问题当预测值接近真实值时梯度依然恒定模型容易在最优解附近来回震荡不容易收敛到特别精细的精度。Huber损失是两者的折中误差小于某个阈值delta时走MSE形式提供平滑二次修正误差大于阈值时走MAE形式限制离群点影响。实际项目中我会优先考虑Huber尤其是回归目标不太“干净”时。下面这张表把几个条件摆在一起方便对照选择损失函数对离群点敏感度梯度特点适合场景MSE高梯度随误差增大而增大无离群点、需要强惩罚MAE低梯度恒定关注中位数、数据含异常点Huber可控小误差二次、大误差线性综合场景多数回归选损失函数时还有一个容易被忽略的问题模型输出层要跟着损失函数走。回归模型输出层一般不加激活函数直接输出实数值二分类输出层用sigmoid多分类用softmax。如果输出层和损失函数不匹配底层计算会乱套。1.4 特定任务的专用损失函数选读这个部分不展开讲只列几个常见方向排序任务常用pairwise loss目标检测的回归分支常用Smooth L1图像分割经常用Dice loss提升小目标的分割效果不平衡分类场景还可以用Focal Loss让模型更关注难分类样本。小白阶段只要记住“不同任务有专门设计的损失函数”这个结论等真正碰到具体业务再去查就行不必一开始就全吞下去。2. 树结构/训练机制决策树到底在做什么2.1 树结构一串可以解释的if-else规则决策树之所以叫“树”因为它的结构像一棵倒挂的树最上面是根节点中间是内部节点末尾是叶节点。从根节点开始每次都问一个“是不是”的问题比如“年龄大于30吗”“是否点击过按钮”根据答案走向不同分支最终走到某个叶节点得到预测结果。举个例子判断一个人会不会购买某商品树可能是这样的根节点问“月收入大于8000吗”如果“否”走到“年龄小于30吗”继续问。每个内部节点都切一刀叶节点给出购买概率。这种结构最大的优势是可解释性强每一个判断都能用语言描述出来这也是树模型在很多风控、信贷场景中依然有市场的原因。另一个特点是树模型的决策边界是坐标轴平行的。什么意思你在二维平面里画点树每次分裂只按一个特征的阈值切一刀最后边界一定是水平和垂直的组合不会出现斜线。单独一棵树的拟合能力往往有限但如果把很多棵树组合起来就能逼近复杂边界。2.2 分裂时怎么选特征熵和基尼系数树在训练时最核心的问题是每个节点应该选哪个特征、按什么阈值切分才能让分类更“纯”。这里的“纯”指的是分裂之后叶节点尽量只包含一类样本。衡量不纯度的指标分类树常用两个信息熵和基尼系数。信息熵的计算是熵 -Σ p_i·log(p_i)p_i是第i类样本占比。两类分布是50%/50%时熵最大也就是最混乱100%/0%时熵为0也就是最纯净。基尼系数更简单基尼 1 - Σ p_i²。同样纯节点基尼为0五五开基尼为0.5。很多主流实现默认用基尼系数因为它没有log运算速度更快。分裂时树会计算每个特征按不同阈值切分后的加权不纯度选不纯度下降最大的方案。这个下降量就叫信息增益。回归树则不用熵或基尼而是用分裂后的均方误差下降来选特征每片叶子里装着训练样本的均值预测时直接输出这个均值。2.3 训练机制递归切分与防过拟合树模型的训练流程可以概括为递归切分从根节点开始对当前节点里的样本集合枚举所有候选特征和切分阈值找出让不纯度下降最多的方案然后切分成左右两个子节点再对每个子节点重复这个过程。一直切到某个停止条件才停下来比如节点样本数少于阈值、深度达到最大深度、信息增益小于某个值等。这个过程看起来简单实际操作中最大的坑是过拟合。树很容易越切越深最后把每个样本都单独放在一个叶节点训练集准确率看上去100%测试集却一塌糊涂。为了压制过拟合常见手段有预剪枝和后剪枝。预剪枝就是在分裂前判断是否值得继续分裂后剪枝是先让树长满再自底向上合并一些节点。工程上更常见的是直接限制树的深度、叶子最少样本数这些超参数简单有效。注意一点树结构对特征尺度不敏感。特征归一化、标准化对于神经网络的训练很重要但决策树的分裂逻辑只关心“按这个特征值切不切得开”单特征的阈值搜索不受其他特征范围影响。如果用的是纯树模型特征缩放可以不做但做集成模型或要和其他模型对比时还是要先做特征清洗和编码。2.4 从单棵树到集成Bagging和Boosting单一决策树容易过拟合一个重要的解决办法就是集成。集成学习有两大流派并行和串行。随机森林属于Bagging的典型它同时训练多棵相互独立的树每棵树在样本层面做有放回抽样在特征层面随机选择一部分特征最后分类任务投票、回归任务平均。这种做法的好处是每棵树虽然可能有些过拟合但大家犯错的方向不同平均之后可以把过拟合抵消掉一部分。另一个流派是Boosting代表是梯度提升树。它不再并行训练而是串行地“补差”。第一棵树先做初始预测算出样本的残差第二棵树去拟合这个残差第三棵树再拟合前两棵树剩余的残差这样每加一棵树就修正一次前面的错误。严格来说梯度提升树拟合的不只是普通残差而是损失函数的负梯度残差是平方损失下的特例。很多小白搞不清Boosting到底是“用树拟合什么”这里多说一句每一轮新树的目标是上一轮预测值对损失函数负梯度方向。有了这个目标无论损失函数是MSE还是交叉熵都能统一处理。整体模型可以写成F_m(x) F_{m-1}(x) ν·h_m(x)其中ν是学习率用来控制每棵树贡献的大小。看到这种式子先别慌下一节专门讲符号。3. 迭代符号含义epoch、batch、iteration到底在说什么3.1 一次迭代更新batch_size、iteration、epoch训练神经网络时训练日志里总会冒出一堆英文单词。先记住三者的关系batch_size是一次迭代喂给模型的样本数量iteration是完成一次前向传播、反向传播和参数更新的过程epoch是把训练集完整过一遍的轮数。它们之间有个简单公式一个epoch包含的iteration次数 训练样本总数 ÷ batch_size。因为最后一批可能不满所以通常需要向上取整。举个例子有1000张图片batch_size为100一个epoch就有10次迭代。如果你设定训练10个epoch总共就是100次参数更新。日志上每看到一次“epoch 5/10, iteration 50”意思就是整个数据集已经完整训练了5遍当前是这轮训练中的第50次小批量更新。每次iteration过后模型参数都会变一次。为什么不让所有数据一次算完直接更新一次一方面内存装不下另一个原因是小批量训练带来的随机噪声可以帮助跳出局部极小点泛化效果反而更好。但batch_size也不是越小越好太小了梯度抖动太大训练不稳定太大了又容易收敛到比较尖的极值点。实际中常用16、32、64、128这些值具体要根据模型的大小和显存灵活调整。3.2 学习率与训练日志中的其他符号除了迭代次数训练日志里最常见的就是lr也就是学习率。学习率控制每次参数更新迈多大一步公式可以简单写成“新参数 旧参数 - 学习率 × 梯度”。lr过大会振荡不收敛过小会训练极慢。很多框架支持让学习率随着训练轮数动态下降比如每隔一定epoch数乘以0.1这就是学习率衰减。还有warmup表示头几个epoch先用较小学习率预热再升到正常值主要是为了防止训练初期参数剧烈震荡。日志里还可能见到loss、acc、val_loss、val_acc。val_前缀代表验证集上的结果专门用来判断模型是否过拟合。如果训练loss持续下降验证loss却开始回升这就是典型的过拟合信号需要考虑提前终止、增强正则或减小模型容量。3.3 树模型中的迭代n_estimators和步长树模型里也有“迭代”概念只是说法不同。以梯度提升树为例迭代方式是一轮加一棵树。前面提到的模型公式F_m(x) F_{m-1}(x) ν·h_m(x)中m代表迭代轮数h_m是第m轮学到的弱学习器ν是步长/学习率。每迭代一次就多出一棵树。所以训练梯度提升树时最核心的超参数就是“树的数量”常用n_estimators或num_boost_round表示。这个数不是越大越好树太多模型会记住训练噪声一样过拟合。实践中常常同时限制最大深度和最小叶子样本数。还有一个常见符号是subsample或bagging_fraction表示每一轮迭代时随机抽取多少比例的样本参与训练。它起到类似随机森林降方差的作用能有效抑制过拟合。如果你看到某个配置里learning_rate为0.05、n_estimators为500大致可以推断这是通过增大迭代轮数、配合较小步长来拟合一个强模型。步长小、树多训练慢但效果好步长大、树少速度快但更容易过拟合。这种权衡要亲手调一遍才能体会。3.4 常见训练符号速查表这里整理一份常见迭代符号速查表建议先收藏。注意不同框架命名有差异使用前查文档确认。符号常见含义容易混淆点epoch数据集完整遍历一遍不是参数更新的次数batch_size每次迭代用的样本数量不是数据集总量iteration一次参数更新有时也被称为steplr / learning_rate学习率控制更新步长训练过程可动态变化n_estimators集成模型里的树数量不是每棵树的深度max_depth树的最大深度过深容易过拟合early_stopping_rounds连续多少轮指标不升后停止训练在验证集上生效每个符号背后都对应训练过程中的某个具体环节。刚开始不需要全部理解只看loss曲线和这几个核心超参数就够用了。很多项目跑不理想往往不是模型不够高级而是这些基础符号对应的设置出了问题。4. 常见问题与实操避坑4.1 损失函数选择速查把选择逻辑压缩成几个问题你是做分类还是回归分类用交叉熵回归先看数据是否有离群点没有用MSE有离群点用Huber或MAE。类别不均衡时分类损失可以加class_weight或改用Focal Loss多标签分类对每个标签单独算交叉熵再取平均。还有一个容易踩的坑不要在分类模型最后一层直接用softmax之后再手动去算交叉熵容易因为log数值稳定性出NaN。更稳妥的做法是使用框架提供的“logits softmax cross entropy”合并接口输入未归一化的得分内部会自动做稳定处理。4.2 树模型训练时常见的坑树模型用类别特征时如果类别数特别多直接做整数编码容易误导分裂需要考虑专门的类目编码方式。限制树深度的同时不要忘了设置最小叶子样本数两者配合才有效。用梯度提升树时样本量太小的数据集反而容易过拟合几百条以下的数据可以优先试试逻辑回归或简单线性模型不要一上来就堆很多树。还有一个经验树模型的训练结果和随机种子关系很大。如果某次跑出来效果很好换了一次却波动很大大概率是样本量少、模型方差高。这时候应该固定随机种子并多做几次交叉验证再下结论不要因为单次结果好就急着上线。4.3 迭代符号与训练日志的纠错很多人看训练日志容易懵为什么loss下降到一定程度开始震荡可能的原因有学习率太大、batch_size太小、数据顺序有偏。可以先降低学习率再看不要急着改模型结构。如果loss迟迟不降可能是特征没处理好或学习率太小。判断标准就一个训练集loss本身还有没有下降能力。如果训练loss都不降那是模型拟合能力不足的问题如果训练loss降了但验证loss不降那是过拟合的问题。这条经验可以筛掉大部分调参死角。用早停法时patience参数设多大合适太小了模型刚遇到正常波动就被打断太大了又浪费训练时间。常见做法是在验证集指标上设置20到50轮具体根据训练总轮数比例来定。这不是玄学是提前观察正常loss波动范围后得到的经验值。4.4 小白入门实操心得我自己的体会是不要一开始就在超长训练和超大模型上死磕。先拿一个小数据集用最简单的网络或一棵树跑通全流程打开训练日志一行一行把epoch、batch、loss对上号。再手动改一下损失函数观察loss曲线的变化。这个过程比刷十篇教程都管用。另外跑项目时先把代码里每一个参数的默认含义查清楚再开工。我以前因为把随机固定参数和树数量搞混训练出来的结果完全不可复现排查了半天才发现是随机种子没固定。基础符号这东西用的时候不查文档迟早会还回来。最后再分享一个小技巧训练笔记里永远记录三组数字——训练loss、验证loss和学习率。每次实验改了什么前后对比如何都记下来。很多看起来复杂的机器学习项目最终拼的就是对这些基础概念的敏感度。把损失函数、树结构和迭代符号这几块基础补牢之后后面看源码、看论文都会顺很多。