神经网络
一、单层神经网络原理与实践
1.生物神经网络原理
1.1生物神经网络原理
生物神经网络原理
从单细胞生物到多细胞生物

单细胞生物:整个生物体由1个细胞构成,在整个生物界中属于最低等最原始的生物,草履虫、蓝藻是典型的有核单细胞生物。没有神经系统,只有“应激性”
多细胞生物:多个、分化的细胞组成的生物体,细胞各有不同的、专门的功能,所有植物界和除粘体门外所有动物界的生物是多细胞生物。有条件反射与神经系统,多个细胞之间如何进行协同工作?
神经细胞的工作机制:网状理论reticular theory
神经系统是一个连续的网络结构,神经元细胞以某种方式连接成一个整体,神经细胞胞体只负责提供支持和营养,脑作为一个整体来实现它的复杂功能,无须关注细胞之间的协作。

神经细胞的工作机制:神经元理论 neurons theory
神经细胞之间是相互独立的,通过某种形式传递信号

神经元学说
卡哈尔总结提出神经元学说(Neuron Doctrine),被称为现代神经科学之父,与卡米洛・高尔基一起获得1906年诺贝尔生理学与医学奖

基于神经组织的发育、退化和再生的结构变化,卡哈尔还首先提出了神经联接的可塑性概念。
1.2MP模型
1943年心理学家W.S.McCulloch和数理逻辑学家W.Pitts提出人工神经元,称为M-P模型。

MP模型是一个基于阈值逻辑算法的神经网络计算模型,由固定的结构和权重构成,输入是0或者1
调整权重与偏置实现不同的数学逻辑

1.3单层感知器&梯度下降法&学习率
单层感知器
1957年,Frank Rosenblatt发明了感知器(Perceptron)结构与MP模型类似,一般视为最简单的人工神经网络。

感知器与MP模型区别:输入不是离散型0/1,激活函数不一定是阈值函数
感知器权重参数更新方法:梯度下降法
对于函数f(x),以x的梯度反方向进行更新,就能够减小f(x),这个方向还是减小f(x)的最快的方向,也被称为“最速下降法”。

梯度更新重要参数:学习率
学习率(Learning Rate),用于控制参数更新的步长

2.感知器与梯度反向传播
2.1线性分类问题
二维线性分类问题
单层感知器作为线性分类器被广泛应用

问题分析

2.2单层感知器求解
令误差函数为L,预测值为y,阈值函数f为符号函数

基于梯度下降法的参数更新为:

基于Python求解单层感知器算法
- 代码实现与结果示意

# Copyright 2021 longpeng2008. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# If you find any problem,please contact us
# Author: longpeng
# Email: longpeng2008to2012@gmail.com
#coding:utf8
import numpy as np
import matplotlib.pyplot as plt
n = 0 # 模型收敛需要的迭代次数
lr = 0.10 # 学习速率
# 输入数据,三个维度分别表示偏置,x坐标,y坐标
X = np.array([[1,2,3],
[1,4,5],
[1,1,1],
[1,5,3],
[1,0,1]])
# 标签
Y = np.array([1,1,-1,1,-1])
# 要学习的模型,f(WX+B),对于正样本,f(WX+b)>0,对于负样本,f(WX+b)<0
# 权重W初始化,取值范围-1到1
W = (np.random.random(X.shape[1])-0.5)*2
# 可视化函数
def get_show():
# 正样本
all_positive_x = [2,4,5]
all_positive_y = [3,5,3]
# 负样本
all_negative_x = [1,0]
all_negative_y = [1,1]
# 计算分界线斜率与截距,W[0]+W[1]*x+W[2]*y=0
k = -W[1] / W[2]
b = -(W[0])/ W[2]
# 生成x刻度
xdata = np.linspace(0, 5)
plt.figure()
plt.plot(xdata,xdata*k+b,'r')
plt.plot(all_positive_x, all_positive_y,'bo')
plt.plot(all_negative_x, all_negative_y, 'yo')
plt.xlabel('x')
plt.ylabel('y')
plt.show()
# 更新权值函数
def get_update():
#定义所有全局变量
global X,Y,W,lr,n
n += 1
#计算符号函数输出
new_output = np.sign(np.dot(X,W.T))
#更新权重
new_W = W + lr*((Y-new_output.T).dot(X))
W = new_W
def main():
for _ in range(100):
get_update()
new_output = np.sign(np.dot(X, W.T))
if (new_output == Y.T).all():
print("迭代次数:", n)
break
get_show()
if __name__ == "__main__":
main()
二、多层神经网络原理与实践
1.多层感知器与反向传播算法
1.1多层感知器
单层感知器的缺陷
马文・明斯基在1969年出版《感知器》书中证明单层感知器无法解决异或问题

