到场蒋思源 戴一鸣 张倩

惊为天人,NumPy手写通通主流板滞进修模子,代码超3万行

用 NumPy 手写所有主流 ML 模子,普林斯顿博士后 David Bourgin 近来开源了一个十分剽悍的项目。超越 3 万行代码、30 众个模子,这也许能打制「最强」的板滞进修基石?

NumPy 举措 Python 生态中最受接待的科学盘算包,许众读者曾经十分熟习它了。它为 Python 供应高服从的众维数组盘算,并供应了一系列上等数学函数,我们可以疾速搭修模子的通通盘算流程。毫不认真任地说,NumPy 便是当代深度进修框架的「爸爸」。

尽管目前运用 NumPy 写模子曾经不是主流,但这种方法仍然不失为是了解底层架构和深度进修原理的好方法。近来,来自普林斯顿的一位博士后将 NumPy 完成的所有板滞进修模子通通开源,并供应了相应的论文和少许完成的测试效果。

  • 项目地址:https://github.com/ddbourgin/numpy-ml

依据中文字幕AV的大约估量,该项目大约有 30 个主要板滞进修模子,另外另有 15 个用于预处理和盘算的小东西,通通.py 文献数目有 62 个之众。平均每个模子的代码行数 500 行以上,神经收集模子的 layer.py 文献中,代码行数接近 4000。

这,应当是目前用 NumPy 手写板滞进修模子的「最高地步」吧。

谁用 NumPy 手推了一大波 ML 模子

通过项目标代码目次,我们能发明,作家基本上把主流模子都完成了一遍,这个义务量确实惊为天人。我们发明作家 David Bourgin 也是一位大神,他于 2018 年取得加州大学伯克利分校盘算认知科学博士学位,随后普林斯顿大学从事博士后研讨。

尽管结业不久,David 顶级期刊与盘算时机议上都发外了少许精良论文。近来完毕的 ICML 2019 中,其关于认知模子先验的研讨就被接纳为少有的 Oral 论文。

David Bourgin 小哥哥便是用 NumPy 手写 ML 模子、手推反向传达的大神。这么众的义务量,当然照旧需求许众参考资源的,David 会了解这些资源或完成,并以一种更易读的方法写出来。

正如 reddit 读者所质疑的: autograd repo 中曾经有许众如许的例子,为什么你还要做这个项目?

作家外示,他确实从 autograd repo 学到了许众,但二者的差别之处于,他显式地举行了所有梯度盘算,以特出看法/数学的分明性。当然,这么做的缺陷也很分明,每次需求微分一个新函数时,你都要写出它的公式……

估量 David Bourgin 小哥哥写完这个项目后,板滞进修根底曾经极其稳固了。着末,David 外示下一步会添加文档和示例,以便当大师运用。

项目总体先容

这个项目最大的特性是作家把板滞进修模子都用 NumPy 手写了一遍,包罗更显式的梯度盘算和反向传达进程。可以说它便是一个板滞进修框架了,只不过代码可读性会强许众。

David Bourgin 外示他不停垂垂写或搜罗差别模子与模块的纯 NumPy 完成,它们跑起来可以没那么速,可是模子的精细进程必定足够直观。每当我们念了解模子 API 背后的完成,却又不念看繁杂的框架代码,那么它可以举措疾速的参考。

作品后面会精细先容通通项目都有什么模子,这里先简明先容它的全体构造。如下所示为项目文献,差别的文献夹即差别品种的代码集。

每一个代码集下,作家都会供应差别完成的参考材料,比如模子的效果示例图、参考论文和参考链接等。如下所示,David 完成神经收集层级的进程中,还供应了参考论文。

当然云云庞大的代码总会保管少许 Bug,作家也十分期望我们能一同完美这些完成。假如我们以前用纯 NumPy 完成过某些好玩的模子,那也可以直接提交 PR 央求。因为完成基本上都只依赖于 NumPy,那么状况配备就简单许众了,大师差未几都能跑得动。

手写 NumPy 全家福

