神经网络

Posted 一蓑烟雨晴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了神经网络相关的知识,希望对你有一定的参考价值。

文章目录

西瓜书笔记

1. 神经元模型

神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。

2. 感知机与多层网络

3. 误差逆传播算法

误差逆传播算法(BackPropagation,简称BP)是迄今为止最成功的神经网络学习算法。通常说“BP网络”时,一般是指用BP算法训练的多层前馈神经网络。
一般来说,标准BP算法每次更新只针对单个样例,参数更新得非常频繁,而且对不同样例进行更新的效果可能出现“抵消”现象。因此,为了达到同样的累积误差最小化,它在读取整个训练集D一遍后才对参数进行更新,其参数更新的频率低得多。但在很多任务中,累积误差下降到一定程度之后,进一步下降会非常缓慢,这时标准BP往往会更快获得较好的解,尤其是在训练集D非常大时更明显。类似于随机梯度下降和标准梯度下降之间的区别。

4. 全局最小与局部极小

局部极小解是参数空间中的某个点,其邻域点的误差函数值均不小于该点的函数值;全局最小解则是指参数空间中所有点的误差函数值均不小于该点的误差函数值。

在现实任务中,人们常采用以下策略来试图“跳出”局部极小,从而进一步接近全局最小:

  • 以多组不同参数值初始化多个神经网络,按标准方法训练后,取其中误差最小的解作为最终参数。这相当于从多个不同的初始点开始搜索,这样就可能陷入不同的局部极小,从中进行选择有可能获得更接近全局最小的结果。
  • 使用“模拟退火”技术。模拟退火在每一步都以一定的概率接受比当前解更差的结果,从而有助于“跳出”局部极小。在每步迭代过程中,接受“次优解”的概率要随着时间的推移而逐渐降低,从而保证算法稳定。
  • 使用随机梯度下降。与标准梯度下降法精确计算梯度不同,随机梯度下降法在计算梯度时加入了随机因素。于是,即便陷入局部极小点,它计算出的梯度仍可能不为零,这样就有机会跳出局部极小继续搜索。

5. 其他常见神经网络

5.1 RBF网络

RBF(Radial Basis Function,径向基函数)网络是一种单隐层前馈神经网络,它使用径向基函数作为隐层神经元激活函数,而输出层则是对隐层神经元输出的线性组合。假定输入为d维向量x,输出为实值,则RBF网络可表示为:
φ ( x ) = ∑ i = 1 q w i ρ ( x , c i ) \\varphi(\\boldsymbolx)=\\sum_i=1^q w_i \\rho\\left(\\boldsymbolx, \\boldsymbolc_i\\right) φ(x)=i=1qwiρ(x,ci)
其中q为隐层神经元个数, c i c_i ci w i w_i wi分别是第i个隐层神经元所对应的中心和权重, ρ ( x , c i ) \\rho\\left(\\boldsymbolx, \\boldsymbolc_i\\right) ρ(x,ci)是径向基函数,这是某种沿径向对称的标量函数,通常定义为样本x到数据中心 c i c_i ci之间欧氏距离的单调函数。常用的高斯径向基函数形如
ρ ( x , c i ) = e − β i ∥ x − c i ∥ 2 \\rho\\left(x, c_i\\right)=e^-\\beta_i\\left\\|x-c_i\\right\\|^2 ρ(x,ci)=eβixci2
可证明,具有足够多隐层神经元的RBF网络能以任何精度逼近任意连续函数。

通常采用两步过程来训练RBF网络:第一步,确定神经元中心 c i c_i ci,常用的方式包括随机采样、聚类等;第二步,利用BP算法等来确定参数 w i w_i wi β i \\beta_i βi.

径向基函数是一个取值仅仅依赖于输入和某些固定点或原点的距离的实值函数,即 φ ( x ) = φ ^ ( ∥ x ∥ ) \\varphi(\\mathbfx)=\\hat\\varphi(\\|\\mathbfx\\|) φ(x)=φ^(x)。任何满足 φ ( x ) = φ ^ ( ∥ x ∥ ) \\varphi(\\mathbfx)=\\hat\\varphi(\\|\\mathbfx\\|) φ(x)=φ^(x)的函数 φ \\varphi φ是径向函数。距离通常是欧几里得距离,尽管有时会使用其他度量。它们经常被作为一个集合,用于构成一些感兴趣的函数空间的基础。径向基函数之和通常用于逼近给定函数。这种近似过程也可以解释为一种简单的神经网络,RBFs也被用作支持向量分类的内核,该技术已被证明足够有效和灵活,以至于径向基函数现在已用于各种工程应用中。