多层感知器Multi Layer Perceptron
简称MLP:在单层神经网络基础上引入一个或多个隐藏层,使网络有多个网络层,被称为多层感知器,或前馈神经网络。

多层感知器表达能力
多层感知机解决异或问题

万能逼近定理
- George Cybenko在1989年首次严格给出并论证了用以Sigmoid函数作为激活函数的神经网络的逼近能力:只要有一个隐藏层,前馈型神经网络就能一致逼近至任意连续函数。
- Cybenko G.Approximation by superpositions of a sigmoidal function[J].Mathematics of control,signals and systems,1989,2(4):303-314.
- Hornik7在1991年证明多层前馈神经网络的结构本身给神经网络提供了泛逼近性(Universal Approximators),即泛逼近定理(Universal Approximation Theorem)
- K.Hornil,"Multilayer Feedforward Networks Are Universal Approximators,"Neural Networks,pp.359-366,1989.
- K.Hornil,"Approximation Capabilities of Multilayer Feedforward Networks,"Neural Networks,pp.251-257,1991.
1.2反向传播算法
什么是反向传播算法
1986年,Rummelhart、McClelland、Hinton等人改进了反向传播算法(Backpropagation,缩写为BP)用于多层神经网络学习

反向传播:损失函数开始从后向前,梯度逐步传递至第一层

1.3误差反向传播算法原理


因为当前层神经元的输入是上一层神经元输出的线性组合,所以可通过下层神经元的误差来表示当前层的误差

误差反向传播算法原理
- 基于反向传播算法的参数更新

2.多层神经网络案例实践
2.1异或问题
多层感知器可以解决单层感知器无法解决的异或问题

基于反向传播算法的参数更新

2.2.多层感知器求解
基于Python求解多层感知器算法

# Copyright 2021 longpeng2008. All Rights Reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # If you find any problem,please contact us # Author: longpeng # Email: longpeng2008to2012@gmail.com #coding:utf8 import numpy as np import matplotlib.pyplot as plt # 输入数据 X = np.array([[1,0,0],[1,0,1],[1,1,0],[1,1,1]]) # 标签 Y = np.array([[0,1,1,0]]) V = (np.random.random((3,4))-0.5)*2 # 第一个网络层参数矩阵,初始化输入层权值,取值范围-1到1 W = (np.random.random((4,1))-0.5)*2 # 第二个网络层参数矩阵,初始化输出层权值,取值范围-1到1 def get_show(): # 正样本 all_positive_x = [0,1] all_positive_y = [0,1] # 负样本 all_negative_x = [0,1] all_negative_y = [1,0] plt.figure() plt.plot(all_positive_x, all_positive_y,'bo') plt.plot(all_negative_x, all_negative_y, 'yo') plt.xlabel('x') plt.ylabel('y') plt.show() # get_show() lr = 0.11 # 激活函数(从0~1) def sigmoid(x): x = 1/(1+np.exp(-x)) return x # 激活函数的导数,f'(x)=f(x)(1-f(x)),dsigmoid(x)=sigmoid(x)*(1-sigmoid(x)) def dsigmoid(x): x = x*(1-x) return x # 更新权值(2个权值矩阵,V和W) def update(): global X,Y,W,V,lr L1 = sigmoid(np.dot(X,V)) # 隐藏层输出(4*3)×(3*4)=(4,4) L2 = sigmoid(np.dot(L1,W)) # 输出层输出(4,4)×(4*1)=(4,1) L2_delta = (Y.T - L2)*dsigmoid(L2) # 输出层的误差=下一层的误差*激活函数导数*与下一层的连接权重矩阵(全为1) L1_delta = L2_delta.dot(W.T)*dsigmoid(L1) # 隐藏层的误差=下一层的误差*激活函数导数*与下一层的连接权重矩阵 W_C = lr*L1.T.dot(L2_delta) # 输出层参数更新值=学习率*误差*上一层的激活值 V_C = lr*X.T.dot(L1_delta) # 隐藏层参数更新=学习率*误差*上一层的激活值 W = W + W_C V = V + V_C errors = [] # 记录误差 for i in range(100000): update() # 更新权值 if i % 1000 == 0: # 输出误差 L1 = sigmoid(np.dot(X,V)) L2 = sigmoid(np.dot(L1,W)) errors.append(np.mean(np.abs(Y.T - L2))) print('Error:',np.mean(np.abs(Y.T - L2))) plt.plot(errors) plt.ylabel('errors') plt.show() L1 = sigmoid(np.dot(X,V)) # 隐藏层输出(4*3)×(3*4)=(4,4) L2 = sigmoid(np.dot(L1,W)) # 输出层输出(4,4)×(4*1)=(4,1) print(L2) def classify(x): if x > 0.5: return 1 else: return 0 for i in map(classify,L2): # L2一共四个数 print(i)
三、序列神经网络
1.序列预测问题与RNN模型
1.1序列预测问题
典型序列预测问题-分类
- 输入不定长序列,给出类别预测,常采用Sequence-to-vector结构

