线性神经网络实现——八例题
import numpy as np
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) #purelin函数 y=x
W_C = lr * (X.T.dot(Y - o)) / int(X.shape[0])
W = W + W_C
for _ in range(100):
update() #更新权值
# 正样本
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()
图片:
单层感知器
import numpy as np
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)
print(i)#迭代次数
o = np.sign(np.dot(X ,W))#计算当前输出
if(o == Y).all():#如果实际输出等于期望输出,模型收敛,循环结束
print('Finished')
print('epochs' ,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()
# 单层感知器无法解决非线性的分类问题
图片:
异或问题
import numpy as np
import matplotlib.pyplot as plt
# 输入数据
X = np.array([[1 ,0 ,0] ,
[1 ,0 ,1] ,
[1 ,1 ,0] ,
[1 ,1 ,1]])
#标签
Y = np.array([[0 ,1 ,1 ,0]])
# 权值初始化,取值范围-1到1
# V代表输入层与隐藏层的权值,W代表隐藏层与输出层的权值
V = np.random.random((3 ,4))*2-1
W = np.random.random((4 ,1))*2-1
print(V)
print(W)
# 学习率设置
lr = 0.11
def sigmoid(x):
return 1/(1 + np.exp(-x))
def dsigmoid(x):
return x*(1-x)
def update():
global X ,Y ,W ,V ,lr
L1 = sigmoid(np.dot(X ,V))#隐藏层输出(4,4)
L2 = sigmoid(np.dot(L1 ,W))#输出层输出(4,1)
L2_delta = (Y.T - L2)*dsigmoid(L2)
L1_delta = L2_delta.dot(W.T)*dsigmoid(L1)
W_C = lr*L1.T.dot(L2_delta)
V_C = lr*X.T.dot(L1_delta)
W = W + W_C
V = V + V_C
for i in range(20000):
update()#更新权值
if i % 500 == 0:
L1 = sigmoid(np.dot(X ,V))#隐藏层输出(4,4)
L2 = sigmoid(np.dot(L1 ,W))#输出层输出(4,1)
print('Error:' ,np.mean(np.abs(Y.T-L2)))
L1 = sigmoid(np.dot(X ,V))#隐藏层输出(4,4)
L2 = sigmoid(np.dot(L1 ,W))#输出层输出(4,1)
print(L2)
线性神经网络解决异或
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]])
#标签
Y = np.array([-1 ,1 ,1 ,-1])
# 权值初始化,6个,取值范围-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) #purelin函数 y=x
W_C = lr * ((Y - o.T).dot(X)) / int(X.shape[0])
W = W + W_C
for _ in range(1000):
update() #更新权值
# 这里不能用以下方式判断收敛是因为假设当前输出值为-0.1 0.1 0.2 -0.2
# 会通过sign函数转化成-1 1 1 -1,看似与期望输出相等,但实际上差别很大
# o = np.sign(np.dot(X ,W.T))#计算当前输出
# if(o == Y.T).all():#如果实际输出等于期望输出,模型收敛,循环结束
# print('Finished')
# print('epochs' ,n)
# break
# 正样本
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)
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.scatter(x1 ,y1 ,c = 'b')
plt.scatter(x2 ,y2 ,c = 'y')
plt.show()
图片: