Open Bryce1010 opened 4 years ago
算法岗面试准备,机器学习基础
算法/深度学习/NLP面试笔记: [github]
AI Jobs Notes https://github.com/amusi/AI-Job-Notes 公式:刷题+背题+项目+实习(可选)+竞赛(可选)+顶会/顶刊(可选)
Deep Learning interview book https://github.com/amusi/Deep-Learning-Interview-Book
机器学习/算法校招面试考点 https://www.nowcoder.com/discuss/165930
一个算法菜鸡的面试经验总结[blog]
深度学习500问 [github]
以问答形式对常用的概率知识、线性代数、机器学习、深度学习、计算机视觉等热点问题进行阐述,以帮助自己及有需要的读者。 全书分为18个章节,50余万字。由于水平有限,书中不妥之处恳请广大读者批评指正。 未完待续............ 如有意合作,联系scutjy2015@163.com 版权所有,违权必究 Tan 2018.06
本节将会涉及以下内容:
分类模型评估常用方法:Accuracy, Precision, Recall, P-R曲线, F1, Confusion Matrix, ROC, AUC ;
回归模型评估常用方法:MSE, MAE, R-Squard ;
误差,偏差和方差;过拟合和欠拟合;交叉验证;Unblanced Data;
指标 | 描述 |
---|---|
Accuracy | 准确率 |
Precision | 精准度/查准率 |
Recall | 召回率/查全率 |
P-R曲线 | 查准率为纵轴,查全率为横轴,作图 |
F1 | F1值 |
Confusion Matrix | 混淆矩阵 |
ROC | ROC曲线 |
AUC | ROC曲线下的面积 |
回归模型常用评估方法:
指标 | 描述 |
---|---|
Mean Square Error (MSE, RMSE) | 平均方差 |
Absolute Error (MAE, RAE) | 绝对误差 |
R-Squared | R平方值 |
查准率和查全率(precision&recall)
ROC和AUC
F1-score
数据
扩增数据集;
数据
对大类样本欠采样;
代表算法:EasyEnsemble。其思想是利用集成学习机制,将大类划分为若干个集合供不同的学习器使用。相当于对每个学习器都进行欠采样,但对于全局则不会丢失重要信息。
数据
对小类样本过采样;
代表算法:SMOTE和ADASYN。
SMOTE:通过对训练集中的小类数据进行插值来产生额外的小类样本数据。
新的少数类样本产生的策略:对每个少数类样本a,在a的最近邻中随机选一个样本b,然后在a、b之间的连线上随机选一点作为新合成的少数类样本。
ADASYN:根据学习难度的不同,对不同的少数类别的样本使用加权分布,对于难以学习的少数类的样本,产生更多的综合数据。 通过减少类不平衡引入的偏差和将分类决策边界自适应地转移到困难的样本两种手段,改善了数据分布。
使用新评价指标;
类别不均衡评价指标
选择新算法;
不同的算法适用于不同的数据分布,应该用不同的算法进行比较
数据代价加权;
对小样本数据增加权值,降低大样本的权值影响,从而使得样本重点集中在小样本上
如何解决欠拟合?
如何解决过拟合?
解决过拟合的方法主要有两个,一个是增加数据,另一个是做正则化;
数据
重新清洗数据,数据不纯导致过拟合;数据
较少样本的特征数;数据
增加训练样本的数据;模型
降低模型复杂度;正则化
增大正则化的系数;正则化
添加dropout方法;让神经元以一定的概率处于不工作的状态;early stoping
支持向量机是一种二分类模型,它的目的是寻找一个超平面来对样本进行分割,分割的原则是边界最大化,最终转化为一个凸二次规划问题来求解.
本节将会将会涉及以下内容:
维数灾难,常用的聚类方法,降维方法
为什么会产生维数灾难?
特征数多
样本密度
假设在分类人物场景下,在低维空间中,样本特征数量少,分类任务难度大;所以容易想到增加特征数量,扩充维度空间,在高纬度中,特征数增加,样本区分度更高,分类任务难度降低。但是换个角度来看,在低纬度情况下样本的密度大,区分度小;在高维空间,样本密度小,样本空间稀疏,区分度大。但是如果样本空间的的维数太大,导致样本密度过于稀疏,造成分类器学习到一些过于特殊的样本,造成过拟合的现象。那么这种现象怎么来避免呢?
怎样避免维数灾难?
降维
一般维数灾难的原因是特征数太多,维数太大,通过降维避免。常用方法有主成分分析法(PCA),线性判别法(LDA),奇异值分解简化数据,拉普拉斯特征映射等。
聚类和降维的关系?
数据点
数据特征
聚类方法
降维方法
聚类是针对数据点的操作,而降维是针对数据特征的操作;常用的聚类方法有K-Means,层次聚类和基于密度的聚类等;常用的降维方法有PCA,lsomap,LLE等。
原理
$$ E=\sum{i=1}^{k}\sum{p\in C_i}\left|p-m_i\right|^2 $$
这里E是数据中所有对象的平方误差的总和,p是空间中的点,$m_i$是簇$C_i$的平均值
算法步骤
首先随机选取k个对象,然后n个对象初始化的分配给这k各族,代表每个族的平均值或中心点;
然后对剩余的所有对象,根据其到不同族中心的距离,将它赋给最近的族,重新计算每个族的平均值或中心;
迭代进行这两个步骤直到族中心不再变化。
代码实现
#创建k个点作为初始的质心点(随机选择)
#当任意一个点的簇分配结果发生改变时
#对数据集中的每一个数据点
#对每一个质心
#计算质心与数据点的距离
#将数据点分配到距离最近的簇
#对每一个簇,计算簇中所有点的均值,并将均值作为质心
import math
import matplotlib.pyplot as plt
import random
def getEuclidean(point1, point2):
dimension = len(point1)
dist = 0.0
for i in range(dimension):
dist += (point1[i] - point2[i]) ** 2
return math.sqrt(dist)
def k_means(dataset, k, iteration):
#初始化簇心向量
index = random.sample(list(range(len(dataset))), k)
vectors = []
for i in index:
vectors.append(dataset[i])
#初始化标签
labels = []
for i in range(len(dataset)):
labels.append(-1)
#根据迭代次数重复k-means聚类过程
while(iteration > 0):
#初始化簇
C = []
for i in range(k):
C.append([])
for labelIndex, item in enumerate(dataset):
classIndex = -1
minDist = 1e6
for i, point in enumerate(vectors):
dist = getEuclidean(item, point)
if(dist < minDist):
classIndex = i
minDist = dist
C[classIndex].append(item)
labels[labelIndex] = classIndex
for i, cluster in enumerate(C):
clusterHeart = []
dimension = len(dataset[0])
for j in range(dimension):
clusterHeart.append(0)
for item in cluster:
for j, coordinate in enumerate(item):
clusterHeart[j] += coordinate / len(cluster)
vectors[i] = clusterHeart
iteration -= 1
return C, labels
层次聚类算法
凝聚
将所有对象看成单独的一个类,计算两两之间的距离,将距离最小的两类合并成一个新类;重新计算新类与其他所有类的距离,重复以上步骤,直至所有类最后合并成要求的类别数量。
SOM聚类算法
self-Organization Maps
(1) 网络初始化,对输出层每个节点权重赋初值; (2) 从输入样本中随机选取输入向量并且归一化,找到与输入向量距离最小的权重向量; (3) 定义获胜单元,在获胜单元的邻近区域调整权重使其向输入向量靠拢; (4) 提供新样本、进行训练; (5) 收缩邻域半径、减小学习率、重复,直到小于允许值,输出聚类结果。
FCM聚类算法
Fuzzy C-Means
(1) 标准化数据矩阵; (2) 建立模糊相似矩阵,初始化隶属矩阵; (3) 算法开始迭代,直到目标函数收敛到极小值; (4) 根据迭代结果,由最后的隶属矩阵确定数据所属的类,显示最后的聚类结果。
四种聚类算法比较
聚类方法 | 聚错样本数 | 运行时间/s | 平均准确率/(%) |
---|---|---|---|
K-Means | 17 | 0.146001 | 89 |
层次聚类 | 51 | 0.128744 | 66 |
SOM | 22 | 5.267283 | 86 |
FCM | 12 | 0.470417 | 92 |
PCA
LDA
算法岗面试准备,深度学习基础
神经网络的训练难度与梯度的反向传播过程密切相关,如果反向回传的梯度越来越小,那么浅层网络更小慢或者不更新,这被成为梯度消失;在深层网络中或者循环神经网络中,如果返现回传的梯度大,那么网络参数更新太快,造成不稳定的现象,这被成为梯度爆炸。那么是什么原因造成梯度消失和梯度爆炸的呢?
学习率的设定
学习率设定过大,使得网络更新快,使得反向传播的梯度积累值更大,一定程度以后,造成梯度爆炸,甚至溢出NaN;
网络参数初始化
网络参数初始化不恰当,使得一开始的参数回传慢,造成梯度消失;或是一开始的梯度回传大,造成梯度爆炸;
激活函数的边缘效应
激活函数边缘一般都有激活抑制和激活放大的部分,在梯度趋于零的时候,造成梯度消失,梯度接近无穷的时候,造成梯度爆炸;
知道原因以后,有什么方法避免吗?
BatchNorm
通过mini-batch的归一化,使得数据总是规范化的,分布总是趋于高斯分布的,一方面避免梯度消失和梯度爆炸的问题,一方面加快网络训练过程。
梯度剪切
这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。
换用不同的激活函数
循环神经网络将RNN替换为LSTM
Sigmoid激活函数
tanh激活函数
Relu激活函数
Leak Relu激活函数
SoftPlus函数
softmax函数
函数定义为: $ \sigma(z)_j = \frac{e^{zj}}{\sum{k=1}^K e^{z_k}} $。
Softmax 多用于多分类神经网络输出。
线性归一化 $$ x^{\prime} = \frac{x-min(x)}{max(x) - min(x)} $$ 适用于数值比较集中的情况;
标准差归一化 $$ x^{\prime} = \frac{x-\mu}{\sigma} $$ 适用于数据符合标准正太分布;
非线性归一化
什么是批归一化?
BN有那些优点?
BN的算法流程?
[基本loss function] [进阶loss function]
常见的卷积主要是由连续紧密的卷积核对输入的图像特征进行滑窗式点乘求和操作,除此之外还有其他类型的卷积核在不同的任务中会用到,具体分类如表5.5所示。 表5.5 卷积核分类
卷积类别 | 示意图 | 作用 |
---|---|---|
标准卷积 | 最常用的卷积核,连续紧密的矩阵形式可以提取图像区域中的相邻像素之间的关联关系,$3\times3$的卷积核可以获得$3\times3$像素范围的感受视野 | |
扩张卷积(带孔卷积或空洞卷积) | 引入一个称作扩张率(Dilation Rate)的参数,使同样尺寸的卷积核可以获得更大的感受视野,相应的在相同感受视野的前提下比普通卷积采用更少的参数。同样是$3\times3$的卷积核尺寸,扩张卷积可以提取$5\times5$范围的区域特征,在实时图像分割领域广泛应用 | |
转置卷积 | 先对原始特征矩阵进行填充使其维度扩大到适配卷积目标输出维度,然后进行普通的卷积操作的一个过程,其输入到输出的维度变换关系恰好与普通卷积的变换关系相反,但这个变换并不是真正的逆变换操作,通常称为转置卷积(Transpose Convolution)而不是反卷积(Deconvolution)。转置卷积常见于目标检测领域中对小目标的检测和图像分割领域还原输入图像尺度。 | |
可分离卷积 | 标准的卷积操作是同时对原始图像$H\times W\times C$三个方向的卷积运算,假设有$K$个相同尺寸的卷积核,这样的卷积操作需要用到的参数为$H\times W\times C\times K$个;若将长宽与深度方向的卷积操作分离出变为$H\times W$与$C$的两步卷积操作,则同样的卷积核个数$K$,只需要$(H\times W + C)\times K$个参数,便可得到同样的输出尺度。可分离卷积(Seperable Convolution)通常应用在模型压缩或一些轻量的卷积神经网络中,如MobileNet$^{[1]}$、Xception$^{[2]}$等 |
在网络结构里面, 一般都存在很多的激活函数, 使用最广泛两个激活函数是sigmoid函数和tanh函数, 这两个函数的导数值都不大于, 也就是说, RNN的多次循环以后, 梯度的大小在不断减小, 最后可能编程很小的小数, 造成梯度消失的现象.
我从三个方面进行考虑:
一是更改激活函数, 比如采用relu激活函数, 在正数部分梯度恒为1, 但是有可能导致梯度爆炸;
二是添加BN层, 在每层卷积后添加BN层, 不仅能对参数归一化, 还能控制过拟合, 加速收敛;
三是更改网络结构, 将RNN更改为LSTM结构;
细胞状态
![Uploading LSTM4.png…]()
LSTM上方是一条贯穿的细胞状态, 类似于传送带,在上面进行细胞交互;
通过读取 h_{t-1} 和输入x_t , sigmoid 输出一个概率表示遗忘的程度f_t;
输入门 第一步, 读入 h_{t-1} 和 输入x_t, sigmoid得到 it 表示要更要什么? 第二步, 读入h{t-1}和输入x_t, tanh得到一个替代的细胞状态 \hat{C_t} 第三步,结合遗忘们和输入门, 决定遗忘什么, 更新什么, 然后得到输出结果C_t
输出门
第一步, 读入 h_{t-1} 和 x_t , 决定输出的内容o_t 第二步, 将o_t 和 C_t 做相乘, 得到应该输出的结果.
这场面试我的是做检测和crowd counting的师姐, 师姐对论文的细节比较关注;
前面问了我两个项目, 最后问了crowd counting相关的和detection相关的;
总结是, 最近有点每太关注detection和crowd counting的文章, 有一些被问到了, 后面也要增加detection方向的论文阅读量 和实践能力;
最后是 做题;
leetcode的原题, 接雨水;
这个题正经思路忘了, 用的stack;
这场面试官好像不是很有耐心, 一上来问我cross entropy的公式, 又让我说RNN和LSTM的区别, 我吐了, 这不是为难人吗?
交叉熵: J=1/n sum_x( yln(a)+(1-y)ln(1-a) )
从上图观察可知,sigmoid函数的导数范围是(0,0.25],tanh函数的导数范围是(0,1],他们的导数最大都不大于1。
梯度消失现象:基于上式,会发现累乘会导致激活函数导数的累乘,如果取tanh或sigmoid函数作为激活函数的话,那么必然是一堆小数在做乘法,结果就是越乘越小。随着时间序列的不断深入,小数的累乘就会导致梯度越来越小直到接近于0,这就是“梯度消失“现象。
实际使用中,会优先选择tanh函数,原因是tanh函数相对于sigmoid函数来说梯度较大,收敛速度更快且引起梯度消失更慢。
如何解决RNN梯度消失问题?
1、选取更好的激活函数,如Relu激活函数。ReLU函数的左侧导数为0,右侧导数恒为1,这就避免了“梯度消失“的发生。但恒为1的导数容易导致“梯度爆炸“,但设定合适的阈值可以解决这个问题。
2、加入BN层,其优点包括可加速收敛、控制过拟合,可以少用或不用Dropout和正则、降低网络对初始化权重不敏感,且能允许使用较大的学习率等。
2、改变传播结构,LSTM结构可以有效解决这个问题。下面将介绍LSTM相关内容。
后面出了一个题目, 一条线上, 有n个建筑物, k个仓库, 要求这k个仓库到n个建筑物的总距离最短;
因为,关于「未来五年计划」的问题,HR真正想了解的,是以下3点:
1、你真的对这个职位感兴趣吗?
2、你能在公司长期稳定的发展吗?
3、你能自主地完成工作吗?
我想把未来的五年计划分为大概3个阶段:
第一个阶段是1年内:
找到一个像阿里这么优秀的公司实习,向周围优秀的师兄师姐学习, 持续加速自己的成长和专业技能的把控。
第二阶段是2-3内: 稳定自己的工作内容和方向,把技术做成T型发展,对自己的方向能够深入了解并掌握, 对相关的知识
常规批开始 5.7
7.15开始投简历 7月中下旬面试 8月下旬发放offer
找工作面试经验记录
自我介绍
时长:3 Min
Detection方向。
在科研方面:
个人博客
简历
面试准备
找到一个自己突出的方向,比较重要