典型序列预测问题-同步序列预测
- 输入不定长序列,输出同样长度的标注结果,常采用Sequence-to-sequence结构

典型序列预测问题-异步序列预测
- 输入不定长序列,输出不同长度的预测结果,常采用Encoder-Decoder结构

典型序列预测问题-序列生成
- 预测不定长的输出序列,常采用vector-to-Sequence结构

1.2循环神经网络
- Recurrent Neural Networks,简称RNN,一种带自反馈的神经网络,能够处理任意长度的时序数据

- 循环神经网络比前馈神经网络更加符合生物神经网络的结构,被广泛应用在语音识别、语言模型等任务上。
RNN模型展开
将RNN按照时间维度展开


RNN内部结构单元的计算
令x是长度为I的向量,ht 是长度为H的向量,将其拼接成(I+ H)的向量作为输入,对应权重系数W的维度是H(I +H)

1.3深层RNN模型
包含了多个隐藏层,获得更复杂的表达能力

- 每个隐藏状态不断传递到当前层的下一个时间步以及当前时间步的下一层
双向RNN模型
不仅包括正向过程,也包含反向过程

双向的RNN获得更加完整的“上下文”信息,具有更强大的表达能力,在语音识别,机器翻译任务中都得到了比单向RNN更好的性能
RNN的参数学习
随时间反向传播算法BPFT(backpropagation through time),误差不仅依赖于当前时刻t,也依赖于之前时刻k,0<k<t。


RNN梯度问题
- 存在长距离依赖问题(梯度爆炸或消失),参数更新主要依靠当前时刻的相邻状态


- (1)连乘存在Whh的坎次幂,如果矩阵特征值远大于1,多次连乘会造成梯度爆炸;如果远小于1,会造成梯度消失;
- (2)Tanh激活函数如果进入饱和区间,连乘后数值变得很小;
2.长短时记忆网络与门控循环单元
2.1长短时记忆网络
Long Short-Term Memory Network
简称LSTM,主要是为了解决RNN训练过程中的长距离依赖问题

引入新的内部状态cell state,它记忆重要时刻信息,生命周期介于长期与短期记忆之间。cell state状态更新是缓慢的,隐藏层h的更新是迅速的。
包含了三个门控单元,遗忘门、输入门与输出门,决定每一个时刻要舍弃什么旧的信息以及添加什么新的信息

- 遗忘门决定了要从cell state中舍弃什么信息
- 输入门决定了要往当前状态中保存什么新的信息
- 输出门决定了要从cell state中输出什么信息
2.2门控单元的计算

2.3门控循环单元
Gated Recurrent Unit(GRU)
- 对LSTM结构的简化,由更新门和重置门组成

- 更新门决定了要从历史信息中保留多少信息,捕捉长程依赖关系。
- 重置门用于控制候选状态C是否依赖于上一状态h t-1,可以用来丢弃与预测无关的历史信息。
门控单元的计算

