diff --git a/README.md b/README.md index a6254fd..1de89a2 100644 --- a/README.md +++ b/README.md @@ -739,6 +739,9 @@ $$ - 决策树剪枝、限制树的深度 3. 加入正则化项(L1或L2)或提高惩罚系数 4. 使用集成学习 +5. 神经网络中使用dropout机制 +6. early stopping +7. 标签平滑 @@ -1006,6 +1009,8 @@ $$ 缺点:无法识别出两个不同的词或者词组具有相同的主题。 +**TF-IDF** + **N-gram模型**:将连续出现的n个词(n<=N)组成的词组也作为一个单独的特征放到向量表示中。 缺点:无法识别出两个不同的词或者词组具有相同的主题。 @@ -1193,6 +1198,17 @@ $$ +**汉明距离** + +两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数 + +1011101 与 1001001 之间的汉明距离是 2。 + +2143896 与 2233796 之间的汉明距离是 3。 + +"toned" 与 "roses" 之间的汉明距离是 3。 + + 5.**相关系数**(correlation coefficient) 相关系数的绝对值越接近1,表示样本越相似;越接近0,表示样本越不相似。 @@ -1678,9 +1694,17 @@ $$ #### **线性回归** - [ ] [2-5-1 线性回归的基本思想是?](#2-5-1) + - [ ] [2-5-2 什么是“广义线性模型”?](#2-5-2) + + 考虑单调可微函数 $g(\cdot)$,令 $g(y)=\overrightarrow{\mathbf{w}}^{T} \overrightarrow{\mathbf{x}}+b$,这样得到的模型称作广义线性模型 (`generalized linear model`)。其中函数 $g(\cdot)$ 称作联系函数 (`link function`) 。 + + + - [ ] [2-5-3 线性回归常用的损失函数有哪些?优化算法有哪些?](#2-5-3) + - [ ] [2-5-4 线性回归适用什么类型的问题?有哪些优缺点?](#2-5-4) + - [ ] [2-5-5 请用最小二乘法推倒参数更新公式?](#2-5-5) @@ -1713,7 +1737,7 @@ $$ - [ ] [2-6-2 逻辑回归和广义线性模型有何关系?](#2-6-2) -可以看做广义线性模型在因变量y服从二元分布时的一个特殊情况 +可以看做广义线性模型在因变量y服从二元分布时的一个特殊情况。 - [ ] [2-6-3 逻辑回归如何处理多标签分类?](#2-6-3) @@ -1854,7 +1878,13 @@ L1正则项约束后的解空间是多边形,而L2正则项约束后的解空 **从函数叠加的观点:** +- [ ] 权重衰减(L2正则化的作用) + + **作用**:权重衰减(L2正则化)可以避免模型过拟合问题。 + **思考**:L2正则化项有让w变小的效果,但是为什么w变小可以防止过拟合呢? + **原理**:(1)从模型的复杂度上解释:更小的权值w,从某种意义上说,表示网络的复杂度更低,对数据的拟合更好(这个法则也叫做奥卡姆剃刀),而在实际应用中,也验证了这一点,L2正则化的效果往往好于未经正则化的效果。(2)从数学方面的解释:过拟合的时候,拟合函数的系数往往非常大,为什么?如下图所示,过拟合,就是拟合函数需要顾忌每一个点,最终形成的拟合函数波动很大。在某些很小的区间里,函数值的变化很剧烈。这就意味着函数在某些小区间里的导数值(绝对值)非常大,由于自变量值可大可小,所以只有系数足够大,才能保证导数值很大。而正则化是通过约束参数的范数使其不要太大,所以可以在一定程度上减少过拟合情况。 + ![img](https://img-blog.csdn.net/20180630161619869?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3Byb2dyYW1fZGV2ZWxvcGVy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) - [ ] [2-6-8 使用交叉熵作为损失函数,梯度下降作为优化方法,推倒参数更新公式](#2-6-8) @@ -2138,11 +2168,46 @@ Boosting通过模型集成降低偏差,提高弱分类器的性能。 - [ ] [2-10-7 如何防止GBDT过拟合?](#2-10-7) +1. 在工程应用中,通常利用下列公式来更新模型: $f_{m}(\overrightarrow{\mathbf{x}})=f_{m-1}(\overrightarrow{\mathbf{x}})+\nu h_{m}\left(\overrightarrow{\mathbf{x}} ; \Theta_{m}\right), \quad 0<\nu \leq 1$。 + + 其中 $\nu$ 称作**学习率**。 + + 学习率是正则化的一部分,它可以降低模型更新的速度(需要更多的迭代)。 + + - 经验表明:一个小的学习率 ($\nu<0.1$) 可以显著提高模型的泛化能力(相比较于$\nu=1$ ) 。 + - 如果学习率较大会导致预测性能出现较大波动。 + +2. `Freidman` 从`bagging` 策略受到启发,采用**随机梯度提升**来修改了原始的梯度提升树算法。 + + - 每一轮迭代中,新的决策树拟合的是原始训练集的一个子集(而并不是原始训练集)的残差。 + + 这个子集是通过对原始训练集的无放回随机采样而来。 + + - 子集的占比 $f$ 是一个超参数,并且在每轮迭代中保持不变。 + + - 如果 $f=1$ ,则与原始的梯度提升树算法相同。 + - 较小的$f$ 会引入随机性,有助于改善过拟合,因此可以视作一定程度上的正则化。 + - 工程经验表明, $0.5 \leq f \leq 0.8$会带来一个较好的结果。 + + - 这种方法除了改善过拟合之外,另一个好处是:未被采样的另一部分子集可以用来计算包外估计误差。 + + 因此可以避免额外给出一个独立的验证集。 + +3. 梯度提升树会**限制每棵树的叶子结点包含的样本数量至少包含 $m$ 个样本**,其中 $m$为超参数。在训练过程中,一旦划分结点会导致子结点的样本数少于 $m$,则终止划分。 + + 这也是一种正则化策略,它会改善叶结点的预测方差。 + - [ ] [2-10-8 在训练过程中哪些参数对模型效果影响比较大?这些参数造成影响是什么?](#2-10-8) + 减小步长需要对应增加最大迭代次数 + + 1) **n_estimators**: 也就是弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是100。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。 + + 2) **learning_rate**: 即每个弱学习器的权重缩减系数νν,也称作步长,在原理篇的正则化章节我们也讲到了,加上了正则化项 + 3) **subsample**: 即我们在原理篇的正则化章节讲到的子采样,取值为(0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在[0.5, 0.8]之间,默认是1.0,即不使用子采样。 #### **k-means** @@ -2468,6 +2533,12 @@ kmean的总体特点 - [ ] [3-1-3 梯度消失和梯度膨胀的原因是什么?有什么方法可以缓解?](#3-1-3) + (1)深度学习的网络层数太多,在进行反向传播时根据链式法则,要连乘每一层梯度值 + + (2)每一层的梯度值是由,非线性函数的导数以及本层的权重相乘得到的,这样非线性的导数的大小和初始化权重的大小会直接影响是否发生梯度弥散或者梯度爆炸 + + 注:任何网络都有可能发生梯度弥散或者梯度爆炸,这是深度学习的基本性质决定的,无法避免。 + 梯度消失(梯度弥散)的原因: 解决方法: @@ -2574,7 +2645,7 @@ $$ - [ ] [3-1-6 写出常用激活函数的导数](#3-1-6) -见上 +![](https://cdn.mathpix.com/snip/images/lch_19BxC77kvBQ20p3no_Z71liDpIIAvdPnxoYWoYA.original.fullsize.png) - [ ] [3-1-7 训练模型的时候,是否可以把网络参数全部初始化为0?为什么](#3-1-7) @@ -2620,7 +2691,7 @@ CNN通过卷积层+pooling层不断堆积,从小的pattern开始不断识别 average-pooling,Max-polling,stochastic-polling(对输入数据中的元素按照一定概率大小随机选择,元素值大的activattion被选中的概率大) -Pooling操作后的结果相比起输入减小了,是一种降采样操作。 +Pooling操作后的结果相比起输入减小了,是一种**降采样**操作。 pooling层的作用 @@ -2631,7 +2702,33 @@ pooling层的作用 - [ ] [3-2-6 为什么CNN需要pooling操作?](#3-2-6) + + + - [ ] [3-2-7 什么是batchnormalization?它的原理是什么?在CNN中如何使用?](#3-2-7) + + 为了解决内部协方差偏移(ICS)问题提出的。高层网络需要不断适应底层输出的分布,导致 + + 对于某一层某个神经元d维输入$\mathrm{x}=\left(x^{(1)} \ldots x^{(d)}\right)$,对每一个维度进行批标准化 + $$ + \widehat{x}^{(k)}=\frac{x^{(k)}-\mathrm{E}\left[x^{(k)}\right]}{\sqrt{\operatorname{Var}\left[x^{(k)}\right]}} + $$ + ![1567511107747](C:\Users\Kevin\AppData\Roaming\Typora\typora-user-images\1567511107747.png) + + ![1567511156114](https://cdn.mathpix.com/snip/images/3nV904o42ao1MH6C2EGrKbM59gU5lXNzzy5TFJ5Le_w.original.fullsize.png) + + + + **BN训练和测试的区别** + + 先说结论:并不是测试时的mean,var的计算方式与训练时不同,而是测试时的mean,var在训练完成整个网络中就全部固定了。 + + 由于在优化网络的时候,我们一般采用的是batch梯度下降。所以在训练过程中,只能计算当前batch样本上的mean和var。但是我们做的normalization是对于整个输入样本空间,因此需要对**每个batch**的mean, var做**指数加权平均**来将batch上的mean和var近似成**整个样本空间**上的mean和var. + + 而在测试Inference过程中,一般不必要也不合适去计算测试时的batch的mean和var,比如测试仅对单样本输入进行测试时,这时去计算单样本输入的mean和var是完全没有意义的。因此会直接拿训练过程中对整个样本空间估算的mean和var直接来用。此时对于inference来说,BN就是一个线性变换。 + + + - [ ] [3-2-8 卷积操作的本质特性包括稀疏交互和参数共享,具体解释这两种特性以其作用?](#3-2-8) **稀疏交互**:每个神经元的只跟上一层的某些神经元连接(vs DNN全连接),用到较少参数 @@ -2653,15 +2750,28 @@ $$ x^* = \mathop{arg \ \rm max}\limits_{x} \ a^k $$ +- [ ] [resnet skip-connection]() -#### **RNN** + 假如,我们在这个block的旁边加了一条“捷径”(如图5橙色箭头),也就是常说的“skip connection”。假设左边的上一层输入为x,虚线框的输出为f(x),上下两条路线输出的激活值相加为h(x),即h(x) = F(x) + x,得出的h(x)再输入到下一层。 -- [ ] [3-3-1 简述RNN模型原理,说说RNN适合解决什么类型问题?为什么](#3-3-1) + - RNN能够很好地处理文本数据变长并且有序的输入序列。它模拟了人阅读一篇文章的顺序,从前到后阅读文章中的每一个单词,将前面阅读到的有用信息编码到状态变量中去,从而拥有一定的记忆能力,可以更好地理解之后的文本。 + ![img](https://pic2.zhimg.com/v2-79e9feb7ee38f64c6cc15c501327b7bd_b.jpg) + + 图6 + + 当进行后向传播时,右边来自深层网络传回来的梯度为1,经过一个加法门,橙色方向的梯度为dh(x)/dx=1,蓝色方向的梯度也为1。这样,经过梯度传播后,现在传到前一层的梯度就变成了[1, 0.0001, 0.01],多了一个“1”!**正是由于多了这条捷径,来自深层的梯度能直接畅通无阻地通过,去到上一层,使得浅层的网络层参数等到有效的训练!** +#### **RNN** + +- [ ] [3-3-1 简述RNN模型原理,说说RNN适合解决什么类型问题?为什么](#3-3-1) + + RNN能够很好地处理文本数据变长并且有序的输入序列。它模拟了人阅读一篇文章的顺序,从前到后阅读文章中的每一个单词,将前面阅读到的有用信息编码到状态变量中去,从而拥有一定的记忆能力,可以更好地理解之后的文本。 + + 不定长;下一时刻的状态于当前输入以及当前状态有关 + - [ ] [3-3-2 RNN和DNN有何异同?](#3-3-2) 相同点:一个长度为T的序列用xun @@ -2670,7 +2780,7 @@ $$ - [ ] [3-3-3 RNN为什么有记忆功能?](#3-3-3) - RNN是包含循环的网络,将前面输入的有用信息编码到状态变量中去,从而拥有了一定的记忆功能。 + RNN是包含循环的网络,将前面输入的有用信息编码到状态变量中去,从而拥有了一定的记忆功能。 - [ ] [3-3-4 长短期记忆网络LSTM是如何实现长短期记忆功能的?](#3-3-4) @@ -2700,7 +2810,7 @@ $$ - [ ] [3-3-6 GRU和LSTM有何异同](#3-3-6) - GRU:将遗忘门和输入门合成了一个单一的更新门。同样还混合了细胞状态和隐藏状态,和其他一些改动。最终的模型比标准的 LSTM 模型要简单,也是非常流行的变体。 + GRU:(1)将遗忘门和输入门合成了一个单一的更新门,只有两个门:更新门、复位门。(2)GRU不再区分cell的状态$\overrightarrow{\mathrm{C}}$和cell的输出$\overrightarrow{\mathbf{h}}$。 ![](https://upload-images.jianshu.io/upload_images/42741-dd3d241fa44a71c0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) reset gate $r_t$:计算候选隐层 $\tilde{h}_{t}$ 时用来控制需要 保留多少之前的记忆 $h_{t-1}$,比如如果 $r_t$ 为0,那么$\tilde{h}_{t}$只包含当前词的信息。 @@ -2733,16 +2843,56 @@ $$ - [ ] [3-3-8 注意力机制是什么?Seq2Seq模型引入注意力机制主要解决什么问题?](#3-3-8) - 主要解决问题: + 编码-解码架构的主要缺点:编码器`RNN`输出的上下文`C`的维度太小,难以恰当的概括一个长的输入序列的完整信息。 + + - [ ] 注意力机制主要解决问题: (1)随着输入序列增长,模型性能发生显著下降。 - ​ 因为编码时驶入序列的全部信息压缩到了一个向量表示中。随着序列增长,句子越前面的词的信息丢失就越严重。 + ​ 因为编码时输入序列的全部信息压缩到了一个定长向量表示中。随着序列增长,句子越前面的词的信息丢失就越严重。 (2)seq2seq输出序列中,常常会损失部分输入序列的信息。 ​ 这是因为在解码时,当前词及对应的源语言词的上下文信息和位置信息在编解码过程中丢失了。 + 原编码-解码架构 + + ![img](http://huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/imgs/dl_rnn/decoder_encoder.jpg) + + 加入attention + + ![img](http://huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/imgs/dl_rnn/attention.jpg) + + attention 本身可以理解为一种**对齐关系**,**给出了模型输入、输出之间的对齐关系,解释了模型到底学到了什么知识。** + + - [ ] 注意力打分函数的计算方式 + + ![1566132296775](C:\Users\Kevin\AppData\Roaming\Typora\typora-user-images\1566132296775.png) + + ![](https://cdn.mathpix.com/snip/images/kLGt8ZRlTjA0PT7LYTuqIC2-ePp9Eh30KX5HANtYs4o.original.fullsize.png) + + - [ ] attention的分类 + + **global attention vs local attention** + + 上述的 `attention` 机制中为了计算上下文向量 $\overrightarrow{\mathbf{c}}_{i}$, 需要考虑 `encoder` 的所有隐向量(`global attention`)。当输入序列较长时(如一段话或一篇文章),计算效率较低。 + + `local attention` 在计算上下文向量 $\overrightarrow{\mathbf{c}}_{i}$ 时只需要考虑 `encoder` 的部分隐向量:首选预测`encoder` 端对齐的位置 $p_{i}$,然后基于位置 $p_{i}$ 选择一个窗口来计算上下文向量 $\overrightarrow{\mathbf{c}}_{i}$ 。 + + + + **self attention** + + 传统的 `attention` 是基于`encoder` 端和 `decoder` 端的隐向量来计算 `attention`的,得到的是输入序列的每个 `input` 和输出序列的每个 `output` 之间的依赖关系。 + + `self attention` 计算三种 `attention`: + + - 在`encoder` 端计算自身的 `attention`,捕捉`input` 之间的依赖关系。 + - 在 `decoder` 端计算自身的 `attention`,捕捉`output` 之间的依赖关系。 + - 将 `encoder` 端得到的 `self attention` 加入到 `decoder` 端得到的 `attention`中,捕捉输入序列的每个 `input` 和输出序列的每个 `output` 之间的依赖关系。 + + + - [ ] [RNN的长期依赖(Long-Term Dependencies)问题是什么?怎么解决]() 长期依赖问题是:随着输入序列的增长,模型的性能发生显著下降,RNN难以捕捉长距离输入之间的依赖。 @@ -2753,12 +2903,58 @@ $$ (1)LSTM、GRU等模型加入门控机制,捕捉长期记忆,很大程度上弥补了梯度消失 - (2) + (2)残差结构 - + (2)设计多个时间尺度的模型:在细粒度的时间尺度上处理近期信息、在粗粒度时间尺度上处理远期的信息。得到粗粒度时间尺度方法1跳跃链接:增加从远期的隐变量到当前隐变量的直接连接;2. 是删除连接:主动删除时间跨度为 1 的连接,并用更长的连接替换。 - [ ] [RNN为什么会产生梯度消失或者梯度爆炸]() + 主要由于权重矩阵 $W$ 在不同时间步被重复使用,导致形成 $W$ 的幂乘 + + 1. 长期依赖的问题是深度学习中的一个主要挑战,其产生的根本问题是:经过许多阶段传播之后,梯度趋向于消失或者爆炸。 + + - 长期依赖的问题中,梯度消失占大部分情况,而梯度爆炸占少数情况。但是梯度爆炸一旦发生,就优化过程影响巨大。 + - `RNN` 涉及到许多相同函数的多次复合作用,每个时间步一次。这种复合作用可以导致极端的非线性行为。因此在`RNN` 中,长期依赖问题表现得尤为突出。 + + 2. 考虑一个没有非线性、没有偏置非常简单的循环结构: $\overrightarrow{\mathbf{h}}^{(t)}=\mathbf{W} \overrightarrow{\mathbf{h}}^{(t-1)}$。则有: + + ![](https://cdn.mathpix.com/snip/images/XOmA-zH1pvODDFxVhIO99BFDrSBP_MyM2xjKywDNnyo.original.fullsize.png) + + 设$\mathbf{N}$ 可以正交分解时: $\mathbf{W}=\mathbf{Q} \mathbf{\Lambda} \mathbf{Q}^{T}$ 。其中 0 为正交矩阵,$\mathbf{\Lambda}$ 为特征值组成的三角阵。则: + $$ + \begin{array}{c}{\overrightarrow{\mathbf{h}}^{(t)}=\mathbf{Q} \mathbf{\Lambda}^{t} \mathbf{Q}^{T} \overrightarrow{\mathbf{h}}^{(0)}} \\ {\nabla_{\overrightarrow{\mathbf{h}}^{(0)}} L=\frac{\partial \overrightarrow{\mathbf{h}}^{(t)}}{\partial \overrightarrow{\mathbf{h}}^{(0)}} \nabla_{\overrightarrow{\mathbf{h}}^{(t)}} L=\mathbf{Q} \mathbf{\Lambda}^{t} \mathbf{Q}^{T} \nabla_{\overrightarrow{\mathbf{h}}^{(t)}} L}\end{array} + $$ + + - 前向传播: + + - 对于特征值的幅度不到 1 的特征值对应的 $\overrightarrow{\mathbf{h}}^{(0)}$ 的部分将随着 $t$ 衰减到 0 。 + - 对于特征值的幅度大于 1 的特征值对应的$\overrightarrow{\mathbf{h}}^{(0)}$ 的部分将随着$t$ 指数级增长。 + + - 反向传播: + + - 对于特征值幅度不到1的梯度的部分将随着$t$ 衰减到 0 。 + + - 对于特征值幅度大于1的梯度的部分将随着 $t$ 指数级增长 。 + + 3. 若考虑非线性和偏置,即: $\overrightarrow{\mathbf{h}}^{(t+1)}=\tanh \left(\overrightarrow{\mathbf{b}}+\mathbf{W} \overrightarrow{\mathbf{h}}^{(t)}+\mathbf{U} \overrightarrow{\mathbf{x}}^{(t+1)}\right)$,有: + $$ + \frac{\partial \overrightarrow{\mathbf{h}}^{(t+1)}}{\partial \overrightarrow{\mathbf{h}}^{(t)}}=\operatorname{diag}\left(1-\left(\overrightarrow{\mathbf{h}}^{(t+1)}\right)^{2}\right) \mathbf{w} + $$ + + - 前向传播: + + 由于每一级的 $\overrightarrow{\mathbf{h}}$ 的幅度被 $\tanh (\cdot)$ 函数限制在 `(-1,1)` 之间,因此前向传播并不会指数级增长。 + + 这也是为什么 `RNN` 使用 `tanh` 激活函数,而不使用 `relu`的原因。 + + - 反向传播: + + 由于隐状态的幅度被$\tanh (\cdot)$ 函数限制在 `(-1,1)` 之间,因此 $\operatorname{diag}\left(1-\left(\overrightarrow{\mathbf{h}}^{(t+1)}\right)^{2}\right) \mathbf{W}$ 对 $\mathbf{W}$进行了一定程度上的缩小。$\overrightarrow{\mathbf{h}}^{(t+1)}$ 越大,结果越小。 + + - 如果 $\mathbf{W}$ 的特征值经过这样的缩小之后,在每个时刻都远小于1(因为每个时刻缩小的比例会变化),则该梯度部分将衰减到 0 。 + - 如果 $\mathbf{W}$ 的特征值经过这样的缩小之后,在每个时刻都远大于1,则该梯度部分将指数级增长。 + - 如果 $\mathbf{W}$ 的特征值经过这样的缩小之后,在不同的时刻有时候小于1有时候大于1(因为每个时刻缩小的比例会变化),则该梯度部分将比较平稳。 + - [ ] [RNN如何解决梯度爆炸问题]() @@ -2767,12 +2963,18 @@ $$ $$ g=\frac{\eta g}{|g|} $$ - + - [ ] [RNN如何解决梯度消失问题]() - (1)LSTM、GRU等模型加入门控机制,捕捉长期记忆,很大程度上弥补了梯度消失 + (1)LSTM、GRU等模型加入门控机制,捕捉长期记忆,很大程度上弥补了梯度消失。 + + ​ 背后的思路是让路径的梯度乘积接近1 + + (2)多时间尺度(增加跳跃连接、删除连接)、泄露单元(线性自连接单元) - (2)RNN+初始化权重矩阵为单位矩阵 + (3)引入残差结构 + + (4)RNN+初始化权重矩阵为单位矩阵 - [ ] [LSTM的结构,每个门的作用,计算公式]() @@ -2796,6 +2998,24 @@ $$ ![](https://colah.github.io/posts/2015-08-Understanding-LSTMs/img/LSTM3-var-tied.png) **GRU** + + - [ ] [LSTM为什么可以解决梯度消失]() + + **将连乘关系转换为相加的线性关系** + + 在LSTM中 $c_{t}=f_{t} \odot c_{t-1}+i_{t} \odot \tilde{c}_{t}$ ,其中 $c_{t-1}$是此前的信息, $\tilde{\mathbf{c}}_{t}$是当前即刻的新信息, $c_t$ 是最终的信息。可以看到 $c_t$和 $c_{t-1}$此时是线性关系,不再是RNN中的连乘关系,梯度以线性在中间节点流动,因此可以保证很长时间的记忆。 + + 进一步地,如果门控信号考虑bias,同时忽略输入变量 $h_{j-1}$的作用,隐含层关系表示为: + $$ + c_{j}=\sigma\left(W^{f} X_{j}+b^{f}\right) c_{j-1}+\sigma\left(W^{i} X_{j}+b^{i}\right) \sigma\left(W X_{j}+b\right) + $$ + 于是,需要连乘的项表示为: + $$ + \frac{\partial c_{j}}{\partial c_{j-1}}=\sigma\left(W^{f} X_{j}+b\right) + $$ + 该值范围在0~1之间。但是在实际参数更新中,可以通过控制bias比较大,使得该值接近于1;在这种情况下,即使通过很多次连乘的操作,梯度也不会消失,仍然可以保持“长距”连乘项的存在。即总可以通过选择合适的参数,在不发生梯度爆炸的情况下,找到合理的梯度方向来更新参数,而且这个方向可以充分地考虑远距离的隐含层信息的传播影响。 + + ## 4、 基础工具 @@ -2853,7 +3073,7 @@ xgboos的优点: - [ ] [4-2-3 为什么xgboost训练会那么快,主要优化点是什么?](#4-2-3) 1. 当数据集大的时候使用**近似算法**:在特征分裂时,根据特征k的分布确定$l$个候选切分点。根据这些切分点把相应的样本放入对应的桶中,对每个桶的$G,H$进行累加,最后通过遍历所有的候选分裂点来找到最佳分裂点。我们对这么多个桶进行分支判断,显然比起对n个样本找分裂节点更快捷。 -2. Block与并行。分块并行,针对的是寻找最优切分点的过程中的排序部分。 +2. Block与并行。**分块并行**,针对的是寻找最优切分点的过程中的排序部分。 3. CPU cache 命中优化。对于exact greedy算法中, 使用**缓存预取**。具体来说,对每个线程分配一个连续的buffer,读取梯度信息并存入Buffer中(这样就实现了非连续到连续的转化),然后再统计梯度信息。 4. Block预取、Block压缩、Block Sharding等 @@ -2918,7 +3138,7 @@ XGBoost能对缺失值自动进行处理,其思想是**对于缺失值自动 二阶泰勒展开实际不是 ![\approx](https://www.zhihu.com/equation?tex=%5Capprox) 最小二乘法,平方损失函数的二阶泰勒展开=最小二乘法。但作者为何想用二阶泰勒展开呢,一种猜想为了xgboost库的可扩展性,**因为任何损失函数只要二阶可导即能【复用】文章中的的任何推导**。而且泰勒的本质是尽量去模仿一个函数,我猜二阶泰勒展开已经足以近似大量损失函数了,典型的还有基于分类的对数似然损失函数。嘿,这样同一套代码就能完成回归或者分类了,而不是每次都推导一番,重写训练代码。 - +xgboost使用了一阶和二阶偏导, 二阶导数有利于梯度下降的更快更准. 使用泰勒展开取得函数做自变量的二阶导数形式, 可以在不选定损失函数具体形式的情况下, 仅仅依靠输入数据的值就可以进行叶子分裂优化计算, 本质上也就把损失函数的选取和模型算法优化/参数选择分开了. 这种去耦合增加了xgboost的适用性, 使得它按需选取损失函数, 可以用于分类, 也可以用于回归。 - [ ] [4-2-7 Xgboost是如何寻找最优特征的?](#4-2-7) @@ -2961,15 +3181,27 @@ $$ - [ ] [5-1-2 如何设计推荐场景的特征体系?举例说明](#5-1-1) + - [ ] [5-1-3 你是如何建立用户模型来理解用户,获取用户兴趣的?](#5-1-1) + - [ ] [5-1-4 你是如何选择适合该场景的推荐模型?讲讲你的思考过程](#5-1-1) + - [ ] [5-1-5 你是如何理解当前流行的召回->粗排->精排的推荐架构?这种架构有什么优缺点?什么场景适用使用,什么场景不适合?](#5-1-1) + - [ ] [5-1-6 如何解决热度穿透的问题?(因为item热度非常高,导致ctr类特征主导排序,缺少个性化的情况)](#5-1-1) + - [ ] [5-1-7 用户冷启动你是如何处理的?](#5-1-1) + - [ ] [5-1-8 新内容你是如何处理的?](#5-1-1) + - [ ] [5-1-9 你们使用的召回算法有哪些?如何能保证足够的召回率?](#5-1-1) + - [ ] [5-1-10 实时数据和离线数据如何融合?工程上是怎样实现?如何避免实时数据置信度不高带来的偏差问题?](#5-1-1) + - [ ] [5-1-11 你们是如何平衡不同优化目标的问题?比如:时长、互动等](#5-1-1) + + multi-task learning + - [ ] [5-1-12 不同类型内容推荐时候,如何平衡不同类型内容,比如图文、视频;或者不同分类](#5-1-1) - [ ] [5-1-13 如何保证线上线下数据一致性?工程上是如何实现?](#5-1-1) - [ ] [5-1-14 离线训练效果好,但是上线效果不明显或在变差可能是什么问题?如何解决?](#5-1-1) @@ -2989,6 +3221,44 @@ l - [ ] [5-1-18 深度学习可以应用到推荐问题上解决哪些问题?为什么比传统机器学习要好?](#5-1-1) +- [ ] 为什么CTR任务中损失函数一般选择交叉熵作为损失函数(分类)而不用平方损失函数(回归) + + 一方面点击-不点击本身是一个二分类的任务,分类任务采用交叉熵作为损失函数是常规做法。另一方面考虑参数更新。 + + 深度学习同样有许多损失函数可供选择,如平方差函数(Mean Squared Error),绝对平方差函数(Mean Absolute Error),交叉熵函数(Cross Entropy)等。而在理论与实践中,我们发现Cross Entropy相比于在线性模型中表现比较好的平方差函数有着比较明显的优势。其主要原因是在深度学习通过反向传递更新*W*和*b*的同时,激活函数Sigmoid的导数在取大部分值时会落入左、右两个饱和区间,造成参数的更新非常缓慢。具体的推导公式如下: + + 一般的MSE被定义为: + + ![img](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2017/8635ca29.png) + + 其中*y*是我们期望的输出,*a*为神经元的实际输出*a=σ(Wx+b)*。由于深度学习反向传递的机制,权值*W*与偏移量*b*的修正公式被定义为: + + ![img](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2017/85ae2260.png) + + 因为Sigmoid函数的性质,导致*σ′(z)*在*z*取大部分值时会造成饱和现象。 + + Cross Entropy的公式为: + + ![img](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2017/2882eb3a.png) + + 如果有多个样本,则整个样本集的平均交叉熵为: + + ![img](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2017/9feeba61.png) + + 其中*n*表示样本编号,*i*表示类别编号。 如果用于Logistic分类,则上式可以简化成: + + ![img](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2017/6720fe17.png) + + 与平方损失函数相比,交叉熵函数有个非常好的特质: + + ![img](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2017/3d8c74bf.png) + + 可以看到,由于没有了*σ′*这一项,这样一来在更新*w*和*b*就不会受到饱和性的影响。当误差大的时候,权重更新就快,当误差小的时候,权重的更新就慢。 + +- [ ] 深度学习模型有什么缺点? + + 单纯的DNN模型对于CTR的提升并不明显。而且单独的DNN模型本身也有一些瓶颈例如,当用户本身是非活跃用户时,由于其自身与Item之间的交互比较少,导致得到的特征向量会非常稀疏,而深度学习模型在处理这种情况时有可能会过度的泛化,导致推荐与该用户本身相关较少的Item(FM模型也存在该问题)。因此,我们将广泛线性模型与深度学习模型相结合,同时又包含了一些组合特征,以便更好的抓住Item-Feature-Label三者之间的共性关系。我们希望在宽深度模型中的宽线性部分可以利用交叉特征去有效地记忆稀疏特征之间的相互作用,而在深层神经网络部分通过挖掘特征之间的相互作用,提升模型之间的泛化能力。 + # **二、数学相关** @@ -3011,6 +3281,17 @@ $$ - [ ] [6-1-4 什么是Beta分布?它与二项分布有什么关系?](#6-1-4) + 参考知乎回答:https://www.zhihu.com/question/30269898 + + beta分布可以看做一个概率的概率分布,当你不知道一个东西的具体概率是多少时,它可以给出了所有概率出现的可能性大小。**它是对二项分布中成功概率p的概率分布的描述。它的形式如下:** + + + + beta分布与二项分布是共轭先验的([Conjugate_prior](https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Conjugate_prior%23Example))。所谓共轭先验就是先验分布是beta分布,而后验分布同样是beta分布。以棒球运动员击球为例,结果很简单: + $$ + \operatorname{Beta}\left(\alpha_{0}+\operatorname{hits}, \beta_{0}+\text { misses }\right) + $$ + - [ ] [6-1-5 什么是泊松分布?它与二项分布有什么关系?](#6-1-5) - [ ] [6-1-6 什么是t分布?他与正态分布有什么关系?](#6-1-6) @@ -3113,22 +3394,70 @@ $$ - [ ] [7-1-1 什么是梯度?](#7-1-1) + 梯度的方向是函数值增加最快的方向,梯度的相反方向是函数值减小的最快的方向。 + +- [ ] [为什么梯度的负方向是局部下降最快方向?]() + + 对 $f(x+v)$在 $x$ 处进行泰勒一阶展开 + $$ + f(x+v) \approx f(x)+\nabla f(x)^{T} v + $$ + 这里有 + $$ + f(x)-f(x+v) \approx-\nabla f(x)^{T} v + $$ + 其中$\nabla f(x)^{T}$和 $v$均为向量,$-\nabla f(x)^{T} v$就是两个向量进行内积,而向量进行内积的最大值就是两者共线的时候,也就是 $v$ 的方向和 $-\nabla f(x)^{T}$ 方向相同时,内积最大。该内积值代表了最大的下降量。 + - [ ] [7-1-2 梯度下降找到的一定是下降最快的方法?](#7-1-1) + 梯度下降法并不一定是全局下降最快的方向,它只是目标函数在当前的点的切平面(当然高维问题不能叫平面)上下降最快的方向。在practical implementation中,牛顿方向(考虑海森矩阵)才一般被认为是下降最快的方向,可以达到superlinear的收敛速度。 + - [ ] [7-1-3 牛顿法和梯度法有什么区别?](#7-1-1) - 梯度法对目标函数进行一阶泰勒展开,梯度就是目标函数的一阶信息; + 梯度下降法:$\overrightarrow{\mathbf{x}}_{k+1}=\overrightarrow{\mathbf{x}}_{k}-\epsilon\overrightarrow{\mathbf{g}}$ + + 牛顿法:$\overrightarrow{\mathbf{x}}_{k+1}=\overrightarrow{\mathbf{x}}_{k}-\mathbf{H}^{-1} \overrightarrow{\mathbf{g}}$ + + 1. 梯度法对目标函数进行一阶泰勒展开,梯度就是目标函数的一阶信息; + + 2. 牛顿法对目标函数进行二阶泰勒展开,Hessian矩阵就是目标函数的二阶信息。 + + 3. 牛顿法的收敛速度一般要远快于梯度法,但是在高维情况下Hessian矩阵求逆的计算复杂度很大,而且当目标函数非凸时,牛顿法有可能会收敛到鞍点。 + 4. 因为梯度法旨在朝下坡移动,而牛顿法目标是寻找梯度为0的点。 + + 5. 位于一个极小值点附近时,牛顿法比梯度下降法能更快地到达极小值点。 - 牛顿法对目标函数进行二阶泰勒展开,Hessian矩阵就是目标函数的二姐信息。 + 如果在一个鞍点附近,牛顿法效果很差,因为牛顿法会主动跳入鞍点。而梯度下降法此时效果较好(除非负梯度的方向刚好指向了鞍点)。 - 牛顿法的收敛速度一般要远快于梯度法,但是在高维情况下Hessian矩阵求逆的计算复杂度很大,而且当目标函数非凸时,牛顿法有可能会收敛到鞍点。因为梯度法旨在朝下坡移动,而牛顿法目标是寻找梯度为0的点。 + 6. 梯度下降法中,每一次 $\overrightarrow{\mathbf{x}}$ 增加的方向一定是梯度相反的方向 $-\epsilon_{k} \nabla_{k}$ 。增加的幅度由$\epsilon_{k}$ 决定,若跨度过大容易引发震荡。 + + 而牛顿法中,每一次 $\overrightarrow{\mathbf{x}}$ 增加的方向是梯度增速最大的反方向 $-\mathbf{H}_{k}^{-1} \nabla_{k}$(它通常情况下与梯度不共线)。增加的幅度已经包含在 $\mathbf{H}_{k}^{-1}$ 中(也可以乘以学习率作为幅度的系数)。 - [ ] [7-1-4 什么是拟牛顿法?](#7-1-1) + 在牛顿法的迭代中,需要计算海森矩阵的逆矩阵 $\mathbf{H}^{-1}$,这一计算比较复杂。可以考虑用一个 $n$ 阶矩阵 $\mathbf{G}_{k}=G\left(\overrightarrow{\mathbf{x}}^{}\right)$ 来近似代替 。 + + 如果选择 $G_{k}$ 作为$\mathbf{H}_{k}^{-1}$ 的近似时,$\mathbf{G}_{k}$ 同样要满足两个条件: + + - $\mathbf{G}_{k}$必须是正定的。 + + - $\mathbf{G}_{k}$满足下面的拟牛顿条件:$\mathbf{G}_{k+1} \overrightarrow{\mathbf{y}}_{k}=\vec{\delta}_{k}$ + + 因为 $\mathbf{G}_{0}$ 是给定的初始化条件,所以下标从 $k+1$ 开始。 + + 按照拟牛顿条件选择$\mathbf{G}_{k}$作为$\mathbf{H}_{k}^{-1}$的近似或者选择$\mathbf{B}_{k}$作为$\mathbf{H}_{k}$的近似的算法称为拟牛顿法 + + 按照拟牛顿条件,在每次迭代中可以选择更新矩阵 + $$ + \mathbf{G}_{k+1}=\mathbf{G}_{k}+\Delta \mathbf{G}_{k} + $$ + +- [ ] + - [ ] [7-1-5 讲解什么是拉格朗日乘子法、对偶问题、kkt条件?](#7-1-1) **凸优化问题** @@ -3163,9 +3492,13 @@ $$ - [ ] [7-1-8 为什么深度学习不用二阶优化?](#7-1-1) + 深度学习的目标函数复杂,非凸;目标函数非凸时,牛顿法有可能会收敛到鞍点 + + + - [ ] [7-1-9 讲解SGD,ftrl、Adagrad,Adadelta,Adam,Adamax,Nadam优化算法以及他们的联系和优缺点](#7-1-1) -- [ ] + - [ ] [7-1-10 为什么batch size大,训练速度快or为什么mini-batch比SGD快?](#7-1-10)