A. 循环神经网络
花书中关于RNN的内容记录于 https://www.jianshu.com/p/206090600f13 。
在前馈神经网络中,信息的传递是单向的,这种限制虽然使得网络变得更容易学习,但在一定程度上也减弱了神经网络模型的能力。在生物神经网络中,神经元之间的连接关系要复杂的多。 前馈神经网络可以看作是一个复杂的函数,每次输入都是独立的,即网络的输出只依赖于当前的输入。但是在很多现实任务中,网络的输入不仅和当前时刻的输入相关,也和其过去一段时间的输出相关 。因此,前馈网络难以处理时序数据,比如视频、语音、文本等。时序数据的长度一般是不固定的,而前馈神经网络要求输入和输出的维数都是固定的,不能任意改变。因此,当处理这一类和时序相关的问题时,就需要一种能力更强的模型。
循环神经网络(Recurrent Neural Network,RNN)是一类具有短期记忆能力的神经网络。在循环神经网络中,神经元不但可以接受其它神经元的信息,也可以接受自身的信息,形成具有环路的网络结构。 和前馈神经网络相比,循环神经网络更加符合生物神经网络的结构。循环神经网络已经被广泛应用在语音识别、语言模型以及自然语言生成等任务上。循环神经网络的参数学习可以通过 随时间反向传播算法 来学习。
为了处理这些时序数据并利用其历史信息,我们需要让网络具有短期记忆能力。而前馈网络是一个静态网络,不具备这种记忆能力。
一种简单的利用历史信息的方法是建立一个额外的延时单元,用来存储网络的历史信息(可以包括输入、输出、隐状态等)。比较有代表性的模型是延时神经网络。
延时神经网络是在前馈网络中的非输出层都添加一个延时器,记录最近几次神经元的输出。在第 个时刻,第 层神经元和第 层神经元的最近 次输出相关,即:
延时神经网络在时间维度上共享权值,以降低参数数量。因此对于序列输入来讲,延时神经网络就相当于卷积神经网络 。
自回归模型(Autoregressive Model,AR) 是统计学上常用的一类时间序列模型,用一个变量 的历史信息来预测自己:
其中 为超参数, 为参数, 为第 个时刻的噪声,方差 和时间无关。
有外部输入的非线性自回归模型(Nonlinear Autoregressive with ExogenousInputs Model,NARX) 是自回归模型的扩展,在每个时刻 都有一个外部输入 ,产生一个输出 。NARX通过一个延时器记录最近几次的外部输入和输出,第 个时刻的输出 为:
其中 表示非线性函数,可以是一个前馈网络, 和 为超参数。
循环神经网络通过使用带自反馈的神经元,能够处理任意长度的时序数据。
给定一个输入序列 ,循环神经网络通过下面
公式更新带反馈边的隐藏层的活性值 :
其中 , 为一个非线性函数,也可以是一个前馈网络。
从数学上讲,上式可以看成一个动力系统。动力系统(Dynamical System)是一个数学上的概念,指 系统状态按照一定的规律随时间变化的系统 。具体地讲,动力系统是使用一个函数来描述一个给定空间(如某个物理系统的状态空间)中所有点随时间的变化情况。因此, 隐藏层的活性值 在很多文献上也称为状态(State)或隐状态(Hidden States) 。理论上,循环神经网络可以近似任意的非线性动力系统。
简单循环网络(Simple Recurrent Network,SRN)是一个非常简单的循环神经网络,只有一个隐藏层的神经网络。
在一个两层的前馈神经网络中,连接存在相邻的层与层之间,隐藏层的节点之间是无连接的。而 简单循环网络增加了从隐藏层到隐藏层的反馈连接 。
假设在时刻 时,网络的输入为 ,隐藏层状态(即隐藏层神经元活性值) 不仅和当前时刻的输入 相关,也和上一个时刻的隐藏层状态 相关:
其中 为隐藏层的净输入, 是非线性激活函数,通常为Logistic函数或Tanh函数, 为状态-状态权重矩阵, 为状态-输入权重矩阵, 为偏置。上面两式也经常直接写为:
如果我们把每个时刻的状态都看作是前馈神经网络的一层的话,循环神经网络可以看作是在时间维度上权值共享的神经网络 。下图给出了按时间展开的循环神经网络。
由于循环神经网络具有短期记忆能力,相当于存储装置,因此其计算能力十分强大。 前馈神经网络可以模拟任何连续函数,而循环神经网络可以模拟任何程序。
定义一个完全连接的循环神经网络,其输入为 ,输出为 :
其中 为隐状态, 为非线性激活函数, 和 为网络参数。
这样一个完全连接的循环神经网络可以近似解决所有的可计算问题 。
循环神经网络可以应用到很多不同类型的机器学习任务。根据这些任务的特点可以分为以下几种模式: 序列到类别模式、同步的序列到序列模式、异步的序列到序列模式 。
序列到类别模式主要用于序列数据的分类问题:输入为序列,输出为类别。比如在文本分类中,输入数据为单词的序列,输出为该文本的类别。
假设一个样本 为一个长度为 的序列,输出为一个类别 。我们可以将样本 按不同时刻输入到循环神经网络中,并得到不同时刻的隐藏状态 。我们可以将 看作整个序列的最终表示(或特征),并输入给分类器 进行分类:
其中 可以是简单的线性分类器(比如Logistic 回归)或复杂的分类器(比如多层前馈神经网络)
除了将最后时刻的状态作为序列表示之外,我们还可以对整个序列的所有状态进行平均,并用这个平均状态来作为整个序列的表示:
同步的序列到序列模式 主要用于序列标注(Sequence Labeling)任务,即每一时刻都有输入和输出,输入序列和输出序列的长度相同 。比如词性标注(Partof-Speech Tagging)中,每一个单词都需要标注其对应的词性标签。
输入为序列 ,输出为序列 。样本 按不同时刻输入到循环神经网络中,并得到不同时刻的隐状态 。每个时刻的隐状态 代表当前和历史的信息,并输入给分类器 得到当前时刻的标签 。
异步的序列到序列模式也称为 编码器-解码器(Encoder-Decoder)模型,即输入序列和输出序列不需要有严格的对应关系,也不需要保持相同的长度。 比如在机器翻译中,输入为源语言的单词序列,输出为目标语言的单词序列。
在异步的序列到序列模式中,输入为长度为 的序列 ,输出为长度为 的序列 。经常通过 先编码后解码 的方式来实现。先将样本 按不同时刻输入到一个循环神经网络(编码器)中,并得到其编码 。然后再使用另一个循环神经网络(解码器)中,得到输出序列 。为了建立输出序列之间的依赖关系,在解码器中通常使用非线性的自回归模型。
其中 分别为用作编码器和解码器的循环神经网络, 为分类器, 为预测输出 的向量表示。
循环神经网络的参数可以通过梯度下降方法来进行学习。给定一个训练样本 ,其中 为长度是 的输入序列, 是长度为 的标签序列。即在每个时刻 ,都有一个监督信息 ,我们定义时刻 的损失函数为:
其中 为第 时刻的输出, 为可微分的损失函数,比如交叉熵。那么整个序列上损失函数为:
整个序列的损失函数 关于参数 的梯度为:
即每个时刻损失 对参数 的偏导数之和。
循环神经网络中存在一个递归调用的函数 ,因此其计算参数梯度的方式和前馈神经网络不太相同。在循环神经网络中主要有两种计算梯度的方式: 随时间反向传播(BPTT)和实时循环学习(RTRL)算法。
随时间反向传播(Backpropagation Through Time,BPTT) 算法的主要思想是通过类似前馈神经网络的错误反向传播算法来进行计算梯度。
BPTT算法将循环神经网络看作是一个展开的多层前馈网络,其中“每一层”对应循环网络中的“每个时刻”。在“展开”的前馈网络中,所有层的参数是共享的,因此参数的真实梯度是将所有“展开层”的参数梯度之和 。
因为参数 和隐藏层在每个时刻 的净输入 有关,因此第 时刻的损失函数 关于参数 的梯度为:
其中 表示“直接”偏导数,即公式 中保持 不变,对 求偏导数,得到:
其中 为第 时刻隐状态的第 维; 除了第 个值为 外,其余都为 的行向量。
定义误差项 为第 时刻的损失对第 时刻隐藏神经层的净输入 的导数,则:
从而:
写成矩阵形式为:
由此得到整个序列的损失函数 关于参数 的梯度:
同理可得, 关于权重 和偏置 的梯度为:
在BPTT算法中,参数的梯度需要在一个完整的“前向”计算和“反向”计算后才能得到并进行参数更新。如下图所示。
与反向传播的BPTT算法不同的是,实时循环学习(Real-Time Recurrent Learning)是通过前向传播的方式来计算梯度。
假设循环神经网络中第 时刻的状态 为:
其关于参数 的偏导数为:
RTRL算法从第1 个时刻开始,除了计算循环神经网络的隐状态之外,还依次前向计算偏导数 。
两种学习算法比较:
RTRL算法和BPTT算法都是基于梯度下降的算法,分别通过前向模式和反向模式应用链式法则来计算梯度。 在循环神经网络中,一般网络输出维度远低于输入维度,因此BPTT算法的计算量会更小,但BPTT算法需要保存所有时刻的中间梯度,空间复杂度较高。RTRL算法不需要梯度回传,因此非常适合于需要在线学习或无限序列的任务中 。
循环神经网络在学习过程中的主要问题是由于 梯度消失或爆炸问题 ,很难建模长时间间隔(Long Range)的状态之间的依赖关系。
在BPTT算法中,我们有:
如果定义 ,则:
若 ,当 时, ,会造成系统不稳定,称为梯度爆炸问题;相反,若 ,当 时, ,会出现和深度前馈神经网络类似的梯度消失问题。
虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系,但是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系。这样,如果t时刻的输出 依赖于 时刻的输入 ,当间隔 比较大时,简单神经网络很难建模这种长距离的依赖关系,称为 长程依赖问题(Long-Term dependencies Problem) 。
一般而言,循环网络的梯度爆炸问题比较容易解决,一般 通过权重衰减或梯度截断来避免。 权重衰减是通过给参数增加 或 范数的正则化项来限制参数的取值范围,从而使得 。梯度截断是另一种有效的启发式方法,当梯度的模大于一定阈值时,就将它截断成为一个较小的数。
梯度消失是循环网络的主要问题。除了使用一些优化技巧外,更有效的方式就是改变模型,比如让 ,同时使用 ,即:
其中 是一个非线性函数, 为参数。
上式中, 和 之间为线性依赖关系,且权重系数为1,这样就不存在梯度爆炸或消失问题。但是,这种改变也丢失了神经元在反馈边上的非线性激活的性质,因此也降低了模型的表示能力。
为了避免这个缺点,我们可以采用一种更加有效的改进策略:
这样 和 之间为既有线性关系,也有非线性关系,并且可以缓解梯度消失问题。但这种改进依然存在两个问题:
为了解决这两个问题,可以通过引入 门控机制 来进一步改进模型。
为了改善循环神经网络的长程依赖问题,一种非常好的解决方案是引入门控机制来控制信息的累积速度,包括 有选择地加入新的信息,并有选择地遗忘之前累积的信息 。这一类网络可以称为基于门控的循环神经网络(Gated RNN)。本节中,主要介绍两种基于门控的循环神经网络: 长短期记忆网络和门控循环单元网络。
长短期记忆(Long Short-Term Memory,LSTM)网络 是循环神经网络的一个变体,可以有效地解决简单循环神经网络的梯度爆炸或消失问题。
在 基础上,LSTM网络主要改进在以下两个方面:
其中 和 三个门(gate)来控制信息传递的路径; 为向量元素乘积; 为上一时刻的记忆单元; 是通过非线性函数得到的候选状态:
在每个时刻 ,LSTM网络的内部状态 记录了到当前时刻为止的历史信息。
在数字电路中,门(Gate)为一个二值变量{0, 1},0代表关闭状态,不许任何信息通过;1代表开放状态,允许所有信息通过。LSTM网络中的“门”是一种“软”门,取值在(0, 1) 之间,表示 以一定的比例运行信息通过 。LSTM网络中三个门的作用为:
(1)遗忘门 控制上一个时刻的内部状态 需要遗忘多少信息。
(2)输入门 控制当前时刻的候选状态 有多少信息需要保存。
(3)输出门
B. BP神经网络中的激励函数除了S型函数,还有什么函数
一般来说,神经网络的激励函数有以下几种:阶跃函数 ,准线性函数,双曲正切函数,Sigmoid函数等等,其中sigmoid函数就是你所说的S型函数。以我看来,在你训练神经网络时,激励函数是不轻易换的,通常设置为S型函数。如果你的神经网络训练效果不好,应从你所选择的算法上和你的数据上找原因。算法上BP神经网络主要有自适应学习速率动量梯度下降反向传播算法(traingdx),Levenberg-Marquardt反向传播算法(trainlm)等等,我列出的这两种是最常用的,其中BP默认的是后一种。数据上,看看是不是有误差数据,如果有及其剔除,否则也会影响预测或识别的效果。
C. 神经网络模型-27种神经网络模型们的简介
【1】Perceptron(P) 感知机
【1】感知机
感知机是我们知道的最简单和最古老的神经元模型,它接收一些输入,然后把它们加总,通过激活函数并传递到输出层。
【2】Feed Forward(FF)前馈神经网络
【2】前馈神经网络
前馈神经网络(FF),这也是一个很古老的方法——这种方法起源于50年代。它的工作原理通常遵循以下规则:
1.所有节点都完全连接
2.激活从输入层流向输出,无回环
3.输入和输出之间有一层(隐含层)
在大多数情况下,这种类型的网络使用反向传播方法进行训练。
【3】Radial Basis Network(RBF) RBF神经网络
【3】RBF神经网络
RBF 神经网络实际上是 激活函数是径向基函数 而非逻辑函数的FF前馈神经网络(FF)。两者之间有什么区别呢?
逻辑函数--- 将某个任意值映射到[0 ,... 1]范围内来,回答“是或否”问题。适用于分类决策系统,但不适用于连续变量。
相反, 径向基函数--- 能显示“我们距离目标有多远”。 这完美适用于函数逼近和机器控制(例如作为PID控制器的替代)。
简而言之,RBF神经网络其实就是, 具有不同激活函数和应用方向的前馈网络 。
【4】Deep Feed Forword(DFF)深度前馈神经网络
【4】DFF深度前馈神经网络
DFF深度前馈神经网络在90年代初期开启了深度学习的潘多拉盒子。 这些依然是前馈神经网络,但有不止一个隐含层 。那么,它到底有什么特殊性?
在训练传统的前馈神经网络时,我们只向上一层传递了少量的误差信息。由于堆叠更多的层次导致训练时间的指数增长,使得深度前馈神经网络非常不实用。 直到00年代初,我们开发了一系列有效的训练深度前馈神经网络的方法; 现在它们构成了现代机器学习系统的核心 ,能实现前馈神经网络的功能,但效果远高于此。
【5】Recurrent Neural Network(RNN) 递归神经网络
【5】RNN递归神经网络
RNN递归神经网络引入不同类型的神经元——递归神经元。这种类型的第一个网络被称为约旦网络(Jordan Network),在网络中每个隐含神经元会收到它自己的在固定延迟(一次或多次迭代)后的输出。除此之外,它与普通的模糊神经网络非常相似。
当然,它有许多变化 — 如传递状态到输入节点,可变延迟等,但主要思想保持不变。这种类型的神经网络主要被使用在上下文很重要的时候——即过去的迭代结果和样本产生的决策会对当前产生影响。最常见的上下文的例子是文本——一个单词只能在前面的单词或句子的上下文中进行分析。
【6】Long/Short Term Memory (LSTM) 长短时记忆网络
【6】LSTM长短时记忆网络
LSTM长短时记忆网络引入了一个存储单元,一个特殊的单元,当数据有时间间隔(或滞后)时可以处理数据。递归神经网络可以通过“记住”前十个词来处理文本,LSTM长短时记忆网络可以通过“记住”许多帧之前发生的事情处理视频帧。 LSTM网络也广泛用于写作和语音识别。
存储单元实际上由一些元素组成,称为门,它们是递归性的,并控制信息如何被记住和遗忘。
【7】Gated Recurrent Unit (GRU)
【7】GRU是具有不同门的LSTM
GRU是具有不同门的LSTM。
听起来很简单,但缺少输出门可以更容易基于具体输入重复多次相同的输出,目前此模型在声音(音乐)和语音合成中使用得最多。
实际上的组合虽然有点不同:但是所有的LSTM门都被组合成所谓的更新门(Update Gate),并且复位门(Reset Gate)与输入密切相关。
它们比LSTM消耗资源少,但几乎有相同的效果。
【8】Auto Encoder (AE) 自动编码器
【8】AE自动编码器
Autoencoders自动编码器用于分类,聚类和特征压缩。
当您训练前馈(FF)神经网络进行分类时,您主要必须在Y类别中提供X个示例,并且期望Y个输出单元格中的一个被激活。 这被称为“监督学习”。
另一方面,自动编码器可以在没有监督的情况下进行训练。它们的结构 - 当隐藏单元数量小于输入单元数量(并且输出单元数量等于输入单元数)时,并且当自动编码器被训练时输出尽可能接近输入的方式,强制自动编码器泛化数据并搜索常见模式。
【9】Variational AE (VAE) 变分自编码器
【9】VAE变分自编码器
变分自编码器,与一般自编码器相比,它压缩的是概率,而不是特征。
尽管如此简单的改变,但是一般自编码器只能回答当“我们如何归纳数据?”的问题时,变分自编码器回答了“两件事情之间的联系有多强大?我们应该在两件事情之间分配误差还是它们完全独立的?”的问题。
【10】Denoising AE (DAE) 降噪自动编码器
【10】DAE降噪自动编码器
虽然自动编码器很酷,但它们有时找不到最鲁棒的特征,而只是适应输入数据(实际上是过拟合的一个例子)。
降噪自动编码器(DAE)在输入单元上增加了一些噪声 - 通过随机位来改变数据,随机切换输入中的位,等等。通过这样做,一个强制降噪自动编码器从一个有点嘈杂的输入重构输出,使其更加通用,强制选择更常见的特征。
【11】Sparse AE (SAE) 稀疏自编码器
【11】SAE稀疏自编码器
稀疏自编码器(SAE)是另外一个有时候可以抽离出数据中一些隐藏分组样试的自动编码的形式。结构和AE是一样的,但隐藏单元的数量大于输入或输出单元的数量。
【12】Markov Chain (MC) 马尔科夫链
【12】Markov Chain (MC) 马尔科夫链
马尔可夫链(Markov Chain, MC)是一个比较老的图表概念了,它的每一个端点都存在一种可能性。过去,我们用它来搭建像“在单词hello之后有0.0053%的概率会出现dear,有0.03551%的概率出现you”这样的文本结构。
这些马尔科夫链并不是典型的神经网络,它可以被用作基于概率的分类(像贝叶斯过滤),用于聚类(对某些类别而言),也被用作有限状态机。
【13】Hopfield Network (HN) 霍普菲尔网络
【13】HN霍普菲尔网络
霍普菲尔网络(HN)对一套有限的样本进行训练,所以它们用相同的样本对已知样本作出反应。
在训练前,每一个样本都作为输入样本,在训练之中作为隐藏样本,使用过之后被用作输出样本。
在HN试着重构受训样本的时候,他们可以用于给输入值降噪和修复输入。如果给出一半图片或数列用来学习,它们可以反馈全部样本。
【14】Boltzmann Machine (BM) 波尔滋曼机
【14】 BM 波尔滋曼机
波尔滋曼机(BM)和HN非常相像,有些单元被标记为输入同时也是隐藏单元。在隐藏单元更新其状态时,输入单元就变成了输出单元。(在训练时,BM和HN一个一个的更新单元,而非并行)。
这是第一个成功保留模拟退火方法的网络拓扑。
多层叠的波尔滋曼机可以用于所谓的深度信念网络,深度信念网络可以用作特征检测和抽取。
【15】Restricted BM (RBM) 限制型波尔滋曼机
【15】 RBM 限制型波尔滋曼机
在结构上,限制型波尔滋曼机(RBM)和BM很相似,但由于受限RBM被允许像FF一样用反向传播来训练(唯一的不同的是在反向传播经过数据之前RBM会经过一次输入层)。
【16】Deep Belief Network (DBN) 深度信念网络
【16】DBN 深度信念网络
像之前提到的那样,深度信念网络(DBN)实际上是许多波尔滋曼机(被VAE包围)。他们能被连在一起(在一个神经网络训练另一个的时候),并且可以用已经学习过的样式来生成数据。
【17】Deep Convolutional Network (DCN) 深度卷积网络
【17】 DCN 深度卷积网络
当今,深度卷积网络(DCN)是人工神经网络之星。它具有卷积单元(或者池化层)和内核,每一种都用以不同目的。
卷积核事实上用来处理输入的数据,池化层是用来简化它们(大多数情况是用非线性方程,比如max),来减少不必要的特征。
他们通常被用来做图像识别,它们在图片的一小部分上运行(大约20x20像素)。输入窗口一个像素一个像素的沿着图像滑动。然后数据流向卷积层,卷积层形成一个漏斗(压缩被识别的特征)。从图像识别来讲,第一层识别梯度,第二层识别线,第三层识别形状,以此类推,直到特定的物体那一级。DFF通常被接在卷积层的末端方便未来的数据处理。
【18】Deconvolutional Network (DN) 去卷积网络
【18】 DN 去卷积网络
去卷积网络(DN)是将DCN颠倒过来。DN能在获取猫的图片之后生成像(狗:0,蜥蜴:0,马:0,猫:1)一样的向量。DNC能在得到这个向量之后,能画出一只猫。
【19】Deep Convolutional Inverse Graphics Network (DCIGN) 深度卷积反转图像网络
【19】 DCIGN 深度卷积反转图像网络
深度卷积反转图像网络(DCIGN),长得像DCN和DN粘在一起,但也不完全是这样。
事实上,它是一个自动编码器,DCN和DN并不是作为两个分开的网络,而是承载网路输入和输出的间隔区。大多数这种神经网络可以被用作图像处理,并且可以处理他们以前没有被训练过的图像。由于其抽象化的水平很高,这些网络可以用于将某个事物从一张图片中移除,重画,或者像大名鼎鼎的CycleGAN一样将一匹马换成一个斑马。
【20】Generative Adversarial Network (GAN) 生成对抗网络
【20】 GAN 生成对抗网络
生成对抗网络(GAN)代表了有生成器和分辨器组成的双网络大家族。它们一直在相互伤害——生成器试着生成一些数据,而分辨器接收样本数据后试着分辨出哪些是样本,哪些是生成的。只要你能够保持两种神经网络训练之间的平衡,在不断的进化中,这种神经网络可以生成实际图像。
【21】Liquid State Machine (LSM) 液体状态机
【21】 LSM 液体状态机
液体状态机(LSM)是一种稀疏的,激活函数被阈值代替了的(并不是全部相连的)神经网络。只有达到阈值的时候,单元格从连续的样本和释放出来的输出中积累价值信息,并再次将内部的副本设为零。
这种想法来自于人脑,这些神经网络被广泛的应用于计算机视觉,语音识别系统,但目前还没有重大突破。
【22】Extreme Learning Machine (ELM) 极端学习机
【22】ELM 极端学习机
极端学习机(ELM)是通过产生稀疏的随机连接的隐藏层来减少FF网络背后的复杂性。它们需要用到更少计算机的能量,实际的效率很大程度上取决于任务和数据。
【23】Echo State Network (ESN) 回声状态网络
【23】 ESN 回声状态网络
回声状态网络(ESN)是重复网络的细分种类。数据会经过输入端,如果被监测到进行了多次迭代(请允许重复网路的特征乱入一下),只有在隐藏层之间的权重会在此之后更新。
据我所知,除了多个理论基准之外,我不知道这种类型的有什么实际应用。。。。。。。
【24】Deep Resial Network (DRN) 深度残差网络
【24】 DRN 深度残差网络
深度残差网络(DRN)是有些输入值的部分会传递到下一层。这一特点可以让它可以做到很深的层级(达到300层),但事实上它们是一种没有明确延时的RNN。
【25】Kohonen Network (KN) Kohonen神经网络
【25】 Kohonen神经网络
Kohonen神经网络(KN)引入了“单元格距离”的特征。大多数情况下用于分类,这种网络试着调整它们的单元格使其对某种特定的输入作出最可能的反应。当一些单元格更新了, 离他们最近的单元格也会更新。
像SVM一样,这些网络总被认为不是“真正”的神经网络。
【26】Support Vector Machine (SVM)
【26】 SVM 支持向量机
支持向量机(SVM)用于二元分类工作,无论这个网络处理多少维度或输入,结果都会是“是”或“否”。
SVM不是所有情况下都被叫做神经网络。
【27】Neural Turing Machine (NTM) 神经图灵机
【27】NTM 神经图灵机
神经网络像是黑箱——我们可以训练它们,得到结果,增强它们,但实际的决定路径大多数我们都是不可见的。
神经图灵机(NTM)就是在尝试解决这个问题——它是一个提取出记忆单元之后的FF。一些作者也说它是一个抽象版的LSTM。
记忆是被内容编址的,这个网络可以基于现状读取记忆,编写记忆,也代表了图灵完备神经网络。
D. 循环神经网络
为什么卷积神经网络不会出现严重的数值问题呢?
卷积神经网络中每一层的权重矩阵 W 是不同的,并且在初始化时它们是独立同分布的,因此可以相互抵消,在多层之后一般不会出现严重的数值问题。
循环神经网络采用 ReLu 激活函数,只有当 W 的取值在单位矩阵附近时才能取得比较好的效果,因此需要将 W 初始化为单位矩阵。
Seq2Seq 模型最基础的解码方法是贪心法,即选取一种度量标准后,每次都在当前状态下选择最佳的一个结果,直到结束。贪心法的计算代价低,适合作为基准结果与其他方法相比较。贪心法获得的是一个局部最优解,由于实际问题的复杂性,该方法往往不能取得最好的结果。
集束搜索: 是一种启发式算法,会保存 beam size 个当前的较佳选择,然后解码时每一步根据保存的选则进行下一步扩展和排序,接着选择前 b 个进行保存,循环迭代,知道结束时选择最佳的一个作为解码的结果。 b 往往选择一个适中的范围,以 8-12 为佳。
Seq2Seq 模型引入注意力机制是为了解决什么问题?为什么选用了双向的循环神经网络模型?
编码时输入序列的全部信息压缩到了一个向量中,随着序列增长,句子越前面的词的信息丢失越严重。同时,Seq2Seq 模型的输出序列中,常常会损失部分输入序列信息,这是解码时,当前词及对应的源语言词的上下文信息和位置信息在编解码过程中丢失了。 引入注意力机制,解决上述问题 。使用双向的循环神经网络进行建模,可以获取前后文的信息。
E. MATLAB中一些函数,用于神经网络
一:minmax()
minmax(A) 即是求解A矩阵中每个 行向量 中的最小值和最大值
eg:A=[1 2 4 -6 ;
3 -4 90 6;
4 6 -23 -35];
P=minmax(A)
P = -6 4
-4 90
-35 6
二:hold on 和hold off
hold on 是当前轴及图像保持而不被刷新,准备接受此后将绘制的图形,多图共存.即,启动图形保持功能,当前坐标轴和图形都将保持,从此绘制的图形都将添加在这个图形的基础上,并自动调整坐标轴的范围。
hold off 使当前轴及图像不再具备被刷新的性质,新图出现时,取消原图。即,关闭图形保持功能。
hold on 和hold off,是相对使用的
前者的意思是,你在当前图的轴(坐标系)中画了一幅图,再画另一幅图时,原来的图还在,与新图共存,都看得到
后者表达的是,你在当前图的轴(坐标系)中画了一幅图,此时,状态是hold off,则再画另一幅图时,原来的图就看不到了,在轴上绘制的是新图,原图被替换了。
三:rand 和 randn
rand是0-1的均匀分布,randn是均值为0方差为1的正态分布;
rand(n)或randn(n)生成n*n的随机数矩阵。
rand(n,m)或randn(m,n)生成m*n的随机数矩阵。
四:gac、gca 和 gco
gcf 返回当前Figure对象的句柄值
gca 返回当前axes对象的句柄值
gco 返回当前鼠标单击的句柄值,该对象可以是除root对象外的任意图形对象,并且Matlab会把当前图形对象的句柄值存放在Figure的CurrentObject属性中。
五:compet
compet是神经网络的竞争传递函数,用于指出矩阵中每列的最大值。对应最大值的行的值为1,其他行的值都为0。
六:bar和barn
二维条形图:bar()
bar(Y) 如果Y为矢量,其每一个元素绘制一个条形;如果Y为矩阵,侧bar函数对每一行元素绘制的条形进行分组。
bar(x,Y) 按x中指定的位置绘制Y中每一元素的条形。
bar(…,width) 设置相邻条形的宽度并控制组内条形的分离,默认值为0.8,如果指定width=1,则组内的条形挨在一起。
bar(…,’style’) 指定绘制条形的类型,style有两个选项:(1) stacked 矩阵Y中每一行绘制一个条形,条形的高度为行元素中元素的和,每一个条形都用多种颜色表示,颜色对应不同种类的元素并表示每行元素对总和的相对贡献。(2) group 绘制n条形图组,每一个条形组中有m个垂直条形,其中n对应矩阵Y的行数,m对应列数,group为style的默认值。
bar(…,LineSpec) 用LineSpec指定的颜色绘制条形。
h=bar(…) 返回图形句柄。
barh(…) 绘制水平条形图。
h=barh(…) 返回水平条形图的图形句柄。
三维条形图:bar3()和barah()
bar3(Y) 绘制三维条形图,如果Y为矢量,其每一个元素绘制一个条形;如果Y为矩阵,侧bar函数对每一行元素绘制的条形进行分组。
bar3(x,Y) 按x中指定的位置绘制Y中每一元素的条形。
bar3(…,width) 设置相邻条形的宽度并控制组内条形的分离,默认值为0.8,如果指定width=1,则组内的条形挨在一起。
bar3(…,’style’) 指定绘制条形的类型,style有3个选项:(1) stacked 矩阵Y中每一行绘制一个条形,条形的高度为行元素中元素的和,每一个条形都用多种颜色表示,颜色对应不同种类的元素并表示每行元素对总和的相对贡献。(2) group 绘制n条形图组,每一个条形组中有m个垂直条形,其中n对应矩阵Y的行数,m对应列数,group为style的默认值。(3) detached 在x方向用单独的条形块绘制Y中的每一行元素,detached为style的默认值;
bar3(…,LineSpec) 用LineSpec指定的颜色绘制条形。
h=bar3(…) 返回三维条形图的图形句柄。
barh(…) 绘制三维水平条形图。
h=barh(…) 返回三维水平条形图的图形句柄。
三维条形图有两种显示形式:分组形式和行列形式。
未完待续
F. 如何用PyTorch实现递归神经网络
从 Siri 到谷歌翻译,深度神经网络已经在机器理解自然语言方面取得了巨大突破。这些模型大多数将语言视为单调的单词或字符序列,并使用一种称为循环神经网络(recurrent neural network/RNN)的模型来处理该序列。但是许多语言学家认为语言最好被理解为具有树形结构的层次化词组,一种被称为递归神经网络(recursive neural network)的深度学习模型考虑到了这种结构,这方面已经有大量的研究。虽然这些模型非常难以实现且效率很低,但是一个全新的深度学习框架 PyTorch 能使它们和其它复杂的自然语言处理模型变得更加容易。
虽然递归神经网络很好地显示了 PyTorch 的灵活性,但它也广泛支持其它的各种深度学习框架,特别的是,它能够对计算机视觉(computer vision)计算提供强大的支撑。PyTorch 是 Facebook AI Research 和其它几个实验室的开发人员的成果,该框架结合了 Torch7 高效灵活的 GPU 加速后端库与直观的 Python 前端,它的特点是快速成形、代码可读和支持最广泛的深度学习模型。
开始 SPINN
链接中的文章(https://github.com/jekbradbury/examples/tree/spinn/snli)详细介绍了一个递归神经网络的 PyTorch 实现,它具有一个循环跟踪器(recurrent tracker)和 TreeLSTM 节点,也称为 SPINN——SPINN 是深度学习模型用于自然语言处理的一个例子,它很难通过许多流行的框架构建。这里的模型实现部分运用了批处理(batch),所以它可以利用 GPU 加速,使得运行速度明显快于不使用批处理的版本。
SPINN 的意思是堆栈增强的解析器-解释器神经网络(Stack-augmented Parser-Interpreter Neural Network),由 Bowman 等人于 2016 年作为解决自然语言推理任务的一种方法引入,该论文中使用了斯坦福大学的 SNLI 数据集。
该任务是将语句对分为三类:假设语句 1 是一幅看不见的图像的准确标题,那么语句 2(a)肯定(b)可能还是(c)绝对不是一个准确的标题?(这些类分别被称为蕴含(entailment)、中立(neutral)和矛盾(contradiction))。例如,假设一句话是“两只狗正跑过一片场地”,蕴含可能会使这个语句对变成“户外的动物”,中立可能会使这个语句对变成“一些小狗正在跑并试图抓住一根棍子”,矛盾能会使这个语句对变成“宠物正坐在沙发上”。
特别地,研究 SPINN 的初始目标是在确定语句的关系之前将每个句子编码(encoding)成固定长度的向量表示(也有其它方式,例如注意模型(attention model)中将每个句子的每个部分用一种柔焦(soft focus)的方法相互比较)。
数据集是用句法解析树(syntactic parse tree)方法由机器生成的,句法解析树将每个句子中的单词分组成具有独立意义的短语和子句,每个短语由两个词或子短语组成。许多语言学家认为,人类通过如上面所说的树的分层方式来组合词意并理解语言,所以用相同的方式尝试构建一个神经网络是值得的。下面的例子是数据集中的一个句子,其解析树由嵌套括号表示:
( ( The church ) ( ( has ( cracks ( in ( the ceiling ) ) ) ) . ) )
这个句子进行编码的一种方式是使用含有解析树的神经网络构建一个神经网络层 Rece,这个神经网络层能够组合词语对(用词嵌入(word embedding)表示,如 GloVe)、 和/或短语,然后递归地应用此层(函数),将最后一个 Rece 产生的结果作为句子的编码:
X = Rece(“the”, “ceiling”)
Y = Rece(“in”, X)
... etc.
但是,如果我希望网络以更类似人类的方式工作,从左到右阅读并保留句子的语境,同时仍然使用解析树组合短语?或者,如果我想训练一个网络来构建自己的解析树,让解析树根据它看到的单词读取句子?这是一个同样的但方式略有不同的解析树的写法:
The church ) has cracks in the ceiling ) ) ) ) . ) )
或者用第 3 种方式表示,如下:
WORDS: The church has cracks in the ceiling .
PARSES: S S R S S S S S R R R R S R R
我所做的只是删除开括号,然后用“S”标记“shift”,并用“R”替换闭括号用于“rece”。但是现在可以从左到右读取信息作为一组指令来操作一个堆栈(stack)和一个类似堆栈的缓冲区(buffer),能得到与上述递归方法完全相同的结果:
1. 将单词放入缓冲区。
2. 从缓冲区的前部弹出“The”,将其推送(push)到堆栈上层,紧接着是“church”。
3. 弹出前 2 个堆栈值,应用于 Rece,然后将结果推送回堆栈。
4. 从缓冲区弹出“has”,然后推送到堆栈,然后是“cracks”,然后是“in”,然后是“the”,然后是“ceiling”。
5. 重复四次:弹出 2 个堆栈值,应用于 Rece,然后推送结果。
6. 从缓冲区弹出“.”,然后推送到堆栈上层。
7. 重复两次:弹出 2 个堆栈值,应用于 Rece,然后推送结果。
8. 弹出剩余的堆栈值,并将其作为句子编码返回。
我还想保留句子的语境,以便在对句子的后半部分应用 Rece 层时考虑系统已经读取的句子部分的信息。所以我将用一个三参数函数替换双参数的 Rece 函数,该函数的输入值为一个左子句、一个右子句和当前句的上下文状态。该状态由神经网络的第二层(称为循环跟踪器(Tracker)的单元)创建。Tracker 在给定当前句子上下文状态、缓冲区中的顶部条目 b 和堆栈中前两个条目 s1\s2 时,在堆栈操作的每个步骤(即,读取每个单词或闭括号)后生成一个新状态:
context[t+1] = Tracker(context[t], b, s1, s2)
容易设想用你最喜欢的编程语言来编写代码做这些事情。对于要处理的每个句子,它将从缓冲区加载下一个单词,运行跟踪器,检查是否将单词推送入堆栈或执行 Rece 函数,执行该操作;然后重复,直到对整个句子完成处理。通过对单个句子的应用,该过程构成了一个大而复杂的深度神经网络,通过堆栈操作的方式一遍又一遍地应用它的两个可训练层。但是,如果你熟悉 TensorFlow 或 Theano 等传统的深度学习框架,就知道它们很难实现这样的动态过程。你值得花点时间回顾一下,探索为什么 PyTorch 能有所不同。
图论
图 1:一个函数的图结构表示
深度神经网络本质上是有大量参数的复杂函数。深度学习的目的是通过计算以损失函数(loss)度量的偏导数(梯度)来优化这些参数。如果函数表示为计算图结构(图 1),则向后遍历该图可实现这些梯度的计算,而无需冗余工作。每个现代深度学习框架都是基于此反向传播(backpropagation)的概念,因此每个框架都需要一个表示计算图的方式。
在许多流行的框架中,包括 TensorFlow、Theano 和 Keras 以及 Torch7 的 nngraph 库,计算图是一个提前构建的静态对象。该图是用像数学表达式的代码定义的,但其变量实际上是尚未保存任何数值的占位符(placeholder)。图中的占位符变量被编译进函数,然后可以在训练集的批处理上重复运行该函数来产生输出和梯度值。
这种静态计算图(static computation graph)方法对于固定结构的卷积神经网络效果很好。但是在许多其它应用中,有用的做法是令神经网络的图结构根据数据而有所不同。在自然语言处理中,研究人员通常希望通过每个时间步骤中输入的单词来展开(确定)循环神经网络。上述 SPINN 模型中的堆栈操作很大程度上依赖于控制流程(如 for 和 if 语句)来定义特定句子的计算图结构。在更复杂的情况下,你可能需要构建结构依赖于模型自身的子网络输出的模型。
这些想法中的一些(虽然不是全部)可以被生搬硬套到静态图系统中,但几乎总是以降低透明度和增加代码的困惑度为代价。该框架必须在其计算图中添加特殊的节点,这些节点代表如循环和条件的编程原语(programming primitive),而用户必须学习和使用这些节点,而不仅仅是编程代码语言中的 for 和 if 语句。这是因为程序员使用的任何控制流程语句将仅运行一次,当构建图时程序员需要硬编码(hard coding)单个计算路径。
例如,通过词向量(从初始状态 h0 开始)运行循环神经网络单元(rnn_unit)需要 TensorFlow 中的特殊控制流节点 tf.while_loop。需要一个额外的特殊节点来获取运行时的词长度,因为在运行代码时它只是一个占位符。
# TensorFlow
# (this code runs once, ring model initialization)
# “words” is not a real list (it’s a placeholder variable) so
# I can’t use “len”
cond = lambda i, h: i < tf.shape(words)[0]
cell = lambda i, h: rnn_unit(words[i], h)
i = 0
_, h = tf.while_loop(cond, cell, (i, h0))
基于动态计算图(dynamic computation graph)的方法与之前的方法有根本性不同,它有几十年的学术研究历史,其中包括了哈佛的 Kayak、自动微分库(autograd)以及以研究为中心的框架 Chainer和 DyNet。在这样的框架(也称为运行时定义(define-by-run))中,计算图在运行时被建立和重建,使用相同的代码为前向通过(forward pass)执行计算,同时也为反向传播(backpropagation)建立所需的数据结构。这种方法能产生更直接的代码,因为控制流程的编写可以使用标准的 for 和 if。它还使调试更容易,因为运行时断点(run-time breakpoint)或堆栈跟踪(stack trace)将追踪到实际编写的代码,而不是执行引擎中的编译函数。可以在动态框架中使用简单的 Python 的 for 循环来实现有相同变量长度的循环神经网络。
# PyTorch (also works in Chainer)
# (this code runs on every forward pass of the model)
# “words” is a Python list with actual values in it
h = h0
for word in words:
h = rnn_unit(word, h)
PyTorch 是第一个 define-by-run 的深度学习框架,它与静态图框架(如 TensorFlow)的功能和性能相匹配,使其能很好地适合从标准卷积神经网络(convolutional network)到最疯狂的强化学习(reinforcement learning)等思想。所以让我们来看看 SPINN 的实现。
代码
在开始构建网络之前,我需要设置一个数据加载器(data loader)。通过深度学习,模型可以通过数据样本的批处理进行操作,通过并行化(parallelism)加快训练,并在每一步都有一个更平滑的梯度变化。我想在这里可以做到这一点(稍后我将解释上述堆栈操作过程如何进行批处理)。以下 Python 代码使用内置于 PyTorch 的文本库的系统来加载数据,它可以通过连接相似长度的数据样本自动生成批处理。运行此代码之后,train_iter、dev_iter 和 test_itercontain 循环遍历训练集、验证集和测试集分块 SNLI 的批处理。
from torchtext import data, datasets
TEXT = datasets.snli.ParsedTextField(lower=True)
TRANSITIONS = datasets.snli.ShiftReceField()
LABELS = data.Field(sequential=False)train, dev, test = datasets.SNLI.splits(
TEXT, TRANSITIONS, LABELS, wv_type='glove.42B')TEXT.build_vocab(train, dev, test)
train_iter, dev_iter, test_iter = data.BucketIterator.splits(
(train, dev, test), batch_size=64)
你可以在 train.py中找到设置训练循环和准确性(accuracy)测量的其余代码。让我们继续。如上所述,SPINN 编码器包含参数化的 Rece 层和可选的循环跟踪器来跟踪句子上下文,以便在每次网络读取单词或应用 Rece 时更新隐藏状态;以下代码代表的是,创建一个 SPINN 只是意味着创建这两个子模块(我们将很快看到它们的代码),并将它们放在一个容器中以供稍后使用。
import torchfrom torch import nn
# subclass the Mole class from PyTorch’s neural network package
class SPINN(nn.Mole):
def __init__(self, config):
super(SPINN, self).__init__()
self.config = config self.rece = Rece(config.d_hidden, config.d_tracker)
if config.d_tracker is not None:
self.tracker = Tracker(config.d_hidden, config.d_tracker)
当创建模型时,SPINN.__init__ 被调用了一次;它分配和初始化参数,但不执行任何神经网络操作或构建任何类型的计算图。在每个新的批处理数据上运行的代码由 SPINN.forward 方法定义,它是用户实现的方法中用于定义模型向前过程的标准 PyTorch 名称。上面描述的是堆栈操作算法的一个有效实现,即在一般 Python 中,在一批缓冲区和堆栈上运行,每一个例子都对应一个缓冲区和堆栈。我使用转移矩阵(transition)包含的“shift”和“rece”操作集合进行迭代,运行 Tracker(如果存在),并遍历批处理中的每个样本来应用“shift”操作(如果请求),或将其添加到需要“rece”操作的样本列表中。然后在该列表中的所有样本上运行 Rece 层,并将结果推送回到它们各自的堆栈。
def forward(self, buffers, transitions):
# The input comes in as a single tensor of word embeddings;
# I need it to be a list of stacks, one for each example in
# the batch, that we can pop from independently. The words in
# each example have already been reversed, so that they can
# be read from left to right by popping from the end of each
# list; they have also been prefixed with a null value.
buffers = [list(torch.split(b.squeeze(1), 1, 0))
for b in torch.split(buffers, 1, 1)]
# we also need two null values at the bottom of each stack,
# so we can from the nulls in the input; these nulls
# are all needed so that the tracker can run even if the
# buffer or stack is empty
stacks = [[buf[0], buf[0]] for buf in buffers]
if hasattr(self, 'tracker'):
self.tracker.reset_state()
for trans_batch in transitions:
if hasattr(self, 'tracker'):
# I described the Tracker earlier as taking 4
# arguments (context_t, b, s1, s2), but here I
# provide the stack contents as a single argument
# while storing the context inside the Tracker
# object itself.
tracker_states, _ = self.tracker(buffers, stacks)
else:
tracker_states = itertools.repeat(None)
lefts, rights, trackings = [], [], []
batch = zip(trans_batch, buffers, stacks, tracker_states)
for transition, buf, stack, tracking in batch:
if transition == SHIFT:
stack.append(buf.pop())
elif transition == REDUCE:
rights.append(stack.pop())
lefts.append(stack.pop())
trackings.append(tracking)
if rights:
reced = iter(self.rece(lefts, rights, trackings))
for transition, stack in zip(trans_batch, stacks):
if transition == REDUCE:
stack.append(next(reced))
return [stack.pop() for stack in stacks]
在调用 self.tracker 或 self.rece 时分别运行 Tracker 或 Rece 子模块的向前方法,该方法需要在样本列表上应用前向操作。在主函数的向前方法中,在不同的样本上进行独立的操作是有意义的,即为批处理中每个样本提供分离的缓冲区和堆栈,因为所有受益于批处理执行的重度使用数学和需要 GPU 加速的操作都在 Tracker 和 Rece 中进行。为了更干净地编写这些函数,我将使用一些 helper(稍后将定义)将这些样本列表转化成批处理张量(tensor),反之亦然。
我希望 Rece 模块自动批处理其参数以加速计算,然后解批处理(unbatch)它们,以便可以单独推送和弹出。用于将每对左、右子短语表达组合成父短语(parent phrase)的实际组合函数是 TreeLSTM,它是普通循环神经网络单元 LSTM 的变型。该组合函数要求每个子短语的状态实际上由两个张量组成,一个隐藏状态 h 和一个存储单元(memory cell)状态 c,而函数是使用在子短语的隐藏状态操作的两个线性层(nn.Linear)和将线性层的结果与子短语的存储单元状态相结合的非线性组合函数 tree_lstm。在 SPINN 中,这种方式通过添加在 Tracker 的隐藏状态下运行的第 3 个线性层进行扩展。
图 2:TreeLSTM 组合函数增加了第 3 个输入(x,在这种情况下为 Tracker 状态)。在下面所示的 PyTorch 实现中,5 组的三种线性变换(由蓝色、黑色和红色箭头的三元组表示)组合为三个 nn.Linear 模块,而 tree_lstm 函数执行位于框内的所有计算。图来自 Chen et al. (2016)。
G. 一文看懂四种基本的神经网络架构
原文链接:
http://blackblog.tech/2018/02/23/Eight-Neural-Network/
更多干货就在我的个人博客 http://blackblog.tech 欢迎关注
刚刚入门神经网络,往往会对众多的神经网络架构感到困惑,神经网络看起来复杂多样,但是这么多架构无非也就是三类,前馈神经网络,循环网络,对称连接网络,本文将介绍四种常见的神经网络,分别是CNN,RNN,DBN,GAN。通过这四种基本的神经网络架构,我们来对神经网络进行一定的了解。
神经网络是机器学习中的一种模型,是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。
一般来说,神经网络的架构可以分为三类:
前馈神经网络:
这是实际应用中最常见的神经网络类型。第一层是输入,最后一层是输出。如果有多个隐藏层,我们称之为“深度”神经网络。他们计算出一系列改变样本相似性的变换。各层神经元的活动是前一层活动的非线性函数。
循环网络:
循环网络在他们的连接图中定向了循环,这意味着你可以按照箭头回到你开始的地方。他们可以有复杂的动态,使其很难训练。他们更具有生物真实性。
循环网络的目的使用来处理序列数据。在传统的神经网络模型中,是从输入层到隐含层再到输出层,层与层之间是全连接的,每层之间的节点是无连接的。但是这种普通的神经网络对于很多问题却无能无力。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。
循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。
对称连接网络:
对称连接网络有点像循环网络,但是单元之间的连接是对称的(它们在两个方向上权重相同)。比起循环网络,对称连接网络更容易分析。这个网络中有更多的限制,因为它们遵守能量函数定律。没有隐藏单元的对称连接网络被称为“Hopfield 网络”。有隐藏单元的对称连接的网络被称为玻尔兹曼机。
其实之前的帖子讲过一些关于感知机的内容,这里再复述一下。
首先还是这张图
这是一个M-P神经元
一个神经元有n个输入,每一个输入对应一个权值w,神经元内会对输入与权重做乘法后求和,求和的结果与偏置做差,最终将结果放入激活函数中,由激活函数给出最后的输出,输出往往是二进制的,0 状态代表抑制,1 状态代表激活。
可以把感知机看作是 n 维实例空间中的超平面决策面,对于超平面一侧的样本,感知器输出 1,对于另一侧的实例输出 0,这个决策超平面方程是 w⋅x=0。 那些可以被某一个超平面分割的正反样例集合称为线性可分(linearly separable)样例集合,它们就可以使用图中的感知机表示。
与、或、非问题都是线性可分的问题,使用一个有两输入的感知机能容易地表示,而异或并不是一个线性可分的问题,所以使用单层感知机是不行的,这时候就要使用多层感知机来解决疑惑问题了。
如果我们要训练一个感知机,应该怎么办呢?
我们会从随机的权值开始,反复地应用这个感知机到每个训练样例,只要它误分类样例就修改感知机的权值。重复这个过程,直到感知机正确分类所有的样例。每一步根据感知机训练法则来修改权值,也就是修改与输入 xi 对应的权 wi,法则如下:
这里 t 是当前训练样例的目标输出,o 是感知机的输出,η 是一个正的常数称为学习速率。学习速率的作用是缓和每一步调整权的程度,它通常被设为一个小的数值(例如 0.1),而且有时会使其随着权调整次数的增加而衰减。
多层感知机,或者说是多层神经网络无非就是在输入层与输出层之间加了多个隐藏层而已,后续的CNN,DBN等神经网络只不过是将重新设计了每一层的类型。感知机可以说是神经网络的基础,后续更为复杂的神经网络都离不开最简单的感知机的模型,
谈到机器学习,我们往往还会跟上一个词语,叫做模式识别,但是真实环境中的模式识别往往会出现各种问题。比如:
图像分割:真实场景中总是掺杂着其它物体。很难判断哪些部分属于同一个对象。对象的某些部分可以隐藏在其他对象的后面。
物体光照:像素的强度被光照强烈影响。
图像变形:物体可以以各种非仿射方式变形。例如,手写也可以有一个大的圆圈或只是一个尖头。
情景支持:物体所属类别通常由它们的使用方式来定义。例如,椅子是为了让人们坐在上面而设计的,因此它们具有各种各样的物理形状。
卷积神经网络与普通神经网络的区别在于,卷积神经网络包含了一个由卷积层和子采样层构成的特征抽取器。在卷积神经网络的卷积层中,一个神经元只与部分邻层神经元连接。在CNN的一个卷积层中,通常包含若干个特征平面(featureMap),每个特征平面由一些矩形排列的的神经元组成,同一特征平面的神经元共享权值,这里共享的权值就是卷积核。卷积核一般以随机小数矩阵的形式初始化,在网络的训练过程中卷积核将学习得到合理的权值。共享权值(卷积核)带来的直接好处是减少网络各层之间的连接,同时又降低了过拟合的风险。子采样也叫做池化(pooling),通常有均值子采样(mean pooling)和最大值子采样(max pooling)两种形式。子采样可以看作一种特殊的卷积过程。卷积和子采样大大简化了模型复杂度,减少了模型的参数。
卷积神经网络由三部分构成。第一部分是输入层。第二部分由n个卷积层和池化层的组合组成。第三部分由一个全连结的多层感知机分类器构成。
这里举AlexNet为例:
·输入:224×224大小的图片,3通道
·第一层卷积:11×11大小的卷积核96个,每个GPU上48个。
·第一层max-pooling:2×2的核。
·第二层卷积:5×5卷积核256个,每个GPU上128个。
·第二层max-pooling:2×2的核。
·第三层卷积:与上一层是全连接,3*3的卷积核384个。分到两个GPU上个192个。
·第四层卷积:3×3的卷积核384个,两个GPU各192个。该层与上一层连接没有经过pooling层。
·第五层卷积:3×3的卷积核256个,两个GPU上个128个。
·第五层max-pooling:2×2的核。
·第一层全连接:4096维,将第五层max-pooling的输出连接成为一个一维向量,作为该层的输入。
·第二层全连接:4096维
·Softmax层:输出为1000,输出的每一维都是图片属于该类别的概率。
卷积神经网络在模式识别领域有着重要应用,当然这里只是对卷积神经网络做了最简单的讲解,卷积神经网络中仍然有很多知识,比如局部感受野,权值共享,多卷积核等内容,后续有机会再进行讲解。
传统的神经网络对于很多问题难以处理,比如你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。RNN之所以称为循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。理论上,RNN能够对任何长度的序列数据进行处理。
这是一个简单的RNN的结构,可以看到隐藏层自己是可以跟自己进行连接的。
那么RNN为什么隐藏层能够看到上一刻的隐藏层的输出呢,其实我们把这个网络展开来开就很清晰了。
从上面的公式我们可以看出,循环层和全连接层的区别就是循环层多了一个权重矩阵 W。
如果反复把式2带入到式1,我们将得到:
在讲DBN之前,我们需要对DBN的基本组成单位有一定的了解,那就是RBM,受限玻尔兹曼机。
首先什么是玻尔兹曼机?
[图片上传失败...(image-d36b31-1519636788074)]
如图所示为一个玻尔兹曼机,其蓝色节点为隐层,白色节点为输入层。
玻尔兹曼机和递归神经网络相比,区别体现在以下几点:
1、递归神经网络本质是学习一个函数,因此有输入和输出层的概念,而玻尔兹曼机的用处在于学习一组数据的“内在表示”,因此其没有输出层的概念。
2、递归神经网络各节点链接为有向环,而玻尔兹曼机各节点连接成无向完全图。
而受限玻尔兹曼机是什么呢?
最简单的来说就是加入了限制,这个限制就是将完全图变成了二分图。即由一个显层和一个隐层构成,显层与隐层的神经元之间为双向全连接。
h表示隐藏层,v表示显层
在RBM中,任意两个相连的神经元之间有一个权值w表示其连接强度,每个神经元自身有一个偏置系数b(对显层神经元)和c(对隐层神经元)来表示其自身权重。
具体的公式推导在这里就不展示了
DBN是一个概率生成模型,与传统的判别模型的神经网络相对,生成模型是建立一个观察数据和标签之间的联合分布,对P(Observation|Label)和 P(Label|Observation)都做了评估,而判别模型仅仅而已评估了后者,也就是P(Label|Observation)。
DBN由多个限制玻尔兹曼机(Restricted Boltzmann Machines)层组成,一个典型的神经网络类型如图所示。这些网络被“限制”为一个可视层和一个隐层,层间存在连接,但层内的单元间不存在连接。隐层单元被训练去捕捉在可视层表现出来的高阶数据的相关性。
生成对抗网络其实在之前的帖子中做过讲解,这里在说明一下。
生成对抗网络的目标在于生成,我们传统的网络结构往往都是判别模型,即判断一个样本的真实性。而生成模型能够根据所提供的样本生成类似的新样本,注意这些样本是由计算机学习而来的。
GAN一般由两个网络组成,生成模型网络,判别模型网络。
生成模型 G 捕捉样本数据的分布,用服从某一分布(均匀分布,高斯分布等)的噪声 z 生成一个类似真实训练数据的样本,追求效果是越像真实样本越好;判别模型 D 是一个二分类器,估计一个样本来自于训练数据(而非生成数据)的概率,如果样本来自于真实的训练数据,D 输出大概率,否则,D 输出小概率。
举个例子:生成网络 G 好比假币制造团伙,专门制造假币,判别网络 D 好比警察,专门检测使用的货币是真币还是假币,G 的目标是想方设法生成和真币一样的货币,使得 D 判别不出来,D 的目标是想方设法检测出来 G 生成的假币。
传统的判别网络:
生成对抗网络:
下面展示一个cDCGAN的例子(前面帖子中写过的)
生成网络
判别网络
最终结果,使用MNIST作为初始样本,通过学习后生成的数字,可以看到学习的效果还是不错的。
本文非常简单的介绍了四种神经网络的架构,CNN,RNN,DBN,GAN。当然也仅仅是简单的介绍,并没有深层次讲解其内涵。这四种神经网络的架构十分常见,应用也十分广泛。当然关于神经网络的知识,不可能几篇帖子就讲解完,这里知识讲解一些基础知识,帮助大家快速入(zhuang)门(bi)。后面的帖子将对深度自动编码器,Hopfield 网络长短期记忆网络(LSTM)进行讲解。
H. 如何用PyTorch实现递归神经网络
如何用PyTorch实现递归神经网络
其实一般都叫递归神经网络,只是recurrent是时间递归(常用),而recursive是指结构递归神经网络
I. BP神经网络函数选择
神经网络不同的网络有这不同的训练函数,BP神经网络有两种训练函数,trainbp(),利用BP算法训练前向神经网络。trainbpx(),利用快速BP算法训练前向神经网络,即采用了动量或自适应学习,可减少训练时间,tansig函数是神经元的传递函数,与训练函数无关,在trainbp()函数中含有要训练神经元的函数。
求采纳为满意回答。
J. rbf神经网络中的训练函数是什么
RBF (Radial Basis Function)可以看作是一个高维空间中的曲面拟合(逼近)问题,学习是为了在多维空间中寻找一个能够最佳匹配训练数据的曲面,然后来一批新的数据,用刚才训练的那个曲面来处理(比如分类、回归)。RBF的本质思想是反向传播学习算法应用递归技术,这种技术在统计学中被称为随机逼近。RBF里的basis function(径向基函数里的基函数)就是在神经网络的隐单元里提供了提供了一个函数集,该函数集在输入模式(向量)扩展至隐空间时,为其构建了一个任意的“基”。这个函数集中的函数就被称为径向基函数。
如果对于输入空间的某个局部区域只有少数几个连接权值影响输出,则该网络称为局部逼近网络。常见的局部逼近网络有RBF网络、小脑模型(CMAC)网络、B样条网络等。
径向基函数解决插值问题
完全内插法要求插值函数经过每个样本点,即。样本点总共有P个。
RBF的方法是要选择P个基函数,每个基函数对应一个训练数据,各基函数形式为,由于距离是径向同性的,因此称为径向基函数。||X-Xp||表示差向量的模,或者叫2范数