本小节主要讲述的是神经网络与感知机的区别,进而介绍其结构;激活函数的介绍,其引入的必要性和种类;最后就是神经网络输出层的一些要求介绍。
3.神经网络
3.1神经网络
神经网络的结构和感知机非常相似。以上图为例,该网络由三层神经元构成:输入层,中间层(也叫作隐藏层)和输出层。由于该网络只有两层神经元有权重,因此也将其称为“两层网络”,类比,将实际拥有权重的层数来表示网络的名称
3.2 感知机和神经网络的区别
- 优缺点的比较
感知机:好处是即便对于复杂的函数,感知机通过叠加层数,也能够进行表示;不好的地方在于,在感知机中,模型中的权重都是人为给定的,不能够自动更新。
神经网络:就能够解决权重的自动更新问题,本章主要介绍神经网络的概念和神经网络进行识别时的处理;在第四章节中,我们将了解如何从数据中学习权重参数 - 复习下感知机:
两个输入信号,一个输出信号组成了一种最简单的感知机。输入的信号分别于其权重相乘再求和(x1w1+x2w2),得到的值与一个临界值θ相比,如果比θ大,那么就输出1,也称为“神经元被激活”,如果比θ小,那么输出0。这个临界值也叫作阀值。
计算公式表示为:
上式可以分为两部分:
输入信号的值会被h(x)转换,转换后的值就是输出y。h(x)是一个阶跃函数,这种转换函数统称为激活函数,对于感知机,其激活函数大部分情况都是阶跃函数。
- 感知机与神经网络的区别:
感知机和神经网络在结构上几乎没有区别,最重要的区别可以认为在激活函数上面。一般认为感知机是单层的,激活函数是阶跃函数,而多层感知机也即神经网络,有各种各样的激活函数。
3.3 激活函数
激活函数:将加权输入信号和偏置的总和,转换为输出信号,这种函数一般称为激活函数,如上面的h(x)函数。常见的激活函数有:sigmoid函数,阶跃函数,ReLU函数和softmax函数。
3.3.1 sigmoid函数
sigmoid函数是神经网络中经常出现的一种激活函数,数学公式表达如下:
图像表示:
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x): #定义sigmoid子函数
return 1/(1+np.exp(-x))
x=np.arange(-5.0,5.0,0.1)
y2=sigmoid(x)
plt.plot(x,y2) #图形的绘制
plt.ylim(-0.1,1.1) #限定y轴的坐标
plt.legend(['sigmoid'],loc='upper left')
plt.show() #图形的显示
输出:
3.3.2 阶跃函数
阶跃函数是在感知机中经常,数学公式表达如下:
图像显示:
import numpy as np
import matplotlib.pyplot as plt
def step_function(x):
y=x>0
return y.astype(np.float) #astype函数为类型转换函数,转换为float类型
x=np.arange(-5.0,5.0,0.1)
y1=step_function(x)
plt.plot(x,y1,linestyle="--") #图形的绘制
plt.ylim(-0.1,1.1) #限定y轴的坐标
plt.legend(['step_function'],loc='upper left')
plt.show() #图形的显示
输出:
3.3.3 ReLU函数
阶跃函数和sigmoid函数很早就开始使用了,ReLU函数最近经常在使用,其数学公式表达如下:
图像显示:
import numpy as np #库的调用
import matplotlib.pyplot as plt
def ReLU(x): #ReLU子函数的定义
return np.maximum(0,x)
x=np.arange(-2.0,2.0,0.1)
y3=ReLU(x)
plt.plot(x,y3) #图形的绘制
plt.ylim(-0.1,3) #限定y轴的坐标
plt.legend(['ReLU'],loc='upper left')
plt.show() #图形的显示
输出:
3.3.3 softmax函数
softmax在分类问题中经常出现,并位于输出层,其数学公式表达如下:
输出之和恒为1,这也就容易让人联想为概率,输出的值越大,其可能性越大,在分类问题中很适用。
子函数的定义:
def softmax(a): #softmax子函数的定义
exp_a=np.exp(a)
sum_exp_a=np.sum(exp_a)
y= exp_a/ sum_exp_a
return y
- 使用softmax可能会存在一个问题,那就是溢出,因为要对输出取指数,取出来的值有的时候会过大,超出变量的定义范围,故改进方法如下:每一个输入都减去一个输入的最大值。
功能实现代码:
#softmax有一个逸出的问题,解决办法如下:减去一个最大值;
def softmax1(x):
c=np.max(x) #选出x中的最大值
exp_x=np.exp(x-c) #对每一个x都减去一个x的最大值c
sum_exp_x=np.sum(exp_x) #对取对数的值求和
y=exp_x/sum_exp_x #输出值
return y
3.3.4恒等函数
恒等函数在回归问题中经常出现,并位于输出层,其可概述为:输出等于输入,即输出为加权输入信号和偏置的总和。恒等函数相当于没有激活函数。
3.4三层神经网络的实现
以下图三层神经网络为对象,实现从输入到输出的前向处理。
三层神经网络:输入层(第0层)有2个神经元,第1个隐藏层(第1层)有3个神经元,第2个隐藏层(第2层)有2个神经元,输出层(第3层)有2个神经元。
- 从输入层到第一层的信号传递
#输入层到第一层
X=np.array([1.0,0.5]) #输入
W1=np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]]) #第0层的权重
B1=np.array([0.1,0.2,0.3]) #偏置,个数与输出保持一致
A1=np.dot(X,W1)+B1
Z1=sigmoid(A1) #输出,激活函数为sigmoid函数
print('第一层输出:Z1=',Z1)
- 从第一层到第二层的信号传递
#第一层到第二层信息传输
X=Z1 #前一层的输出是后一层的输入
W2=np.array([[0.1,0.3],[0.2,0.4],[0.2,0.5]]) #第1层的权重
B2=np.array([0.1,0.2]) #偏置,个数与输出保持一致
A2=np.dot(X,W2)+B2
Z2=sigmoid(A2) #输出,激活函数为sigmoid函数
print('第一层输出:Z2=',Z2)
- 从第二层到输出层的信号传递
#第二层到输出层信息传输
X=Z2 #前一层的输出是后一层的输入
W3=np.array([[0.1,0.3],[0.2,0.4]]) #第1层的权重
B3=np.array([0.1,0.2]) #偏置,个数与输出保持一致
A3=np.dot(X,W3)+B3
y=softmax(A3) #输出,激活函数为softmax函数
print('输出层:y=',y)
- 代码的汇总
def init_network(): #初始的参数函数:这里是人为定义的,在下一章就是计算而来的
network={} #定义一个参数数组
network['W1']=np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
network['W2']=np.array([[0.1,0.3],[0.2,0.4],[0.2,0.5]])
network['W3']=np.array([[0.1,0.3],[0.2,0.4]])
network['B1']=np.array([0.1,0.2,0.3])
network['B2']=np.array([0.1,0.2])
network['B3']=np.array([0.1,0.2])
return network
def forward(network,X): #前向传播函数
W1,W2,W3=network['W1'],network['W2'],network['W3']
B1,B2,B3=network['B1'],network['B2'],network['B3']
A1=np.dot(X,W1)+B1
Z1=sigmoid(A1)
A2=np.dot(Z1,W2)+B2
Z2=sigmoid(A2)
A3=np.dot(Z2,W3)+B3
y=softmax(A3)
return y
network=init_network() #权重的确定
x=np.array([1.0,0.5]) #输入值
y=forward(network,x) #进行前向传播计算
print('最终输出y=',y) #输出
3.5输出层的设计
神经网络一般解决两类问题:分类问题和回归问题,一般分类问题的输出层选用softmax激活函数,回归问题的输出层选用恒值函数。
3.5.1 softmax函数和恒值函数
这两个函数在前面的激活函数中已经说明了。
3.5.2 输出层的神经元数量
输出层的神经元数量根据具体的情况进行确定,对于分类问题,输出神经元的数量等于分类的总量。
参考书籍:
1.《深度学习–基于python的理论与实现》