21/8/12 读书笔记 表驱动法 神经网络

21/8/12 读书笔记

Code Complete 表驱动法

表驱动法是一种在大概率变化的场景下取代复杂逻辑或复杂继承结构的方法,在某些情境下能够取得更高的效率和可维护性。

常见的基于if等逻辑控制实现复杂逻辑的方法,属于将复杂逻辑嵌入代码,而表驱动法则是强调将复杂逻辑嵌入数据。这样有两个好处:

  • 数据比代码更好维护。复杂逻辑通常容易发生变化,而表驱动法大多数情况下可以仅修改数据而避免修改代码。
  • 代码更加简洁。通过访问表来取得对应数据,比经过一大堆逻辑分发简洁;而且由于表驱动法设计下不同数据对象间存在一定同质性,可以让代码的可重用性进一步提升。

假设在消息打印的场景中,输入的数据是一行一行的数据,其中包含N种消息,每种消息的首字段都是用于区分类型的typeID,其余字段各不同,我们需要读入所有的消息并打印出来。基于面向对象的原则会促使我们去建立一个抽象类,其中定义一个打印方法,并基于该抽象类实现N个具体类对应N中消息类型。注意到这种方法中我们相当于把消息的格式硬编码进了程序逻辑中了,导致后续一旦涉及修改,代码就必须被修改。同时我们还实现了N种打印方法。

而表驱动法提供的解决方案让我们将对于消息格式的描述定义成一个格式,存放在表中。我们获取到typeID后直接从表中取出对应消息格式的描述,然后定义统一的打印函数来根据消息格式实现打印。这张表可以内嵌在程序中,也可以放在硬盘上,使用时读入。

可以看出表驱动法就是将数据的转换方式从编程改变为查表,因此只要合理设计数据转换逻辑,就能从表驱动法中获取增益。

表驱动法中查表方式分为:

  • 直接访问:直接用键值访问表,键值是整数。很多时候键值不是一个确切的整数,可能是一个数值范围,而且键值空间可能是过分大或无限大的。因此我们需要经过一定的键值转换,将这些概念转变为有限范围内的整数集合。
  • 索引访问:由于数据空间比键值空间小很多,如果直接将主表设计成和键值空间等规模会浪费过多空间。而索引表的每一项通常比主表的每一项占用更少空间,因此我们建立一个和键值空间等规模的索引表,然后每项有效索引指向规模更小的主表中的一项。这使得我们能在几乎不改变性能的情况下,尽可能少地占用空间。同时可以为一个主表建立多个索引,提高拓展性。可以将索引方式提取为子程序,使得表查询方式维护和更改起来更方便,提高可维护性
  • 阶梯访问:当我们的键值空间是连续的而且在一定数值范围内对应的数据一致时,采用阶梯法将键值空间根据一定划分点划分为多个区间,在查询时查找对应的区间取出对应的数据。通常可以采用二分查找提高查询性能。

注意我们选择合适的表查询方案的宗旨是寻找一个好的方案的同时不要引发灾难,而不是找到最佳的方案。


机器学习 神经网络

神经网络是指具有适应性的简单单元组成的广泛并行互连的网络,其中的简单单元就是神经元模型(neuron)。M-P神经元模型一直沿用至今,其中神经元接受来自其他n个神经元带一定权重的连接,在该连接上传递信号。当该神经元总输出值与该神经元阈值进行比较,利用激活函数(activation function)处理产生当前神经元的输出信号。

感知机(Perceptron)包括两层神经元,其中第一层输入层仅接收信号而不计算,输出层的神经元才是真正进行计算的功能神经元。感知机能够容易地实现逻辑与或非运算。感知机只能处理线性可分的问题,比如对于异或这种非线性问题就难以收敛。

线性可分:存在一个线性的超平面能够将问题空间中不同模式分割开来。

神经元中的阈值等价于一个固定输入为-1的“哑结点(dummy node)”的连接权重。即当A有N个真实结点输入,改为A有N+1个结点输入,其中一个结点是上述的哑结点,而此时A的阈值默认为0。由此可以将阈值和权重的学习统一为权重的学习

为了使得神经网络解决非线性可分的问题,就考虑使用多层的功能神经元。其中输入输出层中间的层称为隐含层

多层前馈神经网络,指每层的神经元全互连,不存在同层连接和跨层连接。这里的前馈指网络拓扑结构中不存在环路。理论已经证明,只要一个具有足够多神经元的隐含层,多层前馈神经网络就能以任意精度逼近任意复杂度的函数

误差逆传播算法(error BackPropagation, BP)是神经网络学习算法中最杰出的算法,其不仅用于多层前馈神经网络,也可用于其他神经网络。其基本思想是先根据当前样本的输入参数计算出输出,然后根据输出和期望输出间的误差计算出输出层神经元的梯度项,然后依次向前计算出每一层神经元的梯度项

