微信扫码
添加专属顾问
我要投稿
深入解析大模型如何引领AI走向通用人工智能(AGI)。 核心内容: 1. 大模型之前的算法演变与关键发展 2. 机器学习基础与深度学习范式 3. 预训练+微调范式与BERT和GPT的对比故事
大部分人都已经清楚什么是大模型(what),怎么用大模型(how),本文将尝试解答为什么是大模型(why)?大家都可以通过写 prompt 来和大模型对话,那大模型之前的算法是怎样的,算法世界经过了哪些比较关键的发展,最后为什么是大模型这条路线走向了 AGI,我会用两篇文章共5.7万字详细探索一下。
剧透一下本文的知识图谱如下:
东西稍稍有点多,为了方便理解,我会把它们分到三个章节并作为正文部分,分别对应上边的颜色逐渐加深的三簇。
文章结构如下:
文章结构
本文会按照下边四个章节展开:
图 0 章节目录
我们会在机器学习章节借助小程序分模型,介绍机器学习的基础工作比如特征工程、模型选择、训练、评价等等,这些工作类似第一行代码 hello world。
第二章我们会将机器学习平滑引入到深度学习的领域, 总结并深入深度学习的一个重要范式 embedding+MLP,比如因为RAG 的火热被人人熟知的 embedding,其实在深度学习中无处不在,同理还有MLP。本章会用一个具体的推荐场景介绍具体的模型细节,但是不慌,会搭积木就可以看的懂?。
第三章深度学习进入到预训练+微调的范式,算法工作变得简单且可迁移,介绍双胞胎 bert 和 gpt 的相爱相杀的故事.
最后附赠一个彩蛋。起因是农历新年和老婆看了一个电影,电影结束了老婆还在等彩蛋,用她的话说,“好电影都有彩蛋”。所以我也准备了一个,也可以直接跳到彩蛋,然后回来看前三章。
所以开始我们的边做边学之旅了。
所以我们第一个要学是“机器学习”。
机器学习:我的PD也是算法工程师
场景
一切从一杯咖啡开始。
今年 8 月份和 pd 一起喝了一杯咖啡,聊了下接下来要做的一个业务场景-如何给支付宝小程序打分,满分 100 分。
简单来说需要给优质的小程序打上高分,给低质量的打低分。小程序的质量有了客观评价分数后,运营同学就可以依此做分层,借助运营手段,促进开发者优化小程序质量,进而提升整体小程序的质量。
pd 已经想到了一种解法,选了几个和小程序质量相关的特征(为了方便理解我们只选取报错率和功能最佳体验两个特征,比较符合直觉:功能越齐备且报错越少的小程序体验更佳),并为每个特征设置了几个档位如下图:我们称之为评分表。
特征(feature) | 档位(bin) | 分数(score) |
报错率 | 档位 1 (报错率<=0.01) | 50 |
档位 2 (报错率>0.01) | 0 | |
最佳实践 | 档位 1 最佳实践(如提供更多功能) | 50 |
档位 2 中档体验 (如提供常见功能) | 30 | |
档位 3 较差体验 (功能不全) | 0 |
表 1 小程序评分表
通过这个评分表,我们可以根据具体小程序的特征及其对应的档位,将每个特征的得分进行汇总,从而计算出最终的总分。
我们用代表分数,x 代表特征(若命中某分桶则为 1,不命中则为 0),w 代表分档后的分数。简单公式如下:
,真实的特征可能是 n 个,公式可能稍微复杂点的求和公式如下:
。
模型自动化
然而实际设计的时候可能会遇到一些问题,比如:档位怎么拆分更科学,会很吃专家经验。 另外随着特征的增多,因为本质是一个求和公式,多个特征之间的档位得分怎么平分这 100 分,保证最后的分数更合理。
既然手动设计规则公式出力还不一定合理,那么这个我们不去干预,让机器(为了好理解,可以认为是运行的一段代码)帮我们自己产出一份更科学的算法公式替换我们的规则公式,或者换句话说,让模型识别到这个潜在的规则公式( 模式、规则 ),我们称这种偷懒的方式叫机器学习。
机器学习的概念非常广泛,我们将最基础的机器学习方法称为传统机器学习。随着神经网络的发展,深度学习(神经元足够多层数足够深的神经网络)作为机器学习的一个重要分支应运而生。而我们现在所熟知的大模型,更是深度学习的一个细分领域,后边我们会细讲。
所以他们的关系是机器学习> 人工神经网络>深度学习> 大模型是一个层级包含的关系。
认识模型
从数学角度来看,pd 的公式是一个线性方程,一般记为 f(x)=wx+b,为了方便理解我们将截距(也叫偏置)b隐藏。线性方程非常直观,假如f(x)=2x(w=2,b=0), 就是下图的那条红线:
图 2 线性函数
在这公式中有两个变量 x 和 w,数学中称x 为 自变量;w 为权重参数也叫参数,对,大模型中常说的 70b 参数就是指的就是有 700 亿个这种数据。
这里发现了第一个问题,即 x 和 w 一定是数字,不然怎么相乘呢。因为 x 本质上是代表了小程序的特征(feature),假如这个原始特征不是一个数字怎么办,我们了解自己的业务,所以可以提前做点工作将其转换成数字, 我们将这个转换成数字的过程可以称之为特征工程。
第二个问题接踵而至,机器怎么才能为每个特征x找到正确的w权重参数。假如啥也不告诉机器,机器肯定是无从下手的。我们把机器当做我们的助理,需要给它传输点经验,然后它才能自主的处理工作。不过这个机器学习助手要求不高,不太需要我们告诉他 why,只需要告诉它我们之前做过的 N 个具体的case 及我们对 case 的处理结果即可,他会自己总结出我们的做事逻辑(模型训练),听起来还不错对吧,有点 ai 的感觉了。
我们称这些 case 为样本,每条样本包含了case 的细节(我们做事的背景)+一个结果(我们做了什么,并称这个为 label)。 大模型场景下我们常听说的人工打标,打的就是这个 label。
假设上边两个问题都解决了,貌似我们就能拿到一个摸得着的具体的公式了比如f(x)=2x,怎么判断这个公式是不是准的呢,还需要一个专业测评阶段。测完发现 ok,可以上线了。部署上线后,后续用户的真实数据请求进来,只需要用相同的特征工程方法(比如训练用 0-男 1-女,此时也用相同方式)处理得到输入 x,直接代入公式就能求到结果,这个就是推理过程。
ok 万事具备开搞,我们已经知道了自己需要做:
6.上线,提供推理服务
模型视角下(我们假设每个特征只占据一个节点),模型及参数的变化过程:
图 3 参数随模型训练变化过程
现在我们 get 到了上边的流程图,训练现在就像一个黑盒,后边会详细解开其中的秘密。
算法思维切换
图 4 最简化的算法模式
上边的例子其实pd 已经潜移默化做了很多算法相关的工作,简单来说,分档(分档的本质是将连续特征转换离散特征)=特征工程,规则公式=算法模型。如果说机器学习=特征工程+算法模型,这么一看 pd 其实也是算法工程师了,事实上我们大家都离算法的世界很近。
借助上边的例子我们看一下算法的做法和常规的工程的做法的区别,借此切换我们的思维模式到算法模式。
图 5 算法和工程的区别
万物皆是 IO 系统,纯工程的逻辑是,理解需求然后写一个代码在线上 run 起来,针对用户的不同的请求给出不同的输出响应。前边我们总结出来算法逻辑是需要根据以往用户的输入(用我们的例子就是不同小程序的特征,做一下特征工程后得到数字化特征)+输出(不同小程序的分数)组成的样本一起给到算法模型进行训练,模型会分析出隐藏在数据背后的业务逻辑,代替了pd 设计规则需求+开发分析需求写代码的过程。
可以很容易看的出来,和工程的做法,算法逻辑稍微有点倒转了。
现在我们要去把这个算法模型的工作具体化了,之前我们分析出开发一个算法模型,需要特征工程、模型定义、模型训练、模型测评等步骤,接下来是时候细致的解开他们四个的面纱了。
开始实质算法工作
上边我们分析出的算法开发步骤对比下工程开发:
图 6 算法开发和工程开发的类比
1.选择模型:根据任务需求选择适合的模型,从很多模型中选一个适合的,比如我们之前选了一个线性模型。工程同学视角就是技术选型。
2.特征工程:准备和处理特征数据,包括特征选择、特征转换、归一化等,以适应并提高模型的表现。
3.训练模型:将处理好的特征数据输入模型进行训练,希望模型学习到数据中的规律和知识。 工程同学视角这两个步骤可以认为是我们的开发和自测阶段
4.评估模型:使用专业的评价标准来评测模型的表现。如果评测结果不令人满意,需要调整。 工程同学视角这个阶段可以认为是测试阶段
5.调整与优化:根据评估结果调整特征、模型架构、超参数等,反复进行训练和评估,直到达到预期的性能。工程同学视角,质量同学测试出来了 bug,我们修改下代码。
6.应用模型:一旦模型的表现ok,就可以发一个算法服务了。工程同学视角是相同的,终于完成质量验收了,上线生产。
再贴一下人类学习和机器学习的类比图,方便理解。
算法的世界其实一直只有数据和模型两个主角,特征工程就是我们为了让模型怎么更好的理解数据,中间做的一个桥梁。
我们用支付宝当面付的产品描述介绍下文本怎么提取特征,为了让模型更好的理解,所以我们要提前做下分词,方便模型学习。另外为了方便理解,分词我用我们熟知的汉语词组进行。
图 7 文本特征的常见方法
其中one-hot (图中扫码的表示是[1,0,0,0,0,0,0,0],这种形式在数学上称之为向量,向量中有一个位置是 1,所以叫 one-hot;如果多个位置是 1 则称之为 muti-hot,muti-hot一般用在同一主体多标签的场景,比如小程序可能有多个标签表达活跃度、是否 KA 等)方式目的是为了让模型感知到每个索引后的分词是不同的,不然 出示=1,付款码=2, 支付=3,模型会以为支付的含义=付款码+出示,它可最擅长做加法了。
如图 ont-hot 有一个致命问题就是,词表如果是 5w,那么每一个分词(token) 都会存在 49999个 0,这不仅导致存储空间的浪费,同时也使得计算效率低下。one-hot 避免了语义混淆, 但是做的太彻底,不同词之间毫无关系,就失去了表达语义的可能,比如猫和狗是相似的关系。
回到问题的本质,我们担心不同词之间的表达在相加或计算时,可能无法准确地反映其语义关系。但是如果可以呢?比如国王 - 男 + 女 ≈女王。
图 8 embedding 例子
这个例子体现了embedding的基本思想:我们不再只用 0 和 1 来表达数据,换成了更精确的数字,依此引入了丰富的语义表示。并显著压缩了向量的维度,比如上边的例子向量只有三维,对,embedding 本质是一个向量,重命名是为了区别普通向量并体现出这个压缩过程。
通过简单的数学计算,例如矩阵分解的方法,我们就可以拆分和压缩向量,得到 embedding,这个思路层广泛应用在协同过滤算法中,首先构建一个用户和商品的共现矩阵,通过矩阵分解就可以生成user和item的embedding,有了这个向量我们就可以做相似度计算了。当然 embedding也可以通过一个专门的算法模型来学习得到,后边会介绍 Word2Vec 和sentence embedding本质上都学习了大量的文本语料后,模型可以生成embedding表征(特征表示)。
embedding 虽好,通过上边的介绍也要知道其本质是对现实世界的压缩,凡压缩就可能有损耗,所以并不一定 100% 准确。
在这里,我们只介绍了文本模态数据的特征提取方式,而对于图像、视频等不同模态的数据,特征提取的方法会有所不同,多模态的特征提取会在第二章节详细介绍。
在提取完特征后,我们还可以进行重要特征的选择,例如,假设我们有 1000 个特征,可以从中挑选出与当前任务强相关的 100 个特征。
如果在第一步计算得出的特征在数值表达上不够显著,我们可以进行一些特征转换,如标准化、归一化、对数变换以及多项式变换(例如立方和平方,比如早期 youtube 会将用户的观看时间做平方,让模型更容易关注到这个特征,另外平方还带来了非线性)。此外,如果特征向量的维度过大,可以通过主成分分析(PCA)来提取主要成分,进一步压缩特征维度,以优化后续的模型训练和性能。
当然还可以通过对多个特征相乘等计算方式,无中生有一个新的特征出来,比如特征有年龄、收入,可以把年龄乘收入,用来捕捉到年龄和收入之间的复合关系,这种方式称之为特征交叉。
在我们的例子中,小程序具有多个特征。经过特征工程提取后,我们可以将这些特征转换为向量,并将它们简单拼接成一个更长的向量(比如城市2 维+类别 4 维 =最后就是一个 6 维的向量),作为一个整体表达整个小程序。
有了这个特征就可以作为输入给模型了。
在我们上一步的特征数据上加上一列 label ,我们称之为一条样本,当然也可以不加。加了 label 让模型照葫芦画瓢的叫监督学习,没有 label 让模型自己悟的叫无监督学习,比如聚类,把相似的数据聚集成一个的簇。偷个懒只给少部分打标,大部分不打标的叫半监督学习or 弱监督。
我们的场景监督学习,因为有 label 嘛。一开始,我们并不会自己设计模型,而是从机器学习的监督学习算法模型库中挑选出适合自己业务场景的模型进行使用,还好我们提前了解了下模型任务分为回归和分类两种,可以根据任务类型进一步缩减一下选择的范围。
分类很好理解,比如给了一堆图片,我们去区分哪些是猫,哪些是狗,哪些是卡皮巴拉。如推荐算法中的点击率预估就是一个比较常见的二分类场景,判断用户点击 1 不点击 0。如逻辑回归、svm、树模型都可以做。不同模型分类的方式不同,目标是一致的,想一个办法把两种数据隔离开。
图 9 不同分类算法的可视化
回归概念略抽象,其来自一个统计学的故事。数学家弗朗西斯·高尔顿通过分析 1078 对父亲与儿子的身高数据,发现了一个有趣的现象,儿子的身高倾向于“回归”到父亲身高的平均值,而不是完全继承父亲的极端身高。他将这种现象称为回归效应(Regression to the Mean),并基于此建立了线性关系模型 y=33.73+0.516x,用于预测子女的身高。其中,x表示父亲的身高,y表示儿子的身高。回归问题很多模型都已做,比如如线性回归、svm、树模型。
这里可以更通俗理解:可枚举的任务通常是分类,输出为离散标签;不可枚举的任务通常是回归,输出为连续数值。
我们确认了我们的场景是有监督,有监督算法模型很多,但是可以更细的看下。
线性关系:
在某些情况下,多个特征之间可能符合线性的关系(线性关系指的就是多个特征之间能否用线性方程描述,比如简单的一元一次方程),这种情况下可以使用线性模型,如线性回归、逻辑回归、岭回归等。按照pd 的假设我们可以选择这类模型。
决策树与集成方法
有时,我们可以通过 n 层 if-else 结构组成的决策树来实现所需的结果,这种树状结构直观地呈现为梯形。在更复杂的情况下,单棵树可能无法精准地解决问题,因此我们采用多棵树的集成方法。根据“三个臭皮匠顶个诸葛亮”的思路,使用多棵树的组合可以选择 Bagging(Bootstrap Aggregating)和 Boosting 两种策略来构建集成模型。前者生成随机森林,而后者涵盖了从 GBDT 到 XGBoost,再到 LightGBM 的演进。
非线性关系:
当特征之间的关系不符合线性假设时,线性模型可能无法很好地捕捉数据的复杂模式。在这种情况下,可以使用非线性模型,如支持向量机(SVM)中的核方法、K近邻(KNN)等。这些模型能够处理更复杂的决策边界,适合处理非线性可分的数据。
机器学习模型种类丰富,比如还有利用概率的贝叶斯算法,许多模型能够应对不同的场景。例如,树模型可以用于分类也可以用于回归,我们可以通过实验分析来比较不同模型的性能,以选择最优解。
粗看我们的场景是一个回归场景,通过小程序的不同特征然后决定最后的得分。但是问题是假如我们把场景设置成回归,就需要打标同学提前打标 N份数据,假设是 1000 个小程序+每个小程序的分数。这对打标同学来说是困难的,怎么凭直觉判断出每个小程序可能 1分甚至更小的差距在哪里。
所以我们换了个思路,打标数据变成了质量体感好的小程序和体感差的小程序,然后让模型去学习小程序成为优质小程序的概率(0,1二分类),从一个回归任务转成了分类任务。
我们选了逻辑回归模型作为算法模型,其公式可以理解:
左图:一开始 pd 的规则模型(算法化后是线性回归模型),但是线性回归计算出来数据可能是-n到 m 的,怎么将数据控制一下限制在[0,1],不要溢出。
右图:我们可以将上一步的结果再做一次数据变化,将最终数据压缩到 0-1,这个数据转换的工具叫做 sigmoid, 也叫logistic函数,sigmoid的作用就是把一个钢铁直男生生掰弯了,从 LR(Linear Regression)到 LR(Logistic Regression)仿佛什么都没变,仿佛什么都变了?。
在后续的深度学习章节,我们将根据神经网络的特性,为sigmoid 这类工具赋予一个更为广为人知的名称——激活函数。
图 10 从线性回归到逻辑回归
之前两步我们1.对打标的样本数据的输入部分做了特征工程,得到了数字化后的数据集。 2.然后选择一个线性模型,比如 LR 模型。接下来是时候让模型从这个数据集中总结学习到知识了。
模型训练的过程是有效学习输入特征与目标变量(label)之间的关系,并使模型具备良好的泛化能力。训练的目标是通过优化模型参数,让它能够准确预测新数据。通俗一点说,如果我们给定的样本,标签是 1,模型会对特征值进行一通计算(不管做什么吧,加减乘除想做什么做什么),最终得到结果也应该尽量接近 1。
这种无限接近的现象被称为拟合,但如果模型只是在记忆训练数据本身,而没有找到隐藏在数据背后的规律,我们称之为过拟合。比如学会了 1+1=2,我们问它 1+2 等于多少,它不会了。相对应地,泛化是指模型在未见过的新数据上也能保持良好预测性能的能力。训练后一个优秀的模型不仅要在训练数据上拟合得好,还应能够泛化到新样本,真正的捕捉到了数据的本质规律。
那么怎么评价模型是不是有泛化能力,数据只让他学一部分,剩下的看看它也能不能预测的准确,这里就涉及到了样本数据的拆分。
与工程测试不同,数据本身就是测试用例。为了评估模型的性能,我们需要将数据初步划分为训练集和测试集。训练集用于模型开发,而测试集用于上线前的最终测试(测试集是一定不能让模型学习的,不然就是提前泄题了)。进一步地,从训练集中再划分出验证集,用于模型开发过程中的自测和调优。
经过这两次拆分,最后数据集通常被分为三个部分:训练集、验证集和测试集。下图表达了这个拆分过程。
图 11 训练集、验证集和测试集
选择好训练集和验证集后,我们就可以训练模型了。训练之前,我们有些参数我们可以干预下,这些参数可以控制学习的速度和性能,我们称之为超参数。超参数可以理解为非模型通过学习到的参数(比如我们一开始提到的权重参数w),是人工可以干预的参数集合。
为了简化理解只举 4个超参数:
学习轮次:学习轮次可以类比为练习某个技能的次数。练习的次数越多,我们可能掌握得越熟练,不过不是越多越好,就像我们幼时背古诗背 100 遍,并没有理解其中的意境,直接脱口而出,可能是过拟合了。
批次大小:学习知识时,每次分章节学习,不会一次学完。机器学习一般都是小批次多 epoch 的训练方式
学习率:学习新技能时,我们的学习速度就是学习率。如果学习速度太快,可能学得不够扎实,容易犯错;如果学习速度太慢,可能需要更长的时间才能掌握技能。学习率是和优化算法配合一起的。
优化算法:优化算法就像是学习新技能时,我们使用的学习方法。不同的方法可以有不同的效果。例如,有的方法可能会让我们更快地掌握技能,有的方法则可能让我们更扎实地掌握技能。有很多的优化算法,优化过程更形象化的样子是,更快的走到谷底,不同的优化算法有不同的路线,优化速度也不尽相同。
图 12 优化算法
损失函数:损失函数一般不认为是超参数,但是为了方便整体理解,我也贴在这里了。损失函数可以类比为考试或测验,每次考试的结果都可以反映出我们与正确答案之间的差距。这个差距(loss)越小,说明学习效果越好。不同的场景一般选择不同的损失函数。比如回归场景常用均方误差(MSE),二分类常用交叉熵损失(Cross-Entropy Loss)。
图 13 配置超参数训练模型
学习的过程其实就像教小孩做题:我们把题目(数据)分成一小堆一小堆的(batch)。模型每学完一堆,就会做个“小测验”(计算 loss),看看自己错哪儿了。然后,优化算法就像个“老师”,根据错误的大小(loss)和学习进度(学习率),告诉模型该怎么调整自己的“思路”(参数)。学完一堆,再学下一堆,直到把所有题目都学完一遍(1 epoch)。如果觉得学得还不够,就再来几轮(n epoch),直到模型学明白。
在机器学习领域,模型通过迭代学习过程不断优化其内部参数,以减少预测误差。超参数的调整,包括但不限于上边的几个参数,是算法同学的比较重要的工作。调参费时费力,因为多个参数本质上是一个笛卡尔积,有些自动调参技术如网格搜索和随机搜索等也被辅助用于寻找最优的超参数组合。
具体来说,一个理想的模型应该能够在训练集上表现好,也要通过测试集的考验。不然就有可能偷懒--欠拟合,死记硬背--过拟合。
图 14 真实数据分布、欠拟合、拟合、过拟合
既然训练会有各种问题,比如过拟合和欠拟合,需要在训练阶段要科学的全面测试。没有好的办法,多实验几遍,当然重复可以以更科学的方式进行---交叉验证(Cross-Validation),特别是k-fold交叉验证,是一种统计学方法,类似于我们熟知的滑动窗口。
通过k-折交叉验证,我们可以观察模型在不同训练集上的性能变化。如果这些性能度量相差不大,那么我们就可以认为模型具有好的泛化能力。
图 15 k 折训练,分片后遍历训练,最后评价
假设我们已经训练好了模型,并且观察到损失函数(loss)在不断降低,这时可能会产生一个疑问:仅仅依靠损失值来评估模型的好坏是否足够科学?
loss 表达了模型自己觉得自己好了,我们要用更直观的方式去看下。例如,在工程角度,质量同学会提前准备比如 100 个测试用例(test case),测试过程中通过 bug 率来判断本次需求的开发质量。我们之前提到过,在算法场景下测试用例实际上就是提前准备的一些样本,因此从具体样本的角度来看,模型的表现如何,可以通过计算正确预测和错误预测的比例来更直观地反映模型的性能。
这样,我们可以更全面地假设模型在实际应用中的表现。
没有人比质量同学更懂测试了,所以我们用质量同学的角度来看算法的几个核心指标是怎么来的。
在做测试分析阶段,质量对当前需求的细致分析后,用思维导图分析出来 N 个 case。但是这些 case 可以继续拆分一下,比如根据是不是正向的 case,分成正向用例和负向用例。前者表达了期望成功的的正常用例,后者期望失败的例如边界异常用例,系统能拦截并提醒报错。
用质量同学用例的预期情况(称为实际)和工程开发的代码处理(称为预测)就有了四种可能(T和 F 代表 true 和 false 是否预测成功,P 和 N 代表Positive和Negative 预测的是正负,比如 TP 代表一个正样本正确被预测了,FN 代表错误的预测成了负样本,代表一个原本正样本被错误预测了,这块稍微有点绕,可以自己稍微思考一下),我们按照下边的图组织下,直观表达预测有没有混淆真实情况,所以称之为混淆矩阵。
图 16 混淆矩阵(Confusion matrix)
机器学习指标 | QA 测试用例类比 | 解释 |
真阳性 (TP) | 正向测试用例,代码通过(Pass) | 正向测试用例按预期通过,表示代码正确处理了这些正常输入。 |
真阴性 (TN) | 负向测试用例,代码拦截(Fail) | 负向测试用例按预期失败,表示代码正确地拒绝或处理了异常或非法输入。 |
假阳性 (FP) | 负向测试用例,代码未拦截(Pass) | 负向测试用例意外通过,表示代码未能正确处理异常或非法输入,存在缺陷。 |
假阴性 (FN) | 正向测试用例,代码拦截(Fail) | 正向测试用例意外失败,表示代码未能正确处理正常逻辑,存在缺陷。 |
准确率是指模型预测正确的样本数与总样本数的比例,一般简称为 ACC。在测试场景,1-acc 就是质量比较关注的 bug 率,代表了本次提测的质量。
我们也可以借助 acc 和 loss 来识别下模型是否过拟合。如果在训练集上表现越来越好,验证集不怎么升高或者降低了,那么就要考虑模型训练过拟合了,其后边的 AUC 等指标也是一样的道理,要多个指标一起看一下。
图 17 acc 和 loss 一起判断模型的表现
不足:假设质量同学准备了 100 个 case,其中有 95 个正向的只有 5 个 负向的。负向的即使不符合预期,正向流程都表现的很好,最后这个指标也会很高,但是负向的 case一旦没拦住,发上线又会影响较大,还是想办法关注到这个指标,比如可以用特异性。
有的场景我们很关注负向的 case,希望异常情况都能被提前识别。那么特异性这个指标,专注于看负向的测试用例中,真正被识别拦截的概率。
既然可以专注负向用例是不是可以专注正向用例,后者就是我们常听说的召回率。
召回率 (Recall) 是实际为正类别中被正确预测为正类别的比例。
我们的小程序场景就是质量高小程序被识别称高质量的比例,较高的召回率意味着我们没有漏掉太多实际高质量的小程序。高召回率在内容推荐场景,可以理解为用户提供尽可能全面的内容,确保他们不错过任何可能感兴趣的内容,比如抖音内容的推荐。
单看这个公式,如果我们只需要把 FN 降低,同时保持住 TP,就可以带来召回的提升。努力让正向的用例通过,同时把没有通过的正向用例修复掉,改了 bug 不带来新的 bug,这个指标就提升了。
仅关注召回率可能导致系统变得过于宽松,因为没关注负向用例,可能允许大量负向测试用例通过(FP),即无法正确识别和拦截这些异常或非法输入。如果考虑一下 FP,拦截负向异常case,先不管失败的正向 case FN 。这就是精确率。
精确率 (Precision) 是预测为正类别中实际为正类别的比例
解释:要想提高精确率就要想办法降低 FP,在我们的小程序分场景高精确率意味着模型会尽量避免将低质量的小程序误判为高质量。
不足:在某些情况下,追求更高的精确率可能导致召回率下降,因为模型可能会更保守,不愿犯错(不愿意将某些不太确定的小程序标记为高质量)。
我们会发现依赖单一指标总会有不足,很容易拆东墙补西墙。所以为了更全面的性能评估,会用一些综合性的指标来看。
既然召回率和精确率都挺重要的,那么和个稀泥。F1 为了调和精准率和召回率, 其思想来源于数学里的调和平均数。F1分数高即模型在这两个方面表现都比较均衡。
与F1-Score(只考虑了TP、FP、FN,召回率和精确率只用了这三个指标)相比,MCC考虑了所有四个混淆矩阵的方面(TP、FP、TN、FN),提供了一个更全面、更均衡的衡量。因此,在需要综合考虑所有类型的预测结果和处理不平衡数据集时,MCC可以说是一种比F1-Score更稳健的性能度量方法。
a.如果正样本的分数高于负样本,计为✅。
b.如果负样本的分数高于正样本,计为❌
c.如果两者相等,可以视为“中立”或按一定规则处理,比如偏向于❌。
import torchimport torch.nn as nnimport torch.optim as optimimport pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom torch.utils.data import DataLoader, TensorDataset# 使用GPU 如果无使用 CPUdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 加载小程序数据集data = pd.read_csv('mini_program_data.csv')# 提取特征和标签X = data[['completeness', 'error_rate']].values # 特征列y = data['label'].values # 标签列(优质与否)# 特征标准化scaler = StandardScaler()X = scaler.fit_transform(X)# 划分训练集和验证集X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)# 转换为 PyTorch 张量X_train_tensor = torch.tensor(X_train, dtype=torch.float32).to(device)y_train_tensor = torch.tensor(y_train, dtype=torch.float32).view(-1, 1).to(device)X_val_tensor = torch.tensor(X_val, dtype=torch.float32).to(device)y_val_tensor = torch.tensor(y_val, dtype=torch.float32).view(-1, 1).to(device)# 创建 TensorDataset 和 DataLoaderbatch_size = 32 # 设置批次大小train_dataset = TensorDataset(X_train_tensor, y_train_tensor)train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)# 定义逻辑回归模型class LogisticRegressionModel(nn.Module): def __init__(self, input_dim): super(LogisticRegressionModel, self).__init__() self.linear = nn.Linear(input_dim, 1) def forward(self, x): # 使用sigmoid return torch.sigmoid(self.linear(x))# 初始化模型、损失函数和优化器input_dim = X_train.shape[1]model = LogisticRegressionModel(input_dim).to(device)criterion = nn.BCELoss() # 二元交叉熵损失optimizer = optim.SGD(model.parameters(), lr=0.01) # 随机梯度下降优化器,学习率 0.01# 训练模型num_epochs = 100for epoch in range(num_epochs): model.train() # 设定为训练模式 for batch_X, batch_y in train_loader: # 使用 DataLoader 进行批次训练 optimizer.zero_grad() # 清零梯度 # 前向传播 outputs = model(batch_X) loss = criterion(outputs, batch_y) # 反向传播和优化 loss.backward() optimizer.step() if (epoch + 1) % 10 == 0: # 每10个epoch输出一次损失 print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')model.eval() # 设定为评估模式with torch.no_grad(): val_outputs = model(X_val_tensor) predicted = (val_outputs > 0.5).float() # 使用0.5作为阈值进行分类 # 计算准确率和F1分数 accuracy = accuracy_score(y_val_tensor.cpu(), predicted.cpu()) f1 = f1_score(y_val_tensor.cpu(), predicted.cpu()) print(f'Validation Accuracy: {accuracy:.2f}') print(f'Validation F1 Score: {f1:.2f}')
总结
美好假设
深度学习:会搭积木就可以开发算法模型
场景
从机器学习到深度学习
万能的MLP
class MLPModel(nn.Module):
def __init__(self, input_dim):
super(MLPModel, self).__init__()
self.fc1 = nn.Linear(input_dim, 64) # 第一层,输入到隐藏层
self.fc2 = nn.Linear(64, 32) # 隐藏层
self.fc3 = nn.Linear(32, 1) # 隐藏层到输出层
self.activation = nn.ReLU() # 使用 ReLU 激活函数
def forward(self, x):
x = self.activation(self.fc1(x)) # 第一层前向传播
x = self.activation(self.fc2(x)) # 第二层前向传播
return torch.sigmoid(self.fc3(x)) # 最后一层Sigmoid激活
搞科研
交叉模型
突然不那么万能的MLP
学成归来,重新做推荐
怎么给用户历史访问的商品列表做特征工程呢,比如用 muti-hot,显然体现不出来用户访问的时序,用户的兴趣是稍纵即逝的,所以还是想办法,专门对历史数据做一下兴趣提取。
注入更多的知识
停下来稍作总结
我们的实践
美好假设
每次有了需求都要重新训练一个模型,是不可以存在一个基础模型,它具有基本认知能力,等新任务来了,只需要稍加训练(迁移学习)就可以快速适应新任务,真正的做到重复使用。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-03-10
【一文看懂】大白话解释大模型的技术原理,为什么它那么聪明?
2025-03-10
【一文看懂】7B、175B,这些大模型参数是什么意思?它们是怎么算出来的?参数越多=模型越强?
2025-03-10
大模型领域常用名词解释(近100个)
2025-03-10
大模型应用联网搜索:重塑智能时代的交互与决策
2025-03-10
MCP:为 AI Agent 打造开放与互操作性的“超级接口”
2025-03-10
QwQ-32B,支持Function Call的推理模型,深度思考Agent的时代来了!
2025-03-10
国产自强!实在Agent+DeepSeek+华为昇腾一体机重磅发布!
2025-03-10
1次搭建完胜1亿次编码,MCP硅谷疯传!Anthropic协议解锁智能体「万能手」
2024-08-13
2024-06-13
2024-09-23
2024-08-21
2024-05-28
2024-07-31
2024-08-04
2024-04-26
2024-07-09
2024-09-17
2025-03-10
2025-03-10
2025-03-10
2025-03-10
2025-03-08
2025-03-08
2025-03-07
2025-03-07