理论部分:
注:训练时候使用purelin函数,输出的时候使用sign函数用于分类
dj:期望输出 oj:实际输出
学习率可以通过开始选择大值,之后选择小值来收敛。
局部最优解在后续内容中会提出解决方案
注;我个人认为是解决非线性问题(决绝异或问题,把异或问题分为两类)未查证
代码部分:使用python实现
import numpy as np
import matplotlib.pyplot as plt
#####################################
#线性神经网络与单层感知器代码区别
#1激活函数不同
#2收敛条件改变了(收敛共有3个方式表现 一、误差达到比较小的值 二、权值的改变了比较小,区域稳定 三、循环一定次数后——本程序使用收敛条件)
#3引入多输入来解决异或问题
#####################################
#输入数据 //小技巧其中X数组中的第一个 1 表示偏置b
# [b,x1,x2]
#原数据 X=np.array([[1,0,0],
# [1,0,1],
# [1,1,0],
# [1,1,1]])#此时的X数据为四个点,用单层感知器无法进行分类
# 升维后 [b,x1,x2,x1^2,x1*x2,x2^2]
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]])#此时的X数据为四个点,用单层感知器无法进行分类
#标签
Y=np.array([-1,1,1,-1])
#权值初始化,
W=(np.random.random(6)-0.5)*2
print(W)
#定义学习率
lr=0.11
#计算迭代次数变量
n=0
#神经网络的输出
O=0
def update():
global X,Y,W,lr,n
n+=1
O=np.dot(X,W.T)#np.sign(np.dot(X,W.T))#感知器
W_C=lr*(Y-O.T).dot(X)/int(X.shape[0])#除以会缩小权值改变
W=W+W_C
for _ in range(1000):
update()#更新权值
#收敛条件为迭代1000次后
#正样本
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)
plt.figure()
plt.plot(xdata,calculate(xdata,1),'r')
plt.plot(xdata,calculate(xdata,2),'r')
plt.plot(x1,y1,'bo')
plt.plot(x2,y2,'yo')
plt.show()
#输出模型的值
O=np.dot(X,W.T)
print(O)
结果:
画图函数计算原理如下
网友评论