3 线性神经网络

一、线性神经网络的引入

​ 由于单层感知器不能解决线性不可分的问题(在上篇文章对线性可分做了解释),如异或问题,这时我们引入了新的结构:线性神经网络。

二、线性神经网络与单层感知机的区别

​ 线性神经网络与单层感知器的结构相似,只是它们的激活函数不同,单层感知器的激活函数只能输出两种可能值(-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))
    

运行结果:

在这里插入图片描述

发布了42 篇原创文章 · 获赞 3 · 访问量 2071

猜你喜欢

转载自blog.csdn.net/stable_zl/article/details/104639029
今日推荐