BP神经网络求解异或算法

BP神经网络求解异或算法

一、BP神经网络

BP算法包括信号的前向传播和误差的反向传播两个过程。即计算误差输出时按从输入到输出的方向进行,而调整权值和阈值则从输出到输入的方向进行。
正向传播时,输入信号通过隐含层作用于输出节点,经过非线性变换,产生输出信号,若实际输出与期望输出不相符,则转入误差的反向传播过程。

误差反传是将输出误差通过隐含层向输入层逐层反传,并将误差分摊给各层所有单元,以从各层获得的误差信号作为调整各单元权值的依据。通过调整输入节点与隐层节点的联接强度和隐层节点与输出节点的联接强度以及阈值,使误差沿梯度方向下降,经过反复学习训练,确定与最小误差相对应的网络参数(权值和阈值),训练即告停止。此时经过训练的神经网络即能对类似样本的输入信息,自行处理输出误差最小的经过非线形转换的信息

下面以单隐藏层为例,进行输出值的公式推导,其结构示意图如下:
在这里插入图片描述
在实际实验过程中我们会依据预测输出值 o 1 o_1 o1与实际输出值的误差或者自定义学习率,对前面计算过程中的 W 11 W_{11} W11 W 21 W_{21} W21 V 11 V_{11} V11 V 12 V_{12} V12 V 21 V_{21} V21 以及 V 22 V_{22} V22进行新的值的计算。

二、激活函数

在神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数。引入激活函数是为了增加神经网络模型的非线性。没有激活函数的每层都相当于矩阵相乘。就算你叠加了若干层之后,无非还是个矩阵相乘
在这里插入图片描述
如图所示,如果没有激活函数 f f f的值就是 x 1 x_1 x1 x 2 x2 x2与相关系数矩阵的乘积之和,是线性的,对于非线性函数的预测不能很好地体现。
针对这种情况我们引入了激活函数,激活函数是非线性函数,常见的激活函数如下:
(1)Sigmoid函数
Sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线。在信息科学中,由于其单增以及反函数单增等性质,Sigmoid函数常被用作神经网络的阈值函数,将变量映射到0,1之间,公式如下:
f ( x ) = 1 1 + e − x f(x)= \frac{1}{1+e^{-x}} f(x)=1+ex1
在这里插入图片描述
(2)Tanh函数
Tanh是双曲函数中的一个,Tanh()为双曲正切。在数学中,双曲正切“Tanh”是由基本双曲函数双曲正弦和双曲余弦推导而来。公式如下:
f ( x ) = e x − e − x e x + e − x f(x)= \frac{e^x-e^{-x}}{e^x+e^{-x}} f(x)=ex+exexex
在这里插入图片描述
(3)ReLU函数
Relu激活函数(The Rectified Linear Unit),用于隐层神经元输出。公式如下:
f ( x ) = m a x ( 0 , x ) f(x)=max(0,x) f(x)=max(0,x)
在这里插入图片描述

三、异或求解

该方法中,我采用的RELU函数作为激活函数,程序代码如下:

import numpy as np 


def com(x, deriv = False):
    if(deriv == True):
        return x*(1-x)
    else:
        return 1/(1+np.exp(-x))

#输入数据
x = np.array([[0,0],[0,1],[1,0],[1,1]])

#输出数据
y = np.array([[0],[1],[1],[0]])

#定义学习率
#learning_rate = 1e-6

#卷积计算权重初始值随机化
w1 = 2*np.random.random((2,4))-1
w2 = 2*np.random.random((4,2))-1
w3 = 2*np.random.random((2,1))-1

for i in range(20000):
    #根据初始权重得到隐藏层数据
    h1 = com(np.dot(x,w1))
    #矩阵中小于0的数据为0,大于0的数据不改变
    h_relu = np.maximum(h1, 0)
    h2 = com(np.dot(h_relu,w2))
    h3 = com(np.dot(h2,w3))

    #误差
    h3_loss = y - h3
    h3_grad = h3_loss*com(h3,deriv = True)
    h2_loss = h3_grad.dot(w3.T)
    h2_grad = h2_loss*com(h2,deriv = True)
    h1_loss = h2_grad.dot(w2.T)
    h1_grad = h1_loss*com(h1,deriv = True)


    w3 += h2.T.dot(h3_grad)
    w2 += h1.T.dot(h2_grad)
    w1 += x.T.dot(h1_grad)

print("out after training")
print(h3)

得到程序运行结果如下:
在这里插入图片描述
由输出结果可知,预测结果比较符合实际。

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个简单的 Python 实现 BP 神经网络求解异或问题的例子: ```python import numpy as np # 定义 sigmoid 函数和它的导数 def sigmoid(x): return 1 / (1 + np.exp(-x)) def sigmoid_derivative(x): return x * (1 - x) # 构建神经网络 class NeuralNetwork: def __init__(self, x, y): self.input = x self.weights1 = np.random.rand(self.input.shape[1], 4) self.weights2 = np.random.rand(4, 1) self.y = y self.output = np.zeros(self.y.shape) def feedforward(self): self.layer1 = sigmoid(np.dot(self.input, self.weights1)) self.output = sigmoid(np.dot(self.layer1, self.weights2)) def backprop(self): # 应用链式法则计算输出层误差 d_weights2 = np.dot(self.layer1.T, (2*(self.y - self.output) * sigmoid_derivative(self.output))) # 应用链式法则计算隐藏层误差 d_weights1 = np.dot(self.input.T, (np.dot(2*(self.y - self.output) * sigmoid_derivative(self.output), self.weights2.T) * sigmoid_derivative(self.layer1))) # 更新权重 self.weights1 += d_weights1 self.weights2 += d_weights2 # 输入数据和标签 X = np.array([[0,0], [0,1], [1,0], [1,1]]) y = np.array([[0],[1],[1],[0]]) # 初始化神经网络 nn = NeuralNetwork(X,y) # 训练神经网络 for i in range(1500): nn.feedforward() nn.backprop() # 输出训练结果 print(nn.output) ``` 这个代码实现了一个具有一个隐藏层的 BP 神经网络,用于求解异或问题。在构建神经网络时,我们使用了 2 个权重矩阵:weights1 和 weights2,分别连接输入层和隐藏层、隐藏层和输出层。在训练神经网络时,我们使用了前向传播和反向传播算法。其中,前向传播用于计算神经网络的输出,反向传播用于更新权重矩阵以最小化误差。最终,我们得到了一个能够正确预测异或运算结果的神经网络
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值