当前位置:   article > 正文

人工神经网络——BP算法_bp神经网络算法

bp神经网络算法

人工神经网络介绍

人工神经网络(Artificial Neural Network,简称ANN)是一种模拟生物神经系统功能的计算模型。它是由一系列相互连接的节点(神经元)组成的,每个节点都能接收输入、处理信息并产生输出。这些神经元之间的连接权重可以通过学习来逐步调整,从而使得神经网络能够自动从输入数据中学习和识别模式,进而完成各种任务,例如图像识别、语音识别、自然语言处理等。

如图是一个简单的神经元模型——M-P神经元模型

一个典型的人工神经网

络通常包含以下几个主要组成部分:

1. 输入层(Input Layer):接收原始的输入数据,并将其传递给下一层进行处理。

2. 隐藏层(Hidden Layers):在输入层和输出层之间有一到多个隐藏层。这些隐藏层包含大量的神经元,负责对输入数据进行特征提取和转换。

3. 输出层(Output Layer):最后一层输出神经元,将最终处理后的结果呈现给用户或作为其他系统的输入。

4. 权重(Weights):连接神经元之间的连接都有一个权重,用于调整输入信号的重要性。这些权重是模型训练的关键,通过训练过程来逐步调整以达到最优化的效果。

5. 激活函数(Activation Function):激活函数负责在神经元中引入非线性特性,使得神经网络能够学习复杂的非线性关系。常见的激活函数包括Sigmoid、ReLU、Tanh等。

 

神经网络的训练过程通常采用反向传播算法(Backpropagation),它通过比较网络输出和实际标签之间的差异来计算损失函数,并根据损失函数的梯度逐步更新连接权重,以使得网络的输出逐渐接近目标结果。

人工神经网络之所以在各种任务中表现出色,是因为它们能够自动学习数据中的特征和模式,无需手动设计特征提取器。这种自动化的特征学习使得神经网络在复杂问题上具有出色的泛化能力,即能够对未见过的数据进行准确的预测和分类。但也正因为其复杂性,神经网络的设计和训练需要大量的数据和计算资源。近年来,随着计算硬件的发展和算法的优化,神经网络在人工智能领域取得了许多重大的突破和应用。

BP算法

BP算法,全称为反向传播算法(Backpropagation),是训练人工神经网络(Artificial Neural Network,ANN)的一种有效且广泛应用的方法。它是一种监督学习算法,用于根据输入数据和对应的目标输出数据,调整神经网络的权重,使得网络能够对输入数据做出正确的预测。

BP算法的基本思想是通过计算网络输出与真实目标之间的误差,并将误差反向传播到网络中的每个神经元,以便调整各层之间的连接权重,从而降低误差,提高网络的预测能力。该算法主要分为两个阶段:前向传播和反向传播。

下面是BP算法的主要步骤:

1. 初始化:随机初始化神经网络中的连接权重。

2. 前向传播(Forward Propagation):将输入数据送入网络的输入层,通过连接权重和激活函数,逐层计算各个神经元的输出,直至得到输出层的输出。

3. 计算误差:将输出层的预测结果与真实的目标输出进行比较,计算网络在当前权重下的误差。

4. 反向传播(Backward Propagation):根据误差,从输出层开始,按照反向顺序逐层计算每个神经元的梯度。梯度表示误差随着权重的变化而变化的速率。这一步是BP算法的核心,通过链式法则计算梯度,并将误差从输出层反向传播到隐藏层和输入层。

5. 权重更新:根据梯度和学习率(一个调整步长的参数),更新连接权重,使误差减小。学习率的选择对于训练的收敛和效果都有重要影响。

6. 重复训练:重复执行前向传播、误差计算、反向传播和权重更新,直到网络的预测结果收敛或达到预定的训练迭代次数。

BP算法的优点是它能够自动学习复杂的非线性映射关系,并且在训练充分的情况下,具有很好的泛化能力。然而,它也存在一些问题,如容易陷入局部最优解、需要大量的训练数据和计算资源等。为了克服这些问题,人们发展了许多改进的BP算法和基于梯度下降的优化方法。

梯度下降

前面都是废话,此处开始才是精华

我们定义f(x)为激活函数,x为输入值,b为隐藏层的输出值,y为输出层的输出值,y_{k}表示实际输出值,v为输入层到隐藏层的权重,w为隐藏层到输出层的权重,输出层阈值定义为\theta,隐藏层定义为\gamma

