机器学习:BP神经网络


单层感知网络是最初的神经网络,具有模型清晰、结构简单、计算量小等优点,但是它无法处理非线性问题。BP神经网络具有任意复杂的模式分类能力和优良的多维函数映射能力,解决了简单感知器不能解决的异或问题和一些其他问题。

神经网络可以包含:

BP神经网络——最简单的

深度学习——可以看作复杂的BP神经网络解决范围更广

其他神经网络

人工神经网络的结构特点

☞非线性:自然界的普遍特性

☞非局限性:一个神经网络通常由多个神经元广泛连接而成。系统的整体行为取决于单元之间的相互作用、相互连接。

☞非常定性:人工神经网络具有自适应、自组织和自学习能力。系统本身一直在演化。

☞非凸性:非凸性是指这种函数有多个极值,因此系统具有多个较平稳的平衡态,这将导致系统演化的多样性。

✦神经网络模型主要有的4种类型:前向型、反馈型、随机型、竞争型

人工神经网络

一般来说,神经网络学习算法要能正常工作,激活函数F应当是可导和光滑的,比如:线性函数、逻辑斯蒂函数

单层神经网络

包括输入、权重、输出
在这里插入图片描述
单层神经网络的主要区别在于输出向量z,输出元的数量多于1时,即认为z是向量。
g(W*a)=z

双层神经网络

单层神经网络无法解决异或问题,增加一个计算层后,不仅可以解决异或问题,而且具有非常好的非线性分类效果。
在这里插入图片描述
在神经网络的每个层次中,除了输出层外,都会含有一个偏置单元
在这里插入图片描述

多层神经网络

“深度信念网络”,即“深度学习”包含的过程

“预训练”——让神经网络中的全职找到一个接近最优解的值。
“微调”——对整个网络进行优化训练。
在这里插入图片描述

在这里插入图片描述
多层神经网络中,输出也是按照一层一层的方式来计算的。

增加更多的层次有什么优势?

1、能够更深入地表示特征,更强的表现函数的模拟能力。
2、随着网络层数的增加,每一层对于前一层次的抽象表示更深入。

BP神经网络

BP神经网络是一种非线性多层前向反馈网络。BP神经网络般分为三层,分别是输入层、隐含层和输出层,这三层中的每一层的神经元状态只影响下一层的神经元状态,若预测结果得不到期望输出,网络则进行反向传播。主要思路是:输入数据,利用反向传播算法对网络的权值和阈值不断地进行调整训练,根据预测误差调整权值和阈值,输出与期望趋近的结果,直到预测结果可以达到期望。
在这里插入图片描述
BP神经网络对输入数据的处理步骤如下:
(1)初始化网络。初始化输入层和隐含层,以及输出层神经元之间的连接权值ωij,ωjk,初始化隐含层和输出阈值a,b,并设置学习率和激活函数
(2)计算隐含层输出。ωij,a分别为输入层和隐含层间的连接权值及隐含层阈值,隐含层输出H的计算为:
在这里插入图片描述
l为隐含层激活函数
(3)计算输出层。H为隐含层的输出,BP网络的预测输出Y为:
在这里插入图片描述
(4) 计算误差。误差e的计算为:
在这里插入图片描述
Ok是实际期望的值
(5)更新权值
在这里插入图片描述
η是学习率
(6)阈值更新。根据预测误差e更新网络的阈值a,b:
在这里插入图片描述
(7)判断迭代是否可以结束,若算法迭代没有结束,则返回第(2)步,直到算法结束。

!!!第(1)步到第(3)是信号的前馈过程,第(4)步到第(7)步是神经网络反向更新参数的过程。

通过TensorFlow实现BP神经网络

# -*- coding: utf-8 -*-
"""
Created on Mon Oct 31 11:50:53 2022

@author: Yangz
"""

