一、线性神经网络的引入
由于单层感知器不能解决线性不可分的问题(在上篇文章对线性可分做了解释),如异或问题,这时我们引入了新的结构:线性神经网络。
二、线性神经网络与单层感知机的区别
线性神经网络与单层感知器的结构相似,只是它们的激活函数不同,单层感知器的激活函数只能输出两种可能值(-1 或 1),而线性神经网络的输出可以是任何取值,其激活函数是线性函数 y = x。
三、线性神经网络的两类学习规则
3.1 LMS 学习规则
LMS 学习规则与单层感知器的学习规则非常类似,区别就在于单层感知器的激活函数的输出是 sign(WT X),而 LMS 的激活函数的输出就是 WT X 本身。
3.2 delta 学习规则
delta 学习规则是一种利用梯度下降法的一般性的学习规则,该规则也可以称为连续感知器学习规则。
注:E 的梯度就是 E 的导数,在求导过程中要注意 X 是常量,W 是变量。
因为使用线性神经网络,激活函数为 y = x,所以 f(X) 的导数是 1,所以式2.23 可化简为
E_C = -(dj - oj) X
(因为符号不好表示,所以用 E_C 来代替等式左边的符号)
梯度下降法
说明:函数在某一点的梯度即为该点的导数,如图所示,当点位于左半部分时,导数为负,而想要减小代价函数值,则必须往大增加 W,所以 W_C 应该为正值,即 -(梯度),右半部分相反,这就是下面这句话的意思。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OJfeUTbs-1583233772719)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1583231324039.png)]
四、代码实现异或
#%%
import numpy as np
import matplotlib.pyplot as plt
# 数据格式:[b = 1, x1, x2, x1 * x2, x1 * x1, x2 * x2]
X = np.array([
[1, 0, 0, 0, 0, 0],
[1, 0, 1, 0, 0, 1],
[1, 1, 0, 0, 1, 0],
[1, 1, 1, 1, 1, 1]
])
Y = np.array([-1, 1, 1, -1])
#权值
W = (np.random.random(6) - 0.5) * 2
#学习率
l_r = 0.12
O = 0
print(W)
#更新权值
def update():
global X, Y, W, n
n += 1
O = np.dot(X, W.T)
W_C = (l_r * np.dot(Y - O.T, X)) / X.shape[0]
W += W_C
# 画出曲线 w0 + w1*x1 + w2*x2 + w3*x1*x2 + w4*x1*x1 + w5*x2*x2 = 0
# x1 设置成 x,x2 设置成 y,其中 x 已知,所以该曲线是关于 y 的一元二次函数
def calculate(root, x):
a = W[5]
b = W[2] + W[3] * x
c = W[0] + W[1] * x + W[4] * x * x
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)
def draw():
# 正样本
x1 = [0, 1]
y1 = [1, 0]
# 负样本
x2 = [0, 1]
y2 = [0, 1]
# 画图
x_data = np.linspace(-1, 2)
plt.figure()
plt.plot(x_data, calculate(1, x_data), 'r')
plt.plot(x_data, calculate(2, x_data), 'r')
plt.plot(x1, y1, 'bo')
plt.plot(x2, y2, 'yo')
plt.show()
#%%
#分别画出计算 100 次,1000 次,100000 次的图
for _ in range(100):
update()
draw()
print("计算结果为:", np.dot(X, W.T))
for _ in range(1000):
update()
draw()
print("计算结果为:", np.dot(X, W.T))
for _ in range(100000):
update()
draw()
print("计算结果为:", np.dot(X, W.T))
运行结果: