被誉为“人脑思维第二方式”的神经网络算法模型,今天它来了!
Posted 数聚应统
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了被誉为“人脑思维第二方式”的神经网络算法模型,今天它来了!相关的知识,希望对你有一定的参考价值。
在机器学习中,神经网络一般指的是“神经网络学习”,是机器学习与神经网络两个学科的交叉部分。所谓神经网络,目前用得最广泛的一个定义是“神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所做出的交互反应”。
一、神经元模型
1.神经元模型
神经网络中最基本的成分是神经元模型(neuron)。“M-P神经元模型”,也称“阈值逻辑单元”,在这个模型中神经元接收到来自n个其他神经元传递过来的输入信号,这些信号通过带权重的连接进行传递,神经元接收到的总输入值将与神经元的阈值进行比较,然后通过激活函数(activation function)的处理以产生神经元的输出。M-P神经元模型如下图所示:
2.激活函数
2.1激活函数的作用
给神经元引入非线性因素,使得神经网络可以任意逼近任何非线性函数,以便于神经网络利用到更多的非线性模型中。如果不使用激活函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出的都是输入的线性组合。
2.2神经网络中常用的激活函数
(1)阶跃函数 神经元模型最理想的激活函数是阶跃函数如图所示,即将神经元输入值与阈值的差值映射为输出值1或0,若差值大于零输出1,对应兴奋;若差值小于零则输出0,对应抑制。缺点是阶跃函数不连续,不光滑。
(2)Sigmoid函数 典型的Sigmoid函数如图(b)所示, Sigmoid函数将较大范围内变化的输入值挤压到 (0,1) 输出值范围内,所以也称为挤压函数(squashing function)。
Sigmoid函数也叫logistic函数,用于隐层神经元输出,取值范围为(0,1),它可以将一个实数映射到(0,1)的区间,可以用来二分类,在特征相差比较复杂或者相差不是特别大的时候效果比较好。
Sigmoid函数缺点:激活函数计算量大,反向传播求误差梯度时,求导涉及到除法;反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练。将多个神经元按一定的层次结构连接起来,就得到了神经网络。它是一种包含多个参数的模型,比方说10个神经元两两连接,则有100个参数需要学习(每个神经元有9个连接权以及1个阈值),若将每个神经元都看作一个函数,则整个神经网络就是由这些函数相互嵌套而成。
(3)Tanh 函数
tanh(x)取值范围是[-1,1]。tanh(x)在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果。与sigmoid区别是,tanh是0的均值,因此在实际应用中tanh会比sigmoid更好。在具体应用中,tanh函数相比于Sigmoid函数往往更具有优越性,这主要是因为sigmoid函数在输入处于[-1,1]之间时,函数值变化敏感,一旦接近或者超出区间就失去敏感性,处于饱和状态。
二、神经网络分类
三、感知机与多层感知机(MLP)
1.感知机(Perceptron)
1.1感知机的构造
感知机(Perceptron)是由两层神经元组成的一个简单模型,但只有输出层是M-P神经元,即只有输出层神经元进行激活函数处理,也称为功能神经元(functional neuron);输入层只是接受外界信号(样本属性)并传递给输出层(输入层的神经元个数等于样本的属性数目),而没有激活函数。感知机的输出层应该可以有多个神经元,从而可以实现多分类问题。
1.2感知机的工作原理
接受一个或者多个二进制输入,产生一个输出。引入权重, 表示相应输入对于输出重要性的实数。神经元的输出为0或1,由 小于或者大于阈值来决定。
2.S型神经元
背景:网络中单个感知器上一个权重或者偏置的微小改动有时候会引起感知器的输出完全翻转,如0变为1。这样的翻转可能接下来引起起于网络的行为以及其复杂的方式完全改变,这使得修改权重和偏置来让网络接近期望的行为变得困难。这时,我们可以引入一种S型神经元的新的人工神经元来解决这个问题。
输入: ,可取[0,1]中的任意值,而不仅是0和1;输出: , 称为S型函数。
S型神经元的输出是:
S型神经元与感知机的相似性:
假如z是一个很大的正数,那么 ,近似感知机;
假如z是一个很小的负数,那么 ,也近似感知机 但是z取在中间值时,偏离感知机模型。取决于 的形状。 的形状:阶跃函数平滑后
S型神经元是平滑后的感知机
的平滑意味着权重和偏置的微小变化,即: 和 ,会让神经元产生一个微小的输出变化 ,其中
注: 是一个反应权重和偏置变化的线性函数,线性使得选择权重和偏置的微小变化达到输出的微小变化的运算变得容易。S型神经元的输出可以是[0,1]的任何实数。
3.多层感知机MLP
3.1 多层感知机的构造
感知机(Perception)由两层神经元组成,输入层接受外界输入信号后传递给输出层,输出层是M-P神经元,也称‘阈值逻辑单元’。由于感知机模型只有一层功能神经元,因此其功能十分有限,只能处理线性可分的问题,对于这类问题,感知机的学习过程一定会收敛(converge),因此总是可以求出适当的权值。但是要解决非线性可分问题,需要考虑使用多层功能神经元,即神经网络。多层感知机由S型神经元构成,多层神经网络的拓扑结构如下图所示:
在神经网络中,输入层与输出层之间的层称为隐含层或隐层(hidden layer),隐层和输出层的神经元都是具有激活函数的功能神经元。只需包含一个隐层便可以称为多层神经网络,常用的神经网络称为“多层前馈神经网络”(multi-layer feedforward neural network),该结构满足以下几个特点:
-
每层神经元与下一层神经元之间完全互连 -
神经元之间不存在同层连接 -
神经元之间不存在跨层连接
根据上面的特点可以得知:这里的“前馈”指的是网络拓扑结构中不存在环或回路,而不是指该网络只能向前传播而不能向后传播(下节中的BP神经网络正是基于前馈神经网络而增加了反馈调节机制)。神经网络的学习过程就是根据训练数据来调整神经元之间的“连接权”以及每个神经元的阈值,换句话说:神经网络所学习到的东西都蕴含在网络的连接权与阈值中。
3.2最简单的多层感知机
多层感知机(MLP,Multilayer Perceptron)也叫人工神经网络(ANN,Artificial Neural Network),除了输入输出层,它中间可以有多个隐层,最简单的MLP只含一个隐层,即三层的结构,如下图:
从上图可以看到,多层感知机层与层之间是全连接(上一层的任何一个神经元与下一层的所有神经元都有连接)。多层感知机最底层是输入层,中间是隐藏层,最后是输出层。输入层:输入是一个n维向量,就有n个神经元。
隐藏层:隐藏层的神经元怎么得来?首先它与输入层是全连接的,假设输入层用向量X表示,则隐藏层的输出就是 f (W1X+b1),W1是权重(也叫连接系数),b1是偏置,函数f 可以是常用的sigmoid函数或者tanh函数。
输出层:隐藏层到输出层可以看成是一个多类别的逻辑回归,也即softmax回归,所以输出层的输出就是 , 表示隐藏层的输出
MLP整个模型就是这样子的,这个三层的MLP可总结为下式:
因此,MLP所有的参数就是各个层之间的连接权重以及偏置,包括 、 、 、 。对于一个具体的问题,怎么确定这些参数?求解最佳的参数是一个最优化问题,解决最优化问题,最简单的就是上文提到的梯度下降法(SGD):首先随机初始化所有参数,然后迭代地训练,不断地计算梯度和更新参数,直到满足某个条件为止(比如误差足够小、迭代次数足够多时)。这个过程涉及到代价函数、规则化(Regularization)、学习速率(learning rate)、梯度计算等,本文不详细讨论。
四、BP神经网络算法(error Back Propagation)
神经网络的学习主要蕴含在权重和阈值中,多层网络使用简单感知机的权重调整规则显然不够用了,BP神经网络算法即误差逆传播算法(error Back Propagation)正是为学习多层前馈神经网络而设计,BP神经网络算法是迄今为止最成功的神经网络学习算法。
BP神经网络由信息的正向传播和误差的反向传播两个过程组成。这里以三层神经网络的误差逆传播算法为例。
1.正向传播过程
前向传播过程,即网络如何根据输入X得到输出Y的。记 为L-1层第k个神经元到第L层第j个神经元的权重, 为第L层第j个神经元的偏置, 为激活函数, 为第L层第j个神经元的激活值(激活函数的输出), 取值取决于上一层神经元的激活,写为矩阵形式为:
为方便表示,记 为每一层的权重输入,(1)式变为 ,利用(1)式一层层计算网络的激活值,最终能够根据输入X得到相应的输出 。
2. 反向传播过程
2.1 代价函数
训练神经网络的目的就是使得代价函数C最小化。假设总的代价函数可以表示为单个样本的代价函数之和的平均,于是,以二次损失函数为例,可以写出整个过程的代价函数:
其中,y=y(x)为期望的输出L为网络的层数, 网络的输出向量。而 是关于的函数,所以可通过不断地调整w,b来改变神经网络的输出。反向传播算法就是用来更新权重和偏置方法,权重w和偏置b的改变如何影响代价函数C是理解反向传播的关键,意味着我们需要算出每个 和 。
2.2 误差
这里引入误差的概念, 表示第L层第j个单元的误差,反向传播算法给出计算误差 的过程,并关联到 和 上。关于误差的理解,《Neural Network and Deep Learning》书中给了一个比较形象的例子。
(a)假设有个小恶魔在第L层第j个单元捣蛋,他让这个神经元的权重输出变化了 ,那么这个神经元的激活输出为 ,然后这个误差向后逐层传播下去,导致最终的代价函数变化了
(b)现在这个小恶魔改过自新,它想帮助我们尽可能减小代价函数的值(使网络输出更符合预期)。假设 一开始是个很大的正值或者负值,小恶魔通过选择一个和 方向相反的 使代价函数更小
(C)随着迭代的进行, 会逐渐趋向于0,那么 c)对于代价函数的改进效果就微乎其微了,这时小恶魔就一脸骄傲的告诉你:“俺已经找到了最优解了(局部最优)”。这启发我们可以用 来衡量神经元的误差。
2.3 反向传播步骤
(1)计算输出层的误差方程
第一项 衡量了代价函数随网络最终输出的变化快慢,而第二项 则衡量了激活函数输出随 的变化快慢。
(2)使用下一层的误差 来表示当前层 的误差方程,误差传递方程表示如下:
为Hadamard积,即矩阵的点积。利用该方法,可以计算网络中每一层的误差了。先计算 ,然后计算 一步步反向传播到输入层。
(3)计算代价函数对偏置的改变率和代价函数对权重的改变率
从上式可以看出,当输入神经元没有被激活,或者输出神经元处于饱和状态,权重和偏置会学习的非常慢。(4)由梯度下降法可得更新规则。
3.总结
BP神经网络训练过程的基本步骤可以归纳如下:
1)初始化网络权值和偏置,一般通过随机的方式进行归纳;
2)前向传播:计算隐层神经元和输出层神经元的输出;
3)反向传播:根据所求出每个神经元的误差值,更新权重和偏置。
上述过程反复迭代,通过损失函数对前向传播进行判定,并通过反向传播过程对参数进行修正,起到监督学习的作用,一直到满足最终条件为止。
案例分析
单层感知机
我们以鸢尾花数据集为例,由于单层感知器是一个二分类器,所以我们将鸢尾花数据也分为两类,“setosa”与“versicolor”(将后两类均看做第2类),那么数据按照特征:花瓣长度与宽度做分类。
iris<-read.csv("D:/Pycharm.project/Machine Learning/input/Iris.csv")
#感知器训练结果:
a<-0.2
w<-rep(0,3)
iris1<-t(as.matrix(iris[,4:5]))
d<-c(rep(0,50),rep(1,100))
e<-rep(0,150)
p<-rbind(rep(1,150),iris1)
max<-100000
eps<-rep(0,100000)
i<-0
repeat{
v<-w%*%p;
y<-ifelse(sign(v)>=0,1,0);
e<-d-y;
eps[i+1]<-sum(abs(e))/length(e)
if(eps[i+1]<0.01){
print("finish:");
print(w);
break;
}
w<-w+a*(d-y)%*%t(p);
i<-i+1;
if(i>max){
print("max time loop");
print(eps[i])
print(y);
break;
}
}
#绘图程序
plot(PetalLengthCm~PetalWidthCm,xlim=c(0,3),ylim=c(0,8),
data=iris[iris$Species=="Iris-virginica",])
data1<-iris[iris$Species=="Iris-versicolor",]
points(data1$PetalWidthCm,data1$PetalLengthCm,col=2)
data2<-iris[iris$Species=="Iris-setosa",]
points(data2$PetalWidthCm,data2$PetalLengthCm,col=3)
x<-seq(0,3,0.01)
y<-x*(-w[2]/w[3])-w[1]/w[3]
lines(x,y,col=4)
BP神经网络做分类~
这个特定的例子为开发一个神经网络来确定股票是否支付股息。因此,我们使用神经网络来解决分类问题。通过分类,我们指的是按类别对数据进行分类的分类。数据集中,将支付股息的股票分配值1。我们将值0分配给不支付股息的股票。此示例的数据集可在dividendinfo.csv中找到。
自变量如下:fcfps:每股自由现金流量(以美元计);income_growth:过去一年的盈利增长(%);de:债务与权益比率;mcap:股票的市值;current_ratio:流动比率(或流动资产/流动负债)。
mydata = read.csv("data/dividendinfo.csv")
attach(mydata)
# Scaled Normalization
# 对数据进行标准化,消除量纲的变化
scaleddata = scale(mydata)
# Max-Min Normalization
# 再将数据再进行0-1的标准化
normalize = function(x) {
return ((x - min(x)) / (max(x) - min(x)))
}
maxmindf = as.data.frame(lapply(mydata, normalize))
attach(maxmindf)
#Training and Test Data
trainset = maxmindf[1:160, ] # 80%
testset = maxmindf[161:200, ] #20%
#Neural Network
library(neuralnet)
nn1 = neuralnet(dividend ~ fcfps + earnings_growth + de + mcap + current_ratio, data = trainset, hidden = c(2,1), linear.output = FALSE, threshold = 0.01)
# 隐层有两层,第一层2个神经元,第二层1个神经元;因为是分类变量,所以线性输出设置为False,阈值先设置为0.01
plot(nn1)
# 确定神经网络中隐藏层的数量并不是一门精确的科学。
# 事实上,有些情况下,没有任何隐藏层,准确度可能会更高。
# 因此,反复试验在这一过程中起着重要作用。
# 再使用其他的隐藏层数量,比如:没有隐藏层
nn2 = neuralnet(dividend ~ fcfps + earnings_growth + de + mcap + current_ratio, data = trainset, linear.output = FALSE, threshold = 0.01)
plot(nn2)
# 误差比第一个模型大
# 现设置三层隐藏层
nn3 = neuralnet(dividend ~ fcfps + earnings_growth + de + mcap + current_ratio, data = trainset, hidden = c(2, 1, 2) , linear.output = FALSE, threshold = 0.01)
plot(nn3
# 将训练集所得模型检验测试集
# 将测试集中的自变量与因变量分离
temp_test = subset(testset, select = c("fcfps", "earnings_growth", "de", "mcap", "current_ratio"))
head(temp_test)
# 对测试集进行预测
nn.results = compute(nn3, temp_test)
# 准确率指标
results = data.frame(actual = testset$dividend, prediction = nn.results$net.result)
# 混乱矩阵
# 使用sapply对结果进行四舍五入,并创建一个混淆矩阵来比较真/假阳性和阴性的数量:
roundedresults = sapply(results, round, digits = 0)
roundedresultsdf = data.frame(roundedresults)
attach(roundedresultsdf)
table(actual, prediction
# 最终,确定股票是否支付股息时产生90%(36/40)的准确率。
排版:郑俊男,彭宜洛
指导:林红梅
以上是关于被誉为“人脑思维第二方式”的神经网络算法模型,今天它来了!的主要内容,如果未能解决你的问题,请参考以下文章