以下取自
EBF的隐单元的“基”构成隐藏层空间,这样就可以将输入矢量直接映射到隐空间。当RBF的中心点确定以后,这种映射关系也就确定了。而隐含层空间到输出空间的映射是线性的,即网络输出是隐单元输出的线性加权和,此处的权即为网络可调参数。径向基神经网络的节点激活函数采用径向基函数,定义了空间中任一点到某一中心点的欧式距离的单调函数。
下图是径向基神经元模型

径向基函数的激活函数是以输入向量和权值向量(此处的权值向量并非隐藏层到输出层的权值)之间的距离||dist||作为自变量的,图中的b为阈值,用于调整神经元的灵敏度。
下图是以高斯核为径向基函数的神经元模型:

对应的激活函数表达式:
R ( x p − c i ) = exp ⁡ ( − 1 2 σ i 2 ∥ x p − c i ∥ 2 ) R\\left(x_p-c_i\\right)=\\exp \\left(-\\frac12 \\sigma_i^2\\left\\|x_p-c_i\\right\\|^2\\right) R(xpci)=exp(2σi21xpci2)

其中X代表输入向量,C代表权值,为高斯函数的中心, σ 2 \\sigma^2 σ2是高斯函数的方差,可以用来调整影响半径。当权值和输入向量的距离越小,网络的输出不断递增,输入向量越靠近径向基函数的中心,隐层节点产生的输出越大。也就是径向基函数对输入信号在局部产生响应,输入向量与权值距离越远,隐层输出越接近0,再经过一层线性变换映射到最终输出层,导致输出层也接近0。
RBF是具有单隐层的三层前向网络。

用RBF网络实现了异或操作,中间层4阶,学习率0.1取自感觉代码其实写的比较晦涩,反向传播部分没有看,下图是网络框架图:

#encoding:utf-8
'''
    P116 5.7 用RBF构建一个完成异或运算的神经网络
    约定:w为隐层与输出层的权值,β为隐层缩放系数,center为神经元中心
    后面带_i,_j表示单元,不带则表示全体🕸
'''
import numpy as np

class Neure:
    '''🕸
        隐层神经元结构体,包括w, β, 与样本中心center
    '''
    def __init__(self, beta, center, omega, index):
        self.beta = beta # β为隐层缩放系数
        self.center = center # center为神经元中心
        self.omega = omega # w为隐层与输出层的权值
        self.index = index

def radial_basis_func(neure_i, feature_j):
    '''
        RBF径向基函数,即pi = exp(-βi(x-ci)²)
    '''
    return np.exp(-neure_i.beta* np.sum(np.square(feature_j - neure_i.center)))

def predict_func(radial_basis):
    '''
        #网络输出φ, neure为全体隐层神经元的集合
        φj = Σwi * p(βi,ci,xj)
    '''
    def func(neures, feature_j):
        unit = lambda neure_i: neure_i.omega * radial_basis(neure_i, feature_j)
        return sum(map(unit, neures))
    return func

def error_func(predict_j):
    '''
        误差评价函数E
    '''
    def func(neure, feature, label):
        unit = lambda feature_j, label_j: 0.5*np.square(predict_j(neure, feature_j)-label_j)
        return sum(map(unit, feature, label))
    return func

def expression_func(radial_basis_func_j, predict_func_j):
    '''
        中间表达式 (φ(xj) - yj)p(xj, ci)
    '''
    def warpper(neure_i):
        def func(neure, feature_j, label_j):
            return (predict_func_j(neure, feature_j)-label_j)*radial_basis_func_j(neure_i, feature_j)
        return func
    return warpper

def e_derivative_of_omega_i_fuc(expression):
    '''
        计算E对wi的偏导
    '''
    def warpper(neure_i):
        def func(neure, feature, label):
            return sum(map(lambda x, y:expression(neure_i)(neure, x, y), feature, label))
        return func
    return warpper

def e_derivative_of_beta_i_fuc(expression):
    '''
        计算E对βi的偏导
    '''
    def warpper(neure_i):
        def func(neure, feature, label):
            return -sum(map(lambda x, y:expression(neure_i)(neure, x, y) * neure_i.omega * np.sum(np.square(x-neure_i.center)), feature, label))
        return func
    return warpper

def beta_gradient_descent(neure_i, neures, feature, label):
    '''
        整合过后的beta梯度方向
    '''
    return e_derivative_of_beta_i_fuc(expression_func(radial_basis_func, predict_func(radial_basis_func)))(neure_i)(neures, feature, label)

