Part I:简历
待补充~
Part II:深度学习
文本分类模型
文本分类模型: CNN、RNN,TextCNN,fasttext TextCNN RCNN HAN DMN EntityNetwork charCNN charRNN等(待补充),各个模型的1. 用途/适用场景;2.具体结构/原理;3. 优缺点;4. 改进;5. 对比其他模型。
1)CNN原理,如何用在文本上,在什么情况下适合用CNN,在什么情况下用LSTM
2)RNN系列,掌握RNN、LSTM和GRU的内部结构,RNN产生梯度消失的原因,LSTM如何解决,GRU对LSTM的改进。
序列标注模型
HMM MMEM 最大熵
文本表示模型
-
词袋模型
TF TF-IDF (每篇文章可以表示成一个长向量,向量中的每一维代表一个单词,该维对应的权重反应了这个词在原文中的重要程度。) -
ngram模型
划分为词并不是很好的做法,比如natural language processing 一词,如果三个词拆分,和三个词连续出现时大相径庭。通常,可以将连续出现的n个词组成的词组(N-gram)作为一个单独的特征放到向量表中,构成N-gram模型。实际应用中,对词进行词干抽取,分词等。 -
主题模型
一种特殊的概率图模型。词袋模型和ngram模型的文本表示模型有一个明显缺陷,即无法识别两个不同的词或者词组具有相同的主题。
如何判定两个不同的词具有相同的主题:比如这两个词可能有更高的概率同时出现在同一篇文档中。
主题模型所解决的事情:从文本库中发现有代表性的主题(得到每个主题上面词的分布),并且计算出每篇文章对应哪些主题。 -
词嵌入与深度学习模型
词嵌入:将词向量化得统称,核心思想:将每个词映射成低维空间上(K维)的一个稠密向量。一篇文章有N个词,就可以用一个N*K的矩阵来表示这个文档。
深度学习模型的每个隐层对应着不同抽象层次的特征。卷积神经网络和循环神经网络的结构在文本中好效果主要是因为能够很好的对文本进行建模,抽取高层语义特征,且减少了网络学习中的参数,提高了训练速度,降低了过拟合的风险。
Word2vec
怎么训练词向量,skip-gram和cbow,可以参考一下:一篇通俗易懂的word2vec
Attention机制
比较常见的方法,可以参考一下:Attention用于NLP的一些小结
关于实战部分:
1)数据预处理,权重初始化,为什么不能全部初始化为0,词向量怎么预训练
图二是0中心化数据:每一个数据样本减去所有的样本均值得到。缺点:数据Y轴变化幅度(抖动幅度)比X轴要大;
图三是归一化数据:需要求数据样本的方差。数据x和y值都在0,1之间。
答:在训练完毕后,虽然不知道网络中每个权重的最终值应该是多少,但如果数据经过了恰当的归一化的话,就可以假设所有权重数值中大约一半为正数,一半为负数。这样,一个听起来蛮合理的想法就是把这些权重的初始值都设为0吧,因为在期望上来说0是最合理的猜测。这个做法错误的!因为如果网络中的每个神经元都计算出同样的输出,然后它们就会在反向传播中计算出同样的梯度,从而进行同样的参数更新。换句话说,如果权重被初始化为同样的值,神经元之间就失去了不对称性的源头。
正确做法:小随机数初始化。 因此,权重初始值要非常接近0又不能等于0。解决方法就是将权重初始化为很小的数值,以此来打破对称性。其思路是:**如果神经元刚开始的时候是随机且不相等的,那么它们将计算出不同的更新,并将自身变成整个网络的不同部分。**小随机数权重初始化的实现方法是:W = 0.01 * np.random.randn(D,H)
其中randn函数是基于零均值和标准差的一个高斯分布(译者注:国内教程一般习惯称均值参数为期望\mu)来生成随机数的。根据这个式子,每个神经元的权重向量都被初始化为一个随机向量,而这些随机向量又服从一个多变量高斯分布,这样在输入空间中,所有的神经元的指向是随机的。也可以使用均匀分布生成的随机数,但是从实践结果来看,对于算法的结果影响极小。
使用1/sqrt(n)校准方差。 上面做法存在一个问题,随着输入数据量的增长,随机初始化的神经元的输出数据的分布中的方差也在增大。我们可以除以输入数据量的平方根来调整其数值范围,这样神经元输出的方差就归一化到1了。也就是说,建议将神经元的权重向量初始化为:w = np.random.randn(n) / sqrt(n)
。其中n是输入数据的数量。这样就保证了网络中所有神经元起始时有近似同样的输出分布。实践经验证明,这样做可以提高收敛的速度。
2)过拟合问题,原因是什么,怎么解决,主要从数据和模型两方面出发:机器学习中用来防止过拟合的方法有哪些?
总结:
- 获取更多数据
- 从数据源头获取
- 数据增强
- 根据当前数据集生成(不建议,数据本身存在误差)
- 使用合适的模型
- 网络结构:网络层数,神经元个数
- 训练时间 Early stopping
- 限制权值 正则化
- 增加噪声
- 结合多种模型
- Bagging:简单来说分段函数的概念:用不同的模型拟合不同部分的训练集
- Boosting:既然训练复杂神经网络比较慢,那我们就可以只使用简单的神经网络(层数、神经元数限制等)。通过训练一系列简单的神经网络,加权平均其输出
- Dropout:在训练时,每次随机(如50%概率)忽略隐层的某些节点;这样,我们相当于随机从2^H个模型中采样选择模型;同时,由于每个网络只见过一个训练数据(每次都是随机的新网络),所以类似 bagging 的做法,这就是我为什么将它分类到「结合多种模型」中; 此外,而不同模型之间权值共享(共同使用这 H 个神经元的连接权值),相当于一种权值正则方法,实际效果比 L2 regularization 更好。
3)调参技巧,比如,卷积核大小怎么按层设置,bn放在哪里比较合适,激活函数之间的区别(sigmoid,tanh和relu),词向量维度怎么设置,等等。
-
卷积核大小的设置
-
BN
批标准化(Bactch Normalization,BN)是为了克服神经网络加深导致难以训练而诞生的,随着神经网络深度加深,训练起来就会越来越困难,收敛速度回很慢,常常会导致梯度弥散问题(Vanishing Gradient Problem)。
为解决数据信号分布不一致问题,一般是根据训练样本和目标样本的比例对训练样本做一个矫正。通过引入Bactch Normalization来标准化某些层或者所有层的输入,从而固定每层输入信息的均值和方差。
方法:Batch Normalization一般用在非线性映射(激活函数)之前,对x=Wu+b做标准化,使结果(输出信号各个维度)的均值为0,方差为1。让每一层的输入有一个稳定的分布会有利于网络的训练。
优点:Bactch Normalization通过标准化让激活函数分布在线性区间,结果就是加大了梯度,让模型更大胆的进行梯度下降,具有如下优点:
加大搜索的步长,加快收敛的速度;
更容易跳出局部最小值;
破坏原来的数据分布,一定程度上缓解了过拟合; -
激活函数之间的区别
-
词向量维度怎么设置
比较大的语料dim在300~500,比如Wikipedia、百度百科全词条,效果会比较好;特定领域的语料可以低一些维度200~300
也有说法是100~200,大的语料200,小的语料100.
4)模型评估指标,acc,pre,recall,f1,roc曲线和auc曲线,分别适用于什么任务,怎么降低偏差,怎么降低方差,可以关注一下Hulu微信公众号:Hulu机器学习问题与解答系列 | 第一弹:模型评估
5)优化方法,批量梯度下降,随机梯度下降,mini-batch梯度下降的区别,adam,adagrad,adadelta,牛顿法
6)梯度消失问题,原因(链式求导,激活函数),解决方法(主要是batch norm);以及梯度爆炸问题(梯度截断)
7)关于训练集和验证集,为什么要划分,如何划分(留出法,交叉验证)8)如何处理数据不均衡问题,也是从数据和模型两方面出发解决。
Part III:机器学习
-
至少要掌握的算法原理:
1)朴素贝叶斯
2)逻辑回归,线性回归
3)决策树,不同的划分方式,ID3,C4.5,CTAR,XGBoost等等
4)Ensemble模型
5)SVM,核函数选择,不同SVM形式
6)HMM,CRF,如何轻松愉快地理解条件随机场(CRF)?
7)最大熵原理,图解最大熵原理(The Maximum Entropy Principle)
8)KNN和K-Means,DBSACN也了解一下,以及各种距离计算方式,关于机器学习距离的理解以上列出的算法都需要掌握其基本原理以及优缺点,可以参考:机器学习算法优缺点及其应用领域 -
必须要会写的公式:
1)BP后向传播过程的推导,可以参考:漫谈LSTM系列的梯度问题,先定义Loss函数,然后分别对输出层参数和隐藏层参数进行求导,得到参数的更新量。
2)softmax和交叉熵推导,分成i=j 和 ij 两种情况来算,参考这里:大师网-简单易懂的softmax交叉熵损失函数求导
3)各种Loss函数
4)似然函数,负对数似然函数的推导
5)最小二乘法,利用矩阵的秩进行推导
7)贝叶斯定理,拉普拉斯平滑 -
最好也要掌握一下的公式:
1)RNN在BP过程中梯度消失的原因,也把这个链式求导过程写出来。
2)各种优化方法的公式,SGD,Momentum,Adagrad,Adam,机器学习优化方法总结比较 - 合唱团abc - 博客园
3)Batch Normalization,就是个归一化过程,再加一个scale操作
4)SVM推导,拉格朗日了解一下:机器学习之拉格朗日乘数法
5)最大熵模型相关推导,一步一步理解最大熵模型 - wxquare - 博客园
Part IV:算法编程
编程分成三种:普通算法编程,海量数据编程,模型编程。
普通算法编程,一般用C++,需要掌握数组,链表,二叉树,递归,贪心,动态规划,各种容器,各种排序算法,在时间或者空间上的优化思路,以及复杂度的分析。
容器是个好东西,用vector代替数组,用map实现桶思想,用set排序,用queue写bfs,用stack写dfs等等。
推荐大家刷:剑指offer,这本书两天就可以看完(如果仅仅是看题目以及思路),然后上牛客网做一下题:剑指Offer_编程题_牛客网,66道原题全在这,而且评论区有大神出没,某些题的解法我觉得比书上的要巧妙。或者刷LeetCode也可以。
随手列几道常考的代码题:
1)复杂链表的复制,链表的删除
2)最长公共子序列,逆序对
3)快排,归并排序,堆排序
4)二分查找,以及衍生的题目
5)深度优先搜索
海量数据编程,这种用python写比较方便一点,可以把大文件划分成小文件,或者分治加哈希:十道海量数据处理面试题与十个方法大总结 - CSDN博客