栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

01.用Numpy手搓一个三层神经网络解决XoR分类问题

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

01.用Numpy手搓一个三层神经网络解决XoR分类问题

本文参考了以下几篇文章

1.BP神经网络算法 python实现 BP神经网络算法 python实现 - 人工智能 - 电子发烧友网

2.一个简单神经网络的代码实现一个简单神经网络的代码实现_神童i的博客-CSDN博客

3.深度学习基础之-5.1非线性分类-二分类深度学习基础之-5.1非线性分类-二分类 神经元解决异或问题 _Susan Wong-CSDN博客

本文主要描述解决XoR问题 以及简单的表格内容预测问题

二、两层神经网络实现线性分类问题 1. 采用算法预测下表结果 线性

Inputs

Output

0

0

1

0

1

1

1

0

1

0

1

1

0

1

1

1

给定已知表格 尝试输入前三列数据去预测第四列数值 其中行为样本。

Input为输入样本 Output为实际结果值

先叠加两层神经网络 采用sigmod函数对数据进行激活

sigmod函数如图所示  

        sigmoid函数可以将任何值都映射到位于0到1范围内的值 通过它可以将任何值映射到位于0-1的范围内 可以令我们的实数值转化为概率值。同时sigmod函数的求导值也是很好求得 导数值为 out * (1 - out )得到 十分高效的。

# 两层神经元
import numpy as np
# 激活函数 sigmod 将任何值变为0 - 1概率值
def sigmod(x, deriv False): # 求导True
 if True deriv:
 return x * (1 - x) # sigmod的导数形式
 return 1/(1 np.exp(-x))
# 训练数据 初始化为numpy矩阵 每行对应实例 每列代表输入节点
train_data np.array([
 [0,0,1],
 [0,1,1],
 [1,0,1],
 [1,1,1]])
y np.array([[0,0,1,1]]).T # 设计输出
np.random.seed(1) # 权重初始集分布都是完全一致的
weights np.random.random((3,1)) #权重矩阵w1
 #print(weights)
weights 2 * weights -1 # 随机数进行处理 类似正态分布 
 #print(weights)
for iter in range(10000): # 变化数据只有weight l1
 l0 train_data # 训练数据
 l1 sigmod(np.dot(l0,weights)) # 训练数据与三个随机权重相乘 激活 预测值
 loss y - l1 # 错误率
 print( loss ,loss)
# l1_delta 是一个变化率选项
 l1_delta loss * sigmod(l1, True) # 求导 - a * dw/dl1# 
 weights np.dot(l0.T, l1_delta) # 权重进行更新
 print( weights ,weights)
 print( n )
 print( times ,iter)
print( pre_l1 n ,l1)

运行10000次后结果如图所示 发现两层神经元可以逼近线性结果。

2. 修改表格为非线性后无法预测

Inputs

Output

0

0

1

0

1

1

1

1

1

0

1

1

0

1

1

0

我们对output数值进行修改后发现 预测的数据竟然是0.5 无法判断 原因是此类数据已经属于非线性无法用两层网络进行拟合。

# 两层神经元
import numpy as np
# 激活函数 sigmod 将任何值变为0 - 1概率值
def sigmod(x, deriv False): # 求导True
 if True deriv:
 return x * (1 - x) # sigmod的导数形式
 return 1/(1 np.exp(-x))
# 训练数据 初始化为numpy矩阵 每行对应实例 每列代表输入节点
train_data np.array([
 [0,0,1],
 [0,1,1],
 [1,0,1],
 [1,1,1]])
y np.array([[0,1,1,0]]).T # 设计输出
np.random.seed(1) # 权重初始集分布都是完全一致的
weights np.random.random((3,1)) #权重矩阵w1
 #print(weights)
weights 2 * weights -1 # 随机数进行处理 类似正态分布 
 #print(weights)
for iter in range(10000): # 变化数据只有weight l1
 l0 train_data # 训练数据
 l1 sigmod(np.dot(l0,weights)) # 训练数据与三个随机权重相乘 激活 预测值
 loss y - l1 # 错误率
 print( loss ,loss)
# l1_delta 是一个变化率选项
 l1_delta loss * sigmod(l1, True) # 求导 - a * dw/dl1# 
 weights np.dot(l0.T, l1_delta) # 权重进行更新
 print( weights ,weights)
 print( n )
 print( times ,iter)
print( pre_l1 n ,l1) 

解决方法也很简单 再加一层神经元 可以更近一步拟合出具体函数。

三、三层神经网络实现非线性分类问题 1. 采用算法预测下表结果 非线性

Inputs

Output

0

0

1

0

1

1

1

1

1

0

1

1

0

1

1

0

第二组数据无法预测是因为非线性 关系复杂一些 但多添加一层线性网络就能处理。

import numpy as np
# 第一步设定激活函数sigmod
def sigmod(x, deriv False): # 求导True
 if True deriv:
 return x * (1 - x) # sigmod的导数形式
 return 1/(1 np.exp(-x))
train_data np.array([
 [0,0,1],
 [0,1,1],
 [1,0,1],
 [1,1,1]])
y np.array([[0], [1], [1], [0]])
np.random.seed(1)
weights1 2 * np.random.random((3, 4)) - 1
weights2 2 * np.random.random((4, 1)) - 1
for cnt in range(1000000):
 l0 train_data # [4, 3] 第一层 输入层 l0为我们的训练数据
 l1 sigmod(np.dot(l0, weights1)) # [4, 4]
 l2 sigmod(np.dot(l1, weights2)) # [4, 1]
 l2_loss y - l2 # [4, 1]
 l2_delta l2_loss * sigmod(l2, True)
 l1_loss l2_delta.dot(weights2.T)
 l1_delta l1_loss * sigmod(l1, True)
 weights1 l0.T.dot(l1_delta)
 weights2 l1.T.dot(l2_delta)
 acc ((l2[0] l2[3]) ((1-l2[1]) (1-l2[2])))/4
 print( cnt ,cnt)
 print( acc ,acc)
print(l2)

 具体结果如上图所示

2. XoR问题的分类讨论

Inputs

Inputs

Output

0

0

0

1

1

0

1

0

1

0

1

1

        异或 英文为exclusive OR 缩写成eor

异或 eor 是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕” 计算机符号为“eor”。其运算法则为 a⊕b (¬a ∧ b) ∨ (a ∧¬b)

        如果a、b两个值不相同 则异或结果为1。如果a、b两个值相同 异或结果为0。

分类的曲线可以理解为下图所示的非线性函数。

编写代码时要注意矩阵对齐 因为XoR分类与之前的表格分类列数上变化一小部分。

import numpy as np
# 第一步设定激活函数sigmod
def sigmod(x, deriv False): # 求导True
 if True deriv:
 return x * (1 - x) # sigmod的导数形式
 return 1/(1 np.exp(-x))
train_data np.array([[0, 0],
 [0, 1],
 [1, 0],
 [1, 1]]) # 与之前相比 输入数据少了一列 预测起来更简单
y np.array([[0], [1], [1], [0]]) # y为预测值
np.random.seed(1) # 固定随机种子
weights1 2 * np.random.random((2, 4)) - 1 # 随机分布w权重
weights2 2 * np.random.random((4, 1)) - 1
for cnt in range(1000000):
 l0 train_data # [4, 2] 第一层 输入层 l0为我们的训练数据
 l1 sigmod(np.dot(l0, weights1)) # [4, 4] 
 l2 sigmod(np.dot(l1, weights2)) # [4, 1]
 l2_loss y - l2 # [4, 1]
 l2_delta l2_loss * sigmod(l2, True) # 每次权重要变化的大小
 l1_loss l2_delta.dot(weights2.T)
 l1_delta l1_loss * sigmod(l1, True)
 weights1 l0.T.dot(l1_delta) # 权重进行更新
 weights2 l1.T.dot(l2_delta)
 acc ((l2[0] l2[3]) ((1-l2[1]) (1-l2[2])))/4 # 预测精准度评定
 print( cnt ,cnt) # 计数
 print( acc ,acc) # 精度
print(l2)
3. 拓展讨论

        下一步选择完成4层的神经网络

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/268040.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号