#import tensorflow as tf
from numpy.random import RandomState
import tensorflow.compat.v1 as tf
#tensorflow版本原因2.0往上的用这种方式
tf.compat.v1.disable_eager_execution()
'''
定义神经网络的参数、输入、输出节点

Variable()函数,在TensorFlow的世界里,变量的定义和初始化是分开的,所有关于图变量的赋值和计算
都要通过tf.Session的run来进行。想要将所有图变量进行集体初始化时应该使用
tf.global_variables_initializer。

placeholder()函数是在神经网络构建graph的时候在模型中的占位,此时并没有把要输入的数据传入模型,
它只会分配必要的内存。等建立session,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据。
'''
#定义训练数据的大小,是每次的训练数据
batch_size = 10 
#声明w1变量,生成2*3的矩阵,均值为0,标准差为1
w1 = tf.Variable(tf.random.normal([2,3],mean=0,stddev=1,seed=1))
#声明w2变量,生成3*1的矩阵,均值为0,标准差为1
w2 = tf.Variable(tf.random.normal([3,1],mean=0,stddev=1,seed=1))
#定义输入x和输出y_
x = tf.placeholder(tf.float32,shape=(None,2),name="x-input")
y_ = tf.placeholder(tf.float32,shape=(None,1),name="y-output") #实际期望值,后面是Y

'''
定义前向传播过程
'''
#前向传播
a = tf.matmul(x, w1) #矩阵乘法
y = tf.matmul(a, w2)  #网络预测值
'''
定义损失函数
'''
#tf.clip_by_value(a,b,c)a是一个矩阵,b是最小值,c是最大值;这个方法是控制a里面的值。
#如果里面的值小于b,输出b,大于c就输出c
cross_entropy = - tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y,1e-10,1.0))) #对数损失函数
'''
定义反向传播算法,修正权重w,偏置a,和学习率
'''
#AdamOptimizer是TensorFlow中实现Adam(自适应矩估计)算法的优化器。
#是一个寻找全局最优点的优化算法,引入了二次梯度校正。 0.001是权重的更新比率
#利用反向传播算法对权重和偏置项进行修正,同时也在运行中不断修正学习率
#.minimize(loss_function)的含义是根据其损失量学习自适应,损失量大则学习率大,
#进行修正的角度越大,损失量小,修正的幅度也小,学习率就小,但是不会超过自己所设定的学习率。
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)

'''
生成模拟数据集,用于训练神经网络
'''
rdm = RandomState(1) #定义一个随机数种子
#数据量大小为128
dataset_size = 128
X = rdm.rand(dataset_size,2) #产生[0,1)之间的数组128*2
Y = [[int(x1 + x2 <1)] for (x1,x2) in X] #Y是与X所对应的存放布尔类型值的list,留为实际值
'''
创建一个会话来运行TensorFlow程序,其实这里只是查看了一下w1、w2,
不创建会话的情况下误差执行上面Tensorflow生成语句
'''
#可以理解为TensorFlow下定义的语句不会立即执行,只有等到开启会话session时,才会执行session.run()语句

with tf.Session() as sess:
    #初始化变量,只有在定义了变量之后才可以初始化
    #init_op = tf.initialize_all_variables() 已被弃用
    init_op = tf.global_variables_initializer()
    sess.run(init_op) #
    #输出目前(未经训练)的参数取值
    print(sess.run(w1))
    print(sess.run(w2))
    print("\n")
    '''
    最后训练模型,得到训练后的参数结果
    '''
    #设定训练轮数
    STEPS = 5000
    #训练的循环
    for i in range(STEPS):
        #每次只训练10个样本数据
        start = (i * batch_size) % dataset_size
        end = min(start + batch_size,dataset_size)
        #利用feed_dict喂入数据
        sess.run(train_step,feed_dict = {x:X[start:end],y_:Y[start:end]})
        if i % 1000 == 0:
            #每隔1000轮,计算在所有数据上的交叉熵并输出
            total_cross_entropy = sess.run(cross_entropy,feed_dict={x:X,y_:Y})
            print('After %d training step(s),cross_entropy on all data is %g' % (i,total_cross_entropy))
        #输出训练后的参数取值
    print(sess.run(w1))
    print(sess.run(w2))
    print("\n")
  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值