第3章 单层感知器与线性神经网络
3.1 生物神经网络
一个多输入单输出非线性系统的动态过程
3.2 单层感知器
3.2.1单层感知器介绍
f(x)称为激活函数,可以理解为信号在轴突上进行的线性或非线性变化。
sign(x)激活函数
当x>0 时,输出值为1;当x=0 时,输出值为0,;当x<0 时,输出值为-1
3.2.2单层感知器计算举例
假如有一个单层感知器有3 个输入
x
1
,
x
2
,
x
3
x_1,x_2,x_3
x1?,x2?,x3?,同时已知b=-0.6,
𝑤
1
=
𝑤
2
=
𝑤
3
𝑤_1=𝑤_2=𝑤_3
w1?=w2?=w3?=0.5, 单层感知器的计算公式𝑓(Σi(𝑤i𝑥i) + 𝑏),则: 若
𝑥
1
=
0
,
𝑥
2
=
0
,
𝑥
3
𝑥_1=0, 𝑥_2=0, 𝑥_3
x1?=0,x2?=0,x3?=0:sign(0.5 × 0 + 0.5 × 0 + 0.5 × 0 ? 0.6) = ?1 若
𝑥
1
=
0
,
𝑥
2
=
0
,
𝑥
3
𝑥_1=0, 𝑥_2=0, 𝑥_3
x1?=0,x2?=0,x3?=1:sign(0.5 × 0 + 0.5 × 0 + 0.5 × 1 ? 0.6) = ?1
3.2.3单层感知器的另一种表达形式
偏置也作为一个输入神经元,b =
x
0
w
0
x_0w_0
x0?w0? =
w
0
w_0
w0? 表达形式更加简洁,更适合使用矩阵来进行运算。
3.3 单层感知器的学习规则
x1,x2,…xn对应于w1,w2,…wn等权值,然后利用公式$\Delta w = \eta(\hat y - y) $ 不断调整,更新权值,知道与真实值一样为止。
3.3.1单层感知机的学习规则介绍
3.3.2单层感知机的学习规则计算举例
见下面代码段1,用两种方法展现,一个是普通算法,一个是向量化,很明显向量化高效。
3.4 学习率
(1)学习率𝜼取值一般取0-1之间; (𝟐)学习率太大容易造成权值调整不稳定; (3)学习率太小,模型参数调整太慢,迭代次数太多。
3.5模型的收敛条件
通常模型的收敛条件可以有以下3 个: (1)loss小于某个预先设定的较小的值; (2)两次迭代之间权值的变化已经很小了; (3)设定最大迭代次数,当迭代超过最大次数就停止。
3.6模型的超参数和参数的区别
超参数:人为设置的一些模型相关的参数。比如说前面提到的学习率,学习 率需要根据经验来人为设置。比如模型的迭代次数,也是需要在模型训练之前预先进行人为设 置。 参数:模型中需要训练的变量。如权值和偏置。
3.7单层感知器分类案例
题目:假设我们有4 个2 维的数据,数据的特征分别是(3,3),(4,3),(1,1),(2,1)。(3,3),(4,3) 这两个数据的标签为1,(1,1),(2,1)这两个数据的标签为-1。构建神经网络来进行分类。
-
通常数据有几个特征(几维)就设几个输入神经元,偏置可以做一个输入神经元也可以不做 -
向量化同时计算所有数据的预测值,利用矩阵乘法,维度为保持一致,可以加一个1,在乘法过程中,会发现转化为偏置。 -
,但是使用单层感知器来做分类的时候,最后得到的分类边界距离某一个类别比较近,而距离另一个类别比较远,并不是一个特别理想的分类效果。图3.7 中的分类效果应该才是比较理想的分类效果,分界线在两个类别比较中间的位置。 代码见下面。(第三个)
3.8 线性神经网络
3.8.1线性神经网络介绍
线性神经网络跟单层感知器非常类似,只是把单层感知器的sign激活函数改成了purelin 函数: 𝑦 = 𝑥
3.8.2线性神经网络分类案例
3.9 线性神经网络处理异或问题
- 异或规则:
(1) 0与0异或等于0;
(2) 0与1异或等于1;
(3) 1与0异或等于1;
(4) 1与1异或等于0。
总结:相同的为0,相异的为1
- 线性神经网络引入非线性解决异或问题
线性神经网络解决不了异或问题,在图像中可以很明显的看出一条直线是不可能将两个类别划分开的,必须引入非线性特征,非线性特征可以从原有特征拼凑。 代码见下面:引入非线性特征前与引入非线性特征后的对比。
import numpy as np
x0 = 1
x1 = 0
x2 = -1
w0 = -5
w1 = 0
w2 = 0
t = 1
lr = 1
b = 0
for i in range(100):
print(w0,w1,w2)
y = np.sign(w0*x0 + w1*x1 + w2*x2)
if(y != t):
w0 = w0 + lr*(t-y)*x0
w1 = w1 + lr*(t-y)*x1
w2 = w2 + lr*(t-y)*x2
else:
print('done')
break
-5 0 0
-3 0 -2
-1 0 -4
done
import numpy as np
X = np.array([[1,0,-1]])
W = np.array([[-5],
[0],
[0]])
t = 1
lr = 1
b = 0
for i in range(100):
print(W)
y = np.sign(np.dot(X,W))
if(y != t):
W = W + lr*(t-y)*X.T
else:
print('done')
break
[[-5]
[ 0]
[ 0]]
[[-3]
[ 0]
[-2]]
[[-1]
[ 0]
[-4]]
done
import numpy as np
import matplotlib.pyplot as plt
X = np.array([[1,3,3],
[1,4,3],
[1,1,1],
[1,2,1]])
T = np.array([[1],
[1],
[-1],
[-1]])
W = np.random.random([3,1])
lr = 0.1
Y = 0
def train():
global W
Y = np.sign(np.dot(X,W))
E = T - Y
delta_W = lr*(X.T.dot(E))/X.shape[0]
W = W + delta_W
for i in range(100):
train()
print('epoch:',i+1)
print('weighets:',W)
Y = np.sign(np.dot(X,W))
if(Y==T).all():
print("当前周期数:",i+1)
print("当前权值:",W)
print("当前结果:",Y)
print('Finished')
break
epoch: 1
weighets: [[ 0.2335144 ]
[-0.08645354]
[-0.07396917]]
epoch: 2
weighets: [[0.2835144 ]
[0.21354646]
[0.17603083]]
epoch: 3
weighets: [[0.1835144 ]
[0.06354646]
[0.07603083]]
epoch: 4
weighets: [[ 0.0835144 ]
[-0.08645354]
[-0.02396917]]
epoch: 5
weighets: [[0.1835144 ]
[0.26354646]
[0.27603083]]
epoch: 6
weighets: [[0.0835144 ]
[0.11354646]
[0.17603083]]
epoch: 7
weighets: [[-0.0164856 ]
[-0.03645354]
[ 0.07603083]]
epoch: 8
weighets: [[-0.0664856 ]
[-0.08645354]
[ 0.02603083]]
epoch: 9
weighets: [[0.0335144 ]
[0.26354646]
[0.32603083]]
epoch: 10
weighets: [[-0.0664856 ]
[ 0.11354646]
[ 0.22603083]]
epoch: 11
weighets: [[-0.1664856 ]
[-0.03645354]
[ 0.12603083]]
当前周期数: 11
当前权值: [[-0.1664856 ]
[-0.03645354]
[ 0.12603083]]
当前结果: [[ 1.]
[ 1.]
[-1.]
[-1.]]
Finished
x1 = [3,4]
y1 = [3,3]
x2 = [1,2]
y2 = [1,1]
k = -W[1]/W[2]
d = -W[0]/W[2]
print(k,d)
xdata = (0,5)
plt.figure(figsize=(6.8,4.5),dpi=200)
plt.plot(xdata,xdata*k+d,'r')
sample_p = plt.scatter(x1,y1,c='b')
sample_n = plt.scatter(x2,y2,c='y')
font1 = {'family' : 'Times New Roman',
'weight' : 'bold',
'size' : 11,
}
legend = plt.legend(handles=[sample_p,sample_n],labels=["positive sample","negative sample"],loc="lower right",prop=font1)
plt.show()
[0.28924306] [1.32099103]
import numpy as np
import matplotlib.pyplot as plt
X = np.array([[1,0,0],
[1,0,1],
[1,1,0],
[1,1,1]])
T = np.array([[-1],
[1],
[1],
[-1]])
W = np.random.random([3,1])
lr = 0.1
Y = 0
def train():
global W
Y = np.dot(X,W)
delta_W = lr*(X.T.dot(T-Y))/X.shape[0]
W = W + delta_W
for i in range(100):
train()
Y = np.dot(X,W)
print(Y)
x1 = [0,1]
y1 = [1,0]
x2 = [0,1]
y2 = [0,1]
k = -W[1]/W[2]
d = -W[0]/W[2]
xdata = (-2,3)
plt.figure(figsize=(3.2,4.5),dpi=200)
plt.plot(xdata,xdata*k+d,'r')
plt.scatter(x1,y1,c='b')
plt.scatter(x2,y2,c='y')
font1 = {'family' : 'Times New Roman',
'weight' : 'bold',
'size' : 7.5,
}
legend = plt.legend(handles=[sample_p,sample_n],labels=["positive sample","negative sample"],loc="lower right",prop=font1)
plt.show()
[[-0.1089797 ]
[-0.00796449]
[-0.02623974]
[ 0.07477546]]
import numpy as np
import matplotlib.pyplot as plt
X = np.array([[1,0,0,0,0,0],
[1,0,1,0,0,1],
[1,1,0,1,0,0],
[1,1,1,1,1,1]])
T = np.array([[-1],
[1],
[1],
[-1]])
W = np.random.random([6,1])
lr = 0.1
Y = 0
def train():
global W
Y = np.dot(X,W)
E = T-Y
delta_W = lr * (X.T.dot(T - Y)) / X.shape[0]
W = W+delta_W
for i in range(1000):
train()
Y = np.dot(X,W)
print(Y)
x1 = [0,1]
y1 = [1,0]
x2 = [0,1]
y2 = [0,1]
def calculate(x,root):
a = W[5]
b = W[2]+x*W[4]
c = W[0]+x*W[1]+x*x*W[3]
if root == 1:
return (-b+np.sqrt(b*b-4*a*c))/(2*a)
if root==2:
return (-b-np.sqrt(b*b-4*a*c))/(2*a)
xdata = np.linspace(-1,2,100)
plt.figure(figsize=(3.2,4.5),dpi=200)
plt.plot(xdata,calculate(xdata,1),'r')
plt.plot(xdata,calculate(xdata,2),'r')
plt.plot(x1,y1,'bo')
plt.plot(x2,y2,'yo')
font1 = {'family' : 'Times New Roman',
'weight' : 'bold',
'size' : 7.5,
}
legend = plt.legend(handles=[sample_p,sample_n],labels=["positive sample","negative sample"],loc="lower right",prop=font1)
plt.show()
[[-0.9864406 ]
[ 0.99094536]
[ 0.99094536]
[-0.99299371]]
|