作家 GitHub 中供应了模子/模块的完成列外,列外构造基本便是代码文献的构造了。全体上,模子主要分为两部分,即古板板滞进修模子与主流的深度进修模子。

此中浅层模子既有隐马尔可夫模子和晋升方法如许的繁杂模子,也包罗了线性回归或近来邻等经典方法。而深度模子则主要从种种模块、层级、耗损函数、最优化器等角度搭修代码架构,从而能疾速构修种种神经收集。

除了模子外,通通项目另有少许辅帮模块,包罗一堆预处理相关的组件和有用的小东西。

该 repo 的模子或代码构造如下所示:

1. 高斯混淆模子

  • EM 教练

2. 隐马尔可夫模子

  • 维特比解码

  • 似然盘算

  • 通过 Baum-Welch/forward-backward 算法举行 MLE 参数估量

3. 隐狄利克雷分派模子(中心模子)

  • 用变分 EM 举行 MLE 参数估量的标准模子

  • 用 MCMC 举行 MAP 参数估量的腻滑模子

4. 神经收集

4.1 层/层级运算

  • Add

  • Flatten

  • Multiply

  • Softmax

  • 全连接/Dense

  • 希罕进化连接

  • LSTM

  • Elman 立场的 RNN

  • 最大+平均池化

  • 点积当心力

  • 受限玻尔兹曼机 (w. CD-n training)

  • 2D 转置卷积 (w. padding 和 stride)

  • 2D 卷积 (w. padding、dilation 和 stride)

  • 1D 卷积 (w. padding、dilation、stride 和 causality)

4.2 模块

  • 双向 LSTM

  • ResNet 立场的残差块(恒等变换和卷积)

  • WaveNet 立场的残差块(带有扩张因果卷积)

  • Transformer 立场的众头缩放点积当心力

4.3 正则化项

  • Dropout

  • 归一化

  • 批归一化(时间上和空间上)

  • 层归一化(时间上和空间上)

4.4 优化器

  • SGD w/ 动量

  • AdaGrad

  • RMSProp

  • Adam

4.5 进修率调治器

  • 常数

  • 指数

  • Noam/Transformer

  • Dlib 调治器

4.6 权重初始化器

  • Glorot/Xavier uniform 和 normal

  • He/Kaiming uniform 和 normal

  • 标准和截断正态分布初始化

4.7 耗损

  • 交叉熵

  • 平方差

  • Bernoulli VAE 耗损

  • 带有梯度惩办的 Wasserstein 耗损

4.8 激活函数

  • ReLU

  • Tanh

  • Affine

  • Sigmoid

  • Leaky ReLU

4.9 模子

  • Bernoulli 变分自编码器

  • 带有梯度惩办的 Wasserstein GAN

4.10 神经收集东西

  • col2im (MATLAB 端口)

  • im2col (MATLAB 端口)

  • conv1D

  • conv2D

  • deconv2D

  • minibatch

5. 基于树的模子

  • 计划树 (CART)

  • [Bagging] 随机森林

  • [Boosting] 梯度晋升计划树

6. 线性模子

  • 岭回归

  • Logistic 回归

  • 最小二乘法

  • 贝叶斯线性回归 w/共轭先验

7.n 元序列模子

  • 最大似然得分

  • Additive/Lidstone 腻滑

  • 简单 Good-Turing 腻滑

8. 深化进修模子

  • 运用交叉熵方法的智能体

  • 首次拜访 on-policy 蒙特卡罗智能体

  • 加权增量主要采样蒙特卡罗智能体

  • Expected SARSA 智能体

  • TD-0 Q-learning 智能体

  • Dyna-Q / Dyna-Q+ 优先扫描

9. 非参数模子

  • Nadaraya-Watson 核回归

  • k 近来邻分类与回归

10. 预处理

  • 离散傅立叶变换 (1D 信号)

  • 双线性插值 (2D 信号)

  • 近来邻插值 (1D 和 2D 信号)

  • 自相关 (1D 信号)

  • 信号窗口

  • 文天职词

  • 特征哈希

  • 特征标准化

  • One-hot 编码/解码

  • Huffman 编码/解码

  • 词频逆文档频率编码

