面试题
https://www.cnblogs.com/CheeseZH/p/11927577.html
其他
大数据相关面试题
最大熵模型源码
维特比算法源码
softmax/交叉熵/dropout/Batch Norm/Layer Norm实现
损失函数(MSE/交叉熵/Hinge)
激活函数(sigmoid/tanh)
梯度下降(GD/SGD/BGD/MBGD/Adagrad/RMSprop/Momentum/Adam)
随机数相关题目 https://octman.com/blog/2013-10-20-interview-questions-random-numbers/
# !/usr/bin/env python
# encoding: utf-8
# random choose k from N
import random
# print( random.randint(1,10) ) # 产生 1 到 10 的一个整数型随机数
# print( random.random() ) # 产生 0 到 1 之间的随机浮点数
# print( random.uniform(1.1,5.4) ) # 产生 1.1 到 5.4 之间的随机浮点数,区间可以不是整数
# print( random.choice('tomorrow') ) # 从序列中随机选取一个元素
# print( random.randrange(1,100,2) ) # 生成从1到100的间隔为2的随机整数
def reservior(k, N):
pool = N[0:k] # 如果只有k个,那全选
for i in range(k, len(N)):
# 再来新数据,则考虑替换
m = random.randint(1, i) # 理解1:从前1~i中随机选一个数删除,第m个数
# 理解2:给新来的第i个数找个位置m
if m < k: # 如果第m个处于池子中,就替换成新元素
pool[m] = N[i]
def shuffle(ls):
l = len(ls)
ls = list(ls)
for i in range(l, -1, -1):
j = random.randint(0, i) # 将第j个数当作第i个数,第i个数就固定了,之后不动了
if i != j: # 如果不是原数组的第i个
ls[i], ls[j] = ls[j], ls[i]
def random_choice(m, n, ls):
# 从长度为n的数组ls中随机挑选m个数
out = []
for i, x in enumerate(ls):
j = random.randint(0, n-i) # 从n-i个数中随机挑1个数
if j < m: # 这个数是否需要放到篮子里
out.append(x)
m -= 1 # 篮子大小更新
return out
def word_break(s, wordDict):
if s == "":
return True
dp = [False for _ in range(len(s)+1)]
dp[0] = True # 空字符串一定是True
for i in range(1, len(s)+1):
for j in range(i):
if dp[j] and s[j:i] in wordDict: # dp[j]能够被拆分并且s[j:i]在词表里,表明dp[i]也满足要求
dp[i] = True
break
return dp[-1]
牛客网-《剑指offer》-包含min函数的栈
牛客网-《剑指offer》-调整数组顺序使奇数位于偶数前面
牛客网-《剑指offer》-数值的整数次方[快速幂运算]
牛客网-《剑指offer》-二进制中1的个数
牛客网-《剑指offer》-矩形覆盖
牛客网-《剑指offer》-斐波那契数列
牛客网-《剑指offer》-跳台阶
牛客网-《剑指offer》-变态跳台阶
牛客网-《剑指offer》-旋转数组的最小数
牛客网-《剑指offer》-用两个栈实现队列
牛客网-《剑指offer》-从尾到头打印链表
牛客网-《剑指offer》-替换空格
牛客网-《剑指offer》-二维数组中的查找
牛客网-《剑指offer》-重建二叉树
编辑距离
最长公共子串
最长公共子序列
从无序数组中快速找到第k小的数
排序算法
字典树
class Trie:
def __init__(self):
self.dic={}
def insert(self,strr):
a = self.dic
for i in strr:
if not i in a:
a[i] = {}
a = a[i]
a["end"] = True
def search(self, strr):
a = self.dic
for i in strr:
if not i in a:
return False
a = a[i]
if "end" in a:
return True
else:
return False
def startsWith(self,strr):
a = self.dic
for i in strr:
if not i in a:
return False
a = a[i]
return True
1. 基础的数据结构:插入排序、选择排序 (记下时间复杂度), 链表新增、删除,二叉树的遍历,其他场景算法题大多出自leetcode
2. 逻辑回归损失是什么, 手动推导一遍
3. 对集成学习, SVM的理解,以公式的形式写出来最好
4. 对HMM ,CRF的理解, CRF的损失函数什么,维特比算法的过程
5. 手写一个tfids
6. word2vec的CBOW与SkipGram模型及两种训练方式(负采样\层级softmax), 两种训练方式的区别和应用场景,
7. word2vec和fasttext的区别, 训练word2vec的有哪些重要参数
8. LSTM的单元结构图和6个公式要记住
9. 有几种Attention, Attention和self-Attention是具体怎么实现的,对应什么场景
10. BERT的模型架构,多少层,什么任务适合bert,什么任务不适合,应用在你写的项目改怎么做
11. tensorflow手写一个卷积代码, BILSTM + CRF模型的原理,记住常用基础api(比如jieba添加默认词典api,分词api)
12. 问项目阶段, 会问数据集怎么得到、模型的训练、怎么部署、项目人员周期,开发中出现问题怎么解决等
为什么bert att中要除以sqrt(d)?
当输入信息的维度d比较高,点积模型的值通常有比较大方差,从而导致softmax函数的梯度会比较小。因此,缩放点积模型可以较好地解决这一问题。
https://zhuanlan.zhihu.com/p/22447440
残差连接,为了解决梯度消失的问题,函数加了1个x,相当于给函数对x的导数增加了一个1。
何恺明等人经过一段时间的研究,认为极其深的深度网络可能深受梯度消失问题的困扰,BN、ReLU等手段对于这种程度的梯度消失缓解能力有限,并提出了单位映射的残差结构[7]。这种结构从本源上杜绝了梯度消失的问题:
基于反向传播法计算梯度优化的神经网络,由于反向传播求隐藏层梯度时利用了链式法则,梯度值会进行一系列的连乘,导致浅层隐藏层的梯度会出现剧烈的衰减,这也就是梯度消失问题的本源,这种问题对于Sigmoid激活尤为严重,故后来深度网络均使用ReLU激活来缓解这个问题,但即使是ReLU激活也无法避免由于网络单元本身输出的尺度关系,在极深度条件下成百上千次的连乘带来的梯度消失。
https://mp.weixin.qq.com/s/PzQoX07nglOW1I7Zp4QKLw
mean square error:适用于回归问题,mse=1/n*SUM((y_i-p_i)^2),和正确的预测,错误的预测都有关
cross entropy: 适用于分类问题, ce = -(SUM(s_i*log(p_i))), s_i是one-hot形式的用于选择正确类别的概率,也就是只和正确的结果有关,和错误的无关;
全连接》softmax》cross entropy
区别1:当模型预测正确时,mse和ce的loss都会趋近于0,但是当模型预测错误的时候,ce会给模型更大的惩罚,也就是更大的梯度
区别2:当激活函数是sigmoid或softmax这种两端有饱和区的函数,用mse的时候梯度和激活函数成正比,当处于饱和区的时候,
mse容易出现梯度消失的情况,而用ce的时候,梯度和激活函数值&实际值的差成正比,也就是误差越大,梯度越大。
sigmoid:f(x) = 1/(1+e^(-x)), 呈S型;求导 f'(x) = f(x)(1-f(x)), 呈山丘型,两边接近0,导致梯度更新缓慢 ,最大值1/4
softmax: e_x/SUM(e_i)
hinge损失:2分类,SVM
- max(0, 1-ty), t={-1, 1}, -1负样本,1正样本,y实数预测值
梯度下降(GD)取决于学习率(步长)和梯度(方向)
SGD
BGD
MBGD
Adagrad:更新学习率时考虑历史所有梯度,累加之前所有的梯度平方。
缺点:在训练的中后期,分母上梯度平方的累加将会越来越大,从而学习率趋近于0,使得训练提前结束。
Momentum:更新梯度时考虑历史所有梯度向量(包括方向和大小)
RMSprop:更新学习率时考虑历史所有梯度
RMSprop是计算之前所有梯度的平均值,因此可缓解Adagrad算法学习率下降较快的问题。
Adam:同时调整学习率和梯度
Beta1:0.9,用于调整历史方向的权重,Momentum
Beta2: 0.99,用于调整历史步长的权重,RMSprop
Epsilon:1e-08,平滑因子,防止分母为0
L1正则化:求导之后正负不同,大小固定。
L2正则化:求导之后考虑了大小。
逻辑回归
- 二分类:sigmoid
- 多分类:softmax
线性回归
多元一次方程
激活函数
sigmoid:1/(1+e^-x)
- x偏大/偏小,梯度变化不明显,梯度消失
- exp计算成本高
- 区间范围0~1,更新同一层的参数,只能向同一个方向,导致梯度Z型问题
- 导数最大1/4
tanh
- 区间范围-1~1
- 也存在梯度消失的问题
- 导数小于1
relu
- 前向过程x<0,则神经元处于非激活状态,反向过程没有梯度,神经元进入死区。
leaky-relu
- 小于0时:x/a
elu
- 小于0时:a(e^x-1), 随着x变小,趋于饱和
gelu
- 在elu的基础上增加了随机正则,tf实现:
def gelu(input_tensor):
cdf = 0.5 * (1.0 + tf.erf(input_tensor / tf.sqrt(2.0)))
return input_tesnsor*cdf
初始化
- 0值初始化,网络退化成1个神经元
- 随机初始化,对于较小的值,在反向传播过程中梯度会被削弱,导致网络无法学习
- Xavier,针对tanh激活函数
- He,针对relu激活函数
Batch Normalization:
- 解决:Internal Covariate Shift
- x = gama*(x-E(x))/sqrt(D(x)) + beta
- 经过归一化后,输入向量的每个维度的均值为 0,方差为 1
- 引入 Batch Normalization 之后可以加大学习率,防止了权重参数上较小的变化放大为激活函数上梯度较大的次优的变化
- 通常,大的学习率会增加每层权重参数的大小,权值参数大小的增加进一步在反向传播过程中加大了梯度并导致梯度爆炸。然而,通过 Batch Normalization,反向传播时,将不收权重参数的大小的影响
- 不适用于RNN:对于有固定深度的前向网络来说,对每一层分别存储各自的上述两个统计量是没有问题的,然而对于循环神经网络来说,我们需要计算和保存序列中不同时间步骤的上述两个统计量,若测试序列比所有训练序列均要长,则 Batch Normalization 将会遇到问题。Batch Normalization 无法应用到在线学习任务或者非常大的分布式模型任务上,此时训练的 batch 较小,因此基于较小的 batch 的计算出的均值和方差统计量无法有效表示全局样本的统计量。
Layer Normalization:
- 假设在非线性激活前的输入的随机变量的分布接近,因此可以直接基于每层的所有非线性激活前的输入估计均值和方差,并基于这两个统计量对输入进行均值为 0,方差为 1 的归一化。
- 每层表示1个样例某个时刻的所有特征的值,将身高/体重/年龄统一归一化。
- Layer Normalization 假设在非线性激活前的输入的随机变量的分布接近,而 CNN网络中图像边缘对应的 kernel 由于由大量的隐藏单元未被激活,因此该假设不成立,因此在 CNN 网络中 Layzer Normalization 效果没有 Batch Normalization 效果好。
crf++
- 模版的含义
U04:%x[2,0]
U05:%x[-1,0]/%x[0,0]
- 参数的含义
- c=1.2:惩罚因子,c越大,越容易过拟合
- f=1:特征频数阈值
liblinear速度更快,适合线上使用
- L1/L2正则化
- L1/L2损失
- SVM/Logistic Regression
- one-vs-the rest
- 线性SVM
SVM细节
word2vec训练
x 信息赠一
x 信息赠一笔
SMP细节
x 决策树生成&剪枝
python
java
数据结构
链表
树
排序
查找