感知器,为了改变权值
模型收敛条件:
误差小于某个预先设定的较小的值
两次迭代之间的权值变化已经很小
设定最大迭代次数,当迭代超过最大次数就停止
单层感知器程序
import numpy as py
import matplotlib.pyplot as plt
# 输入数据
X = np.array([[1,3,3],[1,4,3],[1,1,1],[1,0,2]])
# 标签
Y = np.array([[1],[1],[-1],[-1]])
# 权重初始化,3行1列,取值范围-1到1
W = (np.random.random([3,1])-0.5) * 2
print(W)
# 学习率设置
lr = 0.11
# 神经网络输出
O = 0
# 权值的更新
def update():
global X,Y,W,lr
O = np.sign(np.dot(X,W)) # shape:(3,1)
W_C = lr * (X.T.dot(Y-O)) / int(X.shape[0])
W = W + W_C
for i in range(100):
update() # 更新权值
print(W)
O = np.sign(np.dot(X,W)) # 计算当前输出
if (O == Y).all(): #如果实际输出等于期望输出,模型收敛,循环结束
print('Finished')
print('epoch:',i)
break
# 正样本
x1 = [3,4]
y1 = [3,3]
# 负样本
x2 = [1,0]
y2 = [1,2]
# 计算分界线斜率以及截据
k = -W[1] / W[2]
d = -W[0] / W[2]
print('k=:',k)
print('d=:',d)
xdata = (0,5)
plt.figure()
plt.plot(xdata,xdata*k+d,'r')
plt.scatter(x1,y1,c = 'b')
plt.scatter(x2,y2,c = 'y')
plt.show()
线性神经网络
线性神经网络在结构上与感知其非常相似,只是激活函数不同.
在模型训练时把原来的sign函数改成purelin函数:y = x
import numpy as py
import matplotlib.pyplot as plt
# 输入数据
X = np.array([[1,3,3],[1,4,3],[1,1,1],[1,0,2]])
# 标签
Y = np.array([[1],[1],[-1],[-1]])
# 权重初始化,3行1列,取值范围-1到1
W = (np.random.random([3,1])-0.5) * 2
print(W)
# 学习率设置
lr = 0.11
# 神经网络输出
O = 0
# 权值的更新
def update():
global X,Y,W,lr
O = np.dot(X,W) # shape:(3,1) 激活函数
W_C = lr * (X.T.dot(Y-O)) / int(X.shape[0])
W = W + W_C
for i in range(100):
update() # 更新权值
print(W)
O = np.sign(np.dot(X,W)) # 计算当前输出
if (O == Y).all(): #如果实际输出等于期望输出,模型收敛,循环结束
print('Finished')
print('epoch:',i)
break
# 正样本
x1 = [3,4]
y1 = [3,3]
# 负样本
x2 = [1,0]
y2 = [1,2]
# 计算分界线斜率以及截据
k = -W[1] / W[2]
d = -W[0] / W[2]
print('k=:',k)
print('d=:',d)
xdata = (0,5)
plt.figure()
plt.plot(xdata,xdata*k+d,'r')
plt.scatter(x1,y1,c = 'b')
plt.scatter(x2,y2,c = 'y')
plt.show()
Delta学习规则,也就是连续感知器
代价函数(损失函数)
二次代价函数:
误差E是权向量W的函数,我们可以使用梯度下降法来最小化E的值:
线性神经网络---异或问题解决
import numpy as py 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]]) # 标签, Y = np.array([-1,1,1,-1]) # 权重初始化,因为有六个权值,取值范围-1到1 W = (np.random.random(6)-0.5) * 2 print(W) #[ 0.39617902 0.82250075 0.65458569 -0.52517089 0.2258532 -0.77084044] # 学习率设置 lr = 0.11 # 神经网络输出 O = 0 # 权值的更新 def update(): global X,Y,W,lr O = np.dot(X,W) # shape:(3,1) W_C = lr * (X.T.dot(Y-O)) / int(X.shape[0]) W = W + W_C for i in range(1000): update() # 更新权值 # 正样本 x1 = [0,1] y1 = [1,0] # 负样本 x2 = [0,1] y2 = [0,1] # 因为异或问题本身就是一个直线就不需要分界线 # 计算分界线斜率以及截据 # k = -W[1] / W[2] # d = -W[0] / W[2] # print('k=:',k) # print('d=:',d) 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) else: 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.scatter(x1,y1,c = 'b') plt.scatter(x2,y2,c = 'y') plt.show()
![]()