11. 东西

  • 相似度核

  • 间隔器量

  • 优先级部队

  • Ball tree 数据构造

项目示例

因为代码量庞大,中文字幕AV这里拾掇了少许示例。

比如,完成点积当心力机制

classDotProductAttention(LayerBase):
def__init__(self,scale=True,dropout_p=0,init="glorot_uniform",optimizer=None):
super().__init__(optimizer)
self.init=init
self.scale=scale
self.dropout_p=dropout_p
self.optimizer=self.optimizer
self._init_params()

def_fwd(self,Q,K,V):
scale=1/np.sqrt(Q.shape[-1])ifself.scaleelse1
scores=Q@K.swapaxes(-2,-1)*scale#attentionscores
weights=self.softmax.forward(scores)#attentionweights
Y=weights@V
returnY,weights

def_bwd(self,dy,q,k,v,weights):
d_k=k.shape[-1]
scale=1/np.sqrt(d_k)ifself.scaleelse1

dV=weights.swapaxes(-2,-1)@dy
dWeights=dy@v.swapaxes(-2,-1)
dScores=self.softmax.backward(dWeights)
dQ=dScores@k*scale
dK=dScores.swapaxes(-2,-1)@q*scale
returndQ,dK,dV

以上代码中,Q、K、V 三个向量输入到「_fwd」函数中,用于盘算每个向量的当心力分数,并通过 softmax 的方法取得权重。而「_bwd」函数则盘算 V、当心力权重、当心力分数、Q 和 K 的梯度,用于更新收集权重。

少许完成中,作家也举行了测试,并给出了测试结果。如图为隐狄利克雷(Latent Dirichlet allocation,LDA)完成举行文本聚类的结果。左图为词语特定中心中的分布热力图。右图则为文档特定中心中的分布热力图。

隐狄利克雷分布完成的效果。

初学Numpy
81
相关数据
当心力机制技能

我们可以大约地把神经当心绪制类比成一个可以笃志于输入实质的某一子集(或特征)的神经收集. 当心力机制最早是由 DeepMind 为图像分类提出的,这让「神经收集施行预测义务时可以更众体恤输入中的相关部分,更少体恤不相关的部分」。当解码器生成一个用于构成目标句子的词时,源句子中仅有少部分是相关的;于是,可以运用一个基于实质的当心力机制来依据源句子动态地生成一个(加权的)语境向量(context vector), 然后收集会依据这个语境向量而不是某个固定长度的向量来预测词。

高斯混淆模子技能

高斯混淆模子(Gaussian Mixture Model,GMM)是简单高斯概率密度函数的延迟,便是用众个高斯概率密度函数(正态分布弧线)准确地量化变量分布,是将变量分布剖析为若干基于高斯概率密度函数(正态分布弧线)分布的统计模子。

隐马尔可夫模子技能

隐马尔可夫模子(Hidden Markov Model,HMM)是统计模子,它用来描画一个含有隐含未知参数的马尔可夫进程。其难点是从可察看的参数中确定该进程的隐含参数。然后应用这些参数来作进一步的剖析,比如方式识别。

受限玻尔兹曼机技能

受限玻尔兹曼机(英语:restricted Boltzmann machine, RBM)是一种可通过输入数据集进修概率分布的随机生成神经收集。RBM最初由发明者保罗·吮ィ棱斯基于1986年命名为簧风琴(Harmonium),但直到杰弗里·辛顿及其协作家2000年代中叶发明疾速进修算法后,受限玻兹曼机才变得出名。受限玻兹曼机降维、分类、协同过滤、特征进修和中心修模中取得了运用。依据义务的差别,受限玻兹曼机可以运用监视进修或无监视进修的方法举行教练。受限玻兹曼机也可被用于深度进修收集。精细地,深度信心收集可运用众个RBM堆叠而成,并可运用梯度下降法和反向传达算法举行调优。