Step by Step实现RAG

LLM

RAG(Retrieval and generation)技术可以扩展大模型的知识库,用来回答我们特定问题,这里我们Step by Step 实现RAG技术。

GBDT核心源码解析

Coding, Machine Learning

【文章发布的比较早,新版sklearn已经使用Rust重写了,只能用来凑热闹了】 sklearn中对GBDT的实现是完全遵从论文 Greedy Function Approximation的,我们一起来看一下是怎么实现的。GBDT源码最核心的部分应该是对Loss Function的处理,因为除去Loss部分的代码其他的都是非常直觉且标准的程序逻辑,反正我们就从sklearn对loss的实现开始看吧~~ Loss Function 的实现 以二分类任务为例,loss采用Binomial Deviance,看这个loss很陌生,其实跟我们熟悉的negative log-likelihood / cross entropy 是一回事,因为是二分类问题嘛,模型最终输出其实就是$P(y=1|x)$,即样本$x$是正例的概率,我们把这个概率标记成$p(x)$,那么Binomial Deviance等于 $$\ell(y, F(x)) = -\left [ y\log(p(x)) + (1 – y)\log(1-p(x)) \right […]

XGBoost自定义目标函数

Coding, Machine Learning

xgboost内置了足够丰富的目标函数(objective function),正常来说是能够应付日常需求的,如果~万一~你有特殊需求,它也可以自定义目标函数,或者叫损失函数(loss function),这里介绍下怎么自定义目标函数。

DeepFM

Machine Learning

之前记录了FM,大概在座的各位已经想到后面会聊DeepFM,纵然FM到DeepFM中间隔了众多经典算法,为了照顾直觉上的感受,还是说下DeepFM。 DeepFM也是一种wide&deep形式的模型,模型同时考虑低阶和高阶的特征组合,FM部分负责低阶的特征组合,deep部分负责高阶特征组合。 1.总结构 相信这个图你也看吐了,于是我们还是重新画一下吧.. 这样看起来有没有很清晰~~简直清晰到家了~~~非常稀疏的高纬特征$x$输入到模型,Embedding层他们处理成稠密的低纬特征$D$,之后送入FM部分和Deep部分,这样FM部分输出的结果:  $$out_{FM} = FM(D)$$ Deep部分的输出: $$out_{Deep} = Deep(D)$$ 模型最终的输出 $$out = out_{FM} + out_{Deep}$$ 整个模型的参数,包括Embedding层的weights是一起更新,大概因为Embedding层不光得考虑底阶的特征组合,还得考虑高阶的,所以会有更好的特征表达。 2.输入层+Embedding层 输入层是onehot的特征,每个颜色表示一个field,这个field中的每维数据只跟上面Embedding层的对应field的神经元链接,全链接操作。这样,每个field都会embedding到一个固定长度的向量,这个向量的长度在FM中标记为$k$。 绿色的特征只跟绿色的神经元链接~绿色神经元输出的4个值就是绿色这个field的Embedding向量。 我们看下这个神经元的操作: 这绿色,还真是生机盎然的颜色~ 绿油油的,深绿色那个是1,其他浅绿色都是0,所以这个神经元只有$w_6$留下了,之后其他三个绿色神经元也只有他们的$w_6$留下。 按照这个思路实际上,每个field中只有一个为1的参与实际运算,其他都是打酱油的,于是我们很多model的Input到Embedding代码实现,是直接使用框架的Lookup Table,比如[pytorch的Embedding层]。 如果使用torch.nn.Embedding来实现,还节省了将类别特征onehot的操作,框架直接随机生成$\text{field_length} […]

FM算法

Base, Machine Learning

为啥要聊FM呢,因为它设计很优雅~而且工程实现上有简化技巧,实现起来也很优雅,之后在FNN/DeepFM/xDeepFM都扮演者重要的角色。 Logistic Regression(LR)模型只能学习特征的线性表达,线性部分: $$\hat{y} = w_0 + \sum_{i=1}^{n}w_i x_i$$ 为了能让他具有非线性能力,工程师会根据自己对业务的理解手动进行特征组合,比如$x_{city} \cdot x_{age}$这样模型就能学习年龄和城市的组合情况,比如(城市=北京,年龄=12),在学习过程中就能学习“北京地区12岁的小孩”会怎么怎么着,这样手动的特征组合还是太消耗精力了,一个可以想到的思路是: $$\sum_{i=1}^{n}\sum_{x=1+1}^{n}w_{ij}x_i x_j$$ 不管3721就直接把每个维度的特征都给它组合起来,这样也不是不行,但是这样有一个致命的缺陷——稀疏,大概是制约模型的最大因素吧。我们有很多categorical feature,这些特征一般会经过onehot处理,比如城市有600多个,那么仅仅城市一个特征就要用600维的向量来表达,其中只有一个1,其他599个都是0,着599维根其他特征组合之后又是0,所以引入特征组合之后,使原本稀疏的特征更加稀疏~大概比30岁程序员的头发还稀疏~ FM(Factorization Machines)就是来解决这个问题的,FM不是用一个常数$w_{ij}$来表达$x_i$和$x_j$的权重,它用一群常数来表达~每一维的特征$x_i$都分配一个权重向量$\textbf{v}_i$,这样两维特征要组合的时候用他们各自的权重向量的内积作为他们俩的权重,所以$x_i$和$x_j$组合后是$\left \langle \textbf{v}_i, \textbf{v}_j \right \rangle x_i x_j$ 尖括号是算内积 $$\left \langle […]