手写BP神经网络(简答易懂)
1. 经典的BP神经网络通常由三层组成:输入层、隐含层与输出层。通常输入层神经元的个数与特征数相关,输出层的个数与类别数相同, 隐含层的层数与神经元数均可以自定义。
·
一、基础
1. 经典的BP神经网络通常由三层组成:输入层、隐含层与输出层。通常输入层神经元的个数与特征数相关,输出层的个数与类别数相同, 隐含层的层数与神经元数均可以自定义。

2. 每个神经元代表对数据的一次处理:

二、代码
2.1 说明


2.2 源代码
import numpy as np
np.random.seed(1) # 随机种子,使得每次随机产生的weight都是一样的
# 输入层到隐藏层的权重 范围是[-1,1] 表示3个输入,4个神经元
w1 = 2 * np.random.random((3, 4)) - 1
# 隐藏层到输出层的权重 范围是[-1,1] 表示4个神经元,1个输出
w2 = 2 * np.random.random((4, 1)) - 1
# sigmoid激活函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# sigmoid激活函数的导数
def derivative(x):
return sigmoid(x) * (1 - sigmoid(x))
# 前向传播,根据输入值以及当前权重得每一层的输出
def fp(x):
z1 = np.dot(x, w1) # 汇聚第一层的输入
l1 = sigmoid(z1) # 经过第一层激活函数
z2 = np.dot(l1, w2) # 汇聚第二层的输入
l2 = sigmoid(z2) # 经过第二层激活函数
return l1, l2
# 反向传播,根据输入以及预测的值,计算增量,以便于更新权重
# l1,l2指第一层和第二层神经网络输出
def bp(y, x, l1, l2):
l2_error = l2 - y # 实际上是MSE对第二层神经元输出的导数
l2_slope = l2 * (1 - l2) # 实际上是sigmoid函数的输出对输入的导数
l2_delta = np.dot(l1.T, l2_error * l2_slope)
l1_error = np.dot(l2_error * l2_slope, w2.T) # 实际上是MSE对第一层神经元输出的导数
l1_slope = l1 * (1 - l1)
l1_delta = np.dot(x.T, l1_error * l1_slope)
return l1_delta, l2_delta
def main():
global w1
global w2
x = np.array([[0, 0, 1],
[0, 1, 1],
[1, 0, 1],
[1, 1, 1],
[0, 0, 0],
[0, 1, 0],
[1, 0, 0],
[1, 1, 0]])
# y转置成列向量
y = np.array([[0, 1, 1, 0, 0, 1, 1, 0]]).T
learning_rate = 20
# 训练网络
for it in range(1000):
l1, l2 = fp(x) # 前向传播,得到第一层和第二层的输出
l1_delta, l2_delta = bp(y, x, l1, l2) # 反向传播,得到增量,用于更新权重
w2 -= learning_rate * l2_delta
w1 -= learning_rate * l1_delta
print(fp([[1, 0, 0]])[1])
print(fp([[0, 0, 0]])[1])
if __name__ == '__main__':
main()
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)