(绝大多数我们用偏置而不是阈值,在此用阈值能更好理解和学习)

由数学知识可知,

输出层到隐藏层:

误差:                ​​​​​​​      e=(y-y_{k})f{}'(y)

        ​​​​​​​        ​​​​​​​        ​​​​​​​        \Delta w= \eta eb

                                \Delta \theta =\eta e

隐藏层到输入层

误差:                      e_{h}=w(y-y_{k})f{}'(y)f{}'(b)=wef{}'(b)

                                \Delta v=\eta e_{h}x

                                \Delta \gamma =\eta e_{h}

迭代更新

                                w=w+\Delta w

                                v=v+\Delta v

                                \theta =\theta -\Delta \theta

                                \gamma =\gamma -\Delta \gamma

推导过程不做展示

其实了解这些便可以了

代码展示

  1. import numpy as np
  2. class BackPropagation:
  3. # 初始化各层数量
  4. def __init__(self, input_n, hidden_n, output_n):
  5. self.input_n = input_n
  6. self.hidden_n = hidden_n
  7. self.output_n = output_n
  8. # 随机初始化权重和阈值
  9. self.i_h_weight = np.random.rand(self.input_n, self.hidden_n)
  10. self.h_o_weight = np.random.rand(self.hidden_n, self.output_n)
  11. self.h_threshold = np.random.rand(1, self.hidden_n)
  12. self.o_threshold = np.random.rand(1, self.output_n)
  13. # 激活函数sigmoid function
  14. def sigmoid(self, x):
  15. return 1 / (1 + np.exp(-x))
  16. # sigmiod函数求导
  17. def sigmoid_derivative(self, x):
  18. return x * (1 - x)
  19. # 向前传播forward propagation
  20. def forward_propagation(self, data_train):
  21. # 输入层到隐藏层
  22. hiddens_input = np.dot(data_train, self.i_h_weight) - self.h_threshold
  23. hiddens_output = self.sigmoid(hiddens_input)
  24. # 隐藏层到输出层
  25. outputs_input = np.dot(hiddens_output, self.h_o_weight) - self.o_threshold
  26. outputs_output = self.sigmoid(outputs_input)
  27. return hiddens_output, outputs_output
  28. # 向后传播back propagation
  29. def backpropagation(self, hiddens_output, outputs_output, data_train, data_labels, learning_rate):
  30. # 计算输出层的误差
  31. output_error = data_labels - outputs_output
  32. output_delta = output_error * self.sigmoid_derivative(outputs_output)
  33. # 计算隐藏层的误差
  34. hidden_error = output_delta.dot(self.h_o_weight.T)
  35. hidden_delta = hidden_error * self.sigmoid_derivative(hiddens_output)
  36. # 更新隐藏层到输出层的权重和阈值
  37. self.h_o_weight += hiddens_output.T.dot(output_delta) * learning_rate
  38. self.o_threshold -= np.sum(output_delta, axis=0, keepdims=True) * learning_rate
  39. # 更新输入层到隐藏层的权重和阈值
  40. self.i_h_weight += np.dot(data_train.T, hidden_delta) * learning_rate
  41. self.h_threshold -= np.sum(hidden_delta, axis=0, keepdims=True) * learning_rate
  42. def fit(self, data_train, data_labels, epochs=10, learning_rate=0.01):
  43. for epoch in range(epochs):
  44. hiddens_output, outputs_output = self.forward_propagation(data_train)
  45. self.backpropagation(hiddens_output, outputs_output, data_train, data_labels, learning_rate)
  46. _, output = self.forward_propagation(data_train)
  47. return output

用个及其简单的数据做展示

  1. epochs = 5000
  2. learning_rate = 0.1
  3. data_train = np.array([[0, 0],
  4. [0, 1],
  5. [1, 0],
  6. [1, 1]])
  7. data_labels = np.array([[0],
  8. [1],
  9. [1],
  10. [0]])
  11. labels = bp.fit(data_train, data_labels, epochs=epochs, learning_rate=learning_rate)
  12. print(labels)

结果展示

 可以调整迭代次数,使结果更准确

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/100016
推荐阅读
相关标签
  

闽ICP备14008679号