独家连载 | 使用BP网络解决异或问题

4.7 使用BP网络解决异或问题

代码4-1:BP神经网络解决异或问题

import numpy as np
import matplotlib.pyplot as plt
# 输入数据
X = np.array([[0,0],[0,1], [1,0],[1,1]])
# 标签
T = np.array([[0],[1],[1],[0]])
# 定义一个2层的神经网络:2-10-1
# 输入层2个神经元,隐藏层10个神经元,输出层1个神经元
# 输入层到隐藏层的权值初始化,2行10列
W1 = np.random.random([2,10])
# 隐藏层到输出层的权值初始化,10行1列
W2 = np.random.random([10,1])
# 初始化偏置值,偏置值的初始化一般可以取0,或者一个比较小的常数,如0.1
# 隐藏层的10个神经元偏置
b1 = np.zeros([10])
# 输出层的1个神经元偏置
b2 = np.zeros([1])
# 学习率设置
lr = 0.1
# 定义训练周期数
epochs = 100001
# 定义测试周期数
test = 5000
# 定义sigmoid函数
def sigmoid(x):
    return 1/(1+np.exp(-x))
# 定义sigmoid函数导数
def dsigmoid(x):
    return x(1-x)
# 更新权值和偏置值
def update():
    global X,T,W1,W2,lr,b1,b2
    # 隐藏层输出
L1 = sigmoid(np.dot(X,W1) + b1)
    # 输出层输出
L2 = sigmoid(np.dot(L1,W2) + b2)
    # 根据公式4.41,求输出层的学习信号
delta_L2 = (T - L2)  dsigmoid(L2)
    # 根据公式4.42,求隐藏层的学习信号
delta_L1 = delta_L2.dot(W2.T)  dsigmoid(L1)
    # 根据公式4.44,求隐藏层到输出层的权值改变
    # 由于一次计算了多个样本,所以需要求平均
delta_W2 =lr  L1.T.dot(delta_L2) /X.shape[0]
# 根据公式4.45,求输入层到隐藏层的权值改变
# 由于一次计算了多个样本,所以需要求平均
delta_W1 =lr X.T.dot(delta_L1) / X.shape[0]
    # 更新权值
W2 =W2 + delta_W2
W1 =W1 + delta_W1
# 改变偏置值
# 由于一次计算了多个样本,所以需要求平均
b2 =b2 +lr np.mean(delta_L2, axis=0)
b1 =b1 +lr  np.mean(delta_L1, axis=0)
# 定义空list用于保存loss
loss = []
# 训练模型
for i in range(epochs):
    # 更新权值
    update()
    # 每训练5000次计算一次loss值
    if i %test == 0:
        # 隐藏层输出
L1 = sigmoid(np.dot(X,W1) + b1)
        # 输出层输出
L2 =sigmoid(np.dot(L1,W2) + b2)
        # 计算loss值
        print('epochs:',i,'loss:',np.mean(np.square(T - L2) / 2))
        # 保存loss值
        loss.append(np.mean(np.square(T - L2) / 2))
# 画图训练周期数与loss的关系图
plt.plot(range(0,epochs,test),loss)
plt.xlabel('epochs')
plt.ylabel('loss')
plt.show()
# 隐藏层输出
L1 = sigmoid(np.dot(X,W1) + b1)
# 输出层输出
L2 = sigmoid(np.dot(L1,W2) + b2)
print('output:')
print(L2)
# 因为最终的分类只有0和1,所以我们可以把
# 大于等于0.5的值归为1类,小于0.5的值归为0类
def predict(x):
    if x>=0.5:
        return 1
    else:
return  0
# map会根据提供的函数对指定序列做映射
# 相当于依次把L2中的值放到predict函数中计算
# 然后打印出结果
print ('predict:')
for  i in map(predict,L2):
    print(i)

程序的输出结果为:

epochs: 0 loss: 0.2382731940835196
epochs: 5000 loss: 0.1206923173399693
epochs: 10000 loss: 0.0790971946756123
epochs: 15000 loss: 0.02378338344093093
epochs: 20000 loss: 0.008377749771590743
epochs: 25000 loss: 0.004291050338268038
epochs: 30000 loss: 0.002694668764968099
epochs: 35000 loss: 0.0018982939821333231
epochs: 40000 loss: 0.0014365256397058071
epochs: 45000 loss: 0.001140826866565359
epochs: 50000 loss: 0.0009377943334308873
epochs: 55000 loss: 0.0007910315050028132
epochs: 60000 loss: 0.000680683460806228
epochs: 65000 loss: 0.0005950985467089836
epochs: 70000 loss: 0.0005270339320851203
epochs: 75000 loss: 0.00047177302525578296
epochs: 80000 loss: 0.0004261243077828677
epochs: 85000 loss: 0.00038785770517095713
epochs: 90000 loss: 0.0003553718177062329
epochs: 95000 loss: 0.0003274893656556488
epochs: 100000 loss: 0.00030332701795183955

output:
[[0.02462022]
 [0.97697496]
 [0.97534433]
[0.02612291]]
predict:
0
1
1
0

作者介绍

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qin_bf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值