def omega_gradient_descent(neure_i, neures, feature, label):
    '''
        整合过后的w梯度方向
    '''
    return e_derivative_of_omega_i_fuc(expression_func(radial_basis_func, predict_func(radial_basis_func)))(neure_i)(neures, feature, label)

def loss_func(neures, feature, label):
    '''
        封装后的误差函数
    '''
    return error_func(predict_func(radial_basis_func))(neures, feature, label)
def neure_init(order, neure=None):
    '''
        初始化隐层,order 为隐层神经元个数
    '''
    if neure is None:
        neure = []
    elif order == 0:
        return neure
    neure.append(Neure(1, np.abs(np.random.rand(1, 2)), 1, 4-order))
    return neure_init(order-1, neure=neure)

def train(learning_rate, neures, trainning_set, trainning_count):
    '''
        训练函数
    '''
    for count in range(trainning_count):
        for var in neures:
            var.beta = var.beta - learning_rate * beta_gradient_descent(var, neures, trainning_set[0], trainning_set[1])
            var.omega = var.omega - learning_rate * omega_gradient_descent(var, neures, trainning_set[0], trainning_set[1])
        print("第%d次训练,误差为%.4f" % (count+1,sum(loss_func(neures,trainning_set[0],trainning_set[1]))))

def main():
    '''
        主函数入口
    '''
    #0 数据集定义
    trainning_set = [
        [[0, 0], [0, 1], [1, 0], [1, 1]], [[0], [1], [1], [0]]]
    #1 参数设计
    order_hiddenlayer = 4
    learning_rate = 0.1
    trainning_count = 1000
    #2 网络初始化
    neures = neure_init(order_hiddenlayer)
    #3 训练
    train(learning_rate, neures,trainning_set, trainning_count)
    #4 显示输出
    for var in trainning_set[0]:
        print("%d xor %d is %f" % (var[0], var[1], predict_func(radial_basis_func)(neures, var)))



if __name__ == '__main__':
    main()

Python的径向基函数神经网络实现来自

5.2 ART网络

竞争性学习是神经网络中一种常用的无监督学习策略,在使用该策略时,网络的输出神经元相互竞争,每一时刻仅有一个竞争获胜的神经元被激活,其他神经元的状态被抑制。这种机制亦称“胜者通吃”原则。
ART(Adaptive Reson.ance Theory)网络是竞争型学习的重要代表。该网络由比较层、识别层、识别阈值和重置模块构成。其中,比较层负责接收输入样本,并将其传递给识别层神经元,识别层每个神经元对应一个模式类,神经元数目可在训练过程中动态增长以增加新的模式类。
在接收到比较层的输入信号后,识别层神经元之间相互竞争以产生获胜神经元。竞争的最简单方式是,计算输入向量与每个识别层神经元所对应的模式类的代表向量之间的距离,距离最小者胜。获胜神经元将向其他识别层神经元发送信号,抑制其激活。若输入向量与获胜神经元所对应的代表向量之间的相似度大于识别阈值,则当前输入样本将被归为该代表向量所属类别,同时,网络连接权将会更新,使得以后在接收到相似样本时该模式类会计算出更大的相似度,从而使该获胜神经元有更大可能获胜;若相似度不大于识别阈值,则重置模块将在识别层增设一个新的神经元,其代表向量就设置为当前输入向量。
ART比较好地缓解了竞争型学习中的“可塑性-稳定性窘境”。可塑性是指神经网络要有学习新知识的能力,而稳定性则是指神经网络在学习新知识时要保持对旧知识的记忆。这就使得ART网络具有一个很重要的优点:可进行增量学习或在线学习。
早期的ART网络只能处理布尔型输入数据,此后ART发展成了一个算法族,包括能处理实值输入的ART2网络、结合模糊处理的FuzzyART网络,以及可进行监督学习的ARTMAP网络等。
以下参考《自适应共振理论原理与应用研究》——彭小萍
由于其学习架构为无监督模型,使得ART非常适合应用于模式识别和错误检测。
ART有很多版本,ART1是最早版本,它主要用于处理只含有0与1的图像的辨识问题,而ART2可以处理灰度(即连续值)的输入。
分流模型 分流模型是Grossberg类神经网络的神经元核心数学模型。
中心激励横向抑制 除了原有的分流模型之外,还加入了一个神经元间交互作用函数 g (

以上是关于神经网络的主要内容,如果未能解决你的问题,请参考以下文章

循环神经网络(RNN)

循环神经网络(RNN)

循环神经网络(RNN)

深入浅出图解CNN-卷积神经网络

3.1循环神经网络数学理解

LSTM VS RNN改进