该层神经元的梯度项,指误差对于该层神经元的输入值的梯度=\(\frac{\partial误差}{\partial神经元总输入值}\)

标准BP算法是针对每个样本的误差进行训练的,而累积BP算法是针对所有样本的累积误差进行训练的。标准BP算法参数更新频繁,不同的更新很可能出现抵消,在面对很大的训练集时能够更快获得较好的解。累积BP算法参数更新频率低,但是误差下降到一定程度后就会非常慢。

采用BP算法的多层前馈神经网络经常出现过拟合,通常需要:

  • 早停:通过利用验证集,如果训练集误差降低而验证集误差升高则停止训练。
  • 正则化:在误差目标函数中添加正则化项,迫使学习过程考虑网络的复杂度。

为了跳出局部最小解,通常采用启发式的方法:

  • 用多组不同的参数值初始化多个神经网络,取误差最小的解作为最终参数。
  • 模拟退火(simulated annealing):在训练的每一步都以一定概率接受次优解,其中的概率随着时间推移而减小,保证算法稳定。
  • 随机梯度下降:在梯度下降过程中引入随机因素,以期在陷入局部最小解时跳出局部。

以下为场景的神经网络模型:

  • RBF网络:Radial Basis Function指径向基函数。RBF网络以径向基函数作为隐含层神经元的激活函数,以隐含层神经元输出值的线性组合作为模型的输出层。

    径向基函数:函数结果仅取决于输入值和指定中心间的距离。

    中心:指数据样本的中心。可以用聚类方法得到数据分布中的k个中心,作为径向基函数中考虑的中心,每个隐含层神经元对应一个中心。

  • ART网络:属于竞争型学习(competitive learning),ART全称Adaptive Resonance Theory, 自适应谐振理论。其中分为比较层、识别层,并指定识别阈值。先计算输入向量与每个识别层神经元对应模式类的代表向量间的距离,距离最小者获胜并激活,同时抑制其他神经元激活。然后如果输入向量与获胜神经元代表向量间的相似度很高以至于高于识别阈值,则将该样本划归获胜神经元,同时更新网络权值使得下一次获胜神经元能够对类似样本获得更高的相似度。如果相似度达不到识别阈值,就在识别层新增一个神经元,并将其代表向量设置为当前输入向量。ART算法可进行增量学习和在线学习,能够记忆旧知识并在其基础上继续学习。

    可以注意ART算法并不考虑数据样本的真实标记,这意味着它是无监督学习。

  • SOM网络:Self-Organizing Map,自组织映射。其也是一种无监督竞争学习型神经网络。其将高维空间内相似的样本点映射到网络输出层中的邻近神经元。注意SOM网络中的输出层神经元呈二维矩阵方式排列。其接收一个训练样本后,计算其与每个输出层神经元代表向量的距离,距离最近的神经元获胜。获胜神经元及其邻近神经元的代表向量都会被更新,使得这些代表向量和训练样本间距离进一步缩小。

  • 级联相关网络:Cascade-Correlation,级联相关。其是结构自适应网络中的代表,即网络结构本身也作为训练目标。刚开始训练时只有输入层和输出层,随着训练进行,将加入新的隐含层神经元,其输入连接的权值固定不变。训练的目的是最大化新神经元的输出和网络误差之间的相关性

  • Elman网络:Elman网络是典型的递归神经网络RNN,其最大的特点在于网络中存在环形结构,这种环形结构能够使得网络在不同时刻的状态相互联系,使得RNN能够处理时间有关的动态变化。隐含层神经元的输出被反馈回来,下一时刻与输入层的输出值一起作为隐含层神经元的输入。

深度学习模型中通常隐含层的数量大于三,可以理解为通过简单的单层隐含层,从数据中提取低层特征,再从低层特征中提取更高层的特征……直到最后得到很抽象的高层特征,这种提取的行为称为特征学习多隐层神经网络难以直接使用BP算法进行训练,误差逆传播时会发散而不能收敛。多隐层网络训练通常有两个有效手段:

  • 预训练+微调:预训练指将上一层隐含层的输出作为输入,每次对多隐层中的一层隐含层进行训练。微调指预训练完成后对整个网络进行训练,通常采用BP算法等经典算法即可。这种方法相当于利用预训练尽可能降低了使用BP算法训练发散的可能性

  • 权值共享:对于多隐层神经网络,让多个神经元共享相同的连接权值,这一思想在卷积神经网络CNN中发挥重要作用。CNN中无论卷积层还是采样层,每个平面上的所有神经元采用相同的连接权值。

posted @ 2021-08-12 15:09  neumy  阅读(242)  评论(0)    收藏  举报