【神经网络】1:单层感知器解决异或问题
2018-01-11 11:08
260 查看
前言:写完上一篇《KNN算法实现手写数字识别》到现在已经过去了十天,2018年伊始几天同学同事都是各种浪,自己坚持学习实在是痛苦啊!
不悲不气,闲话不多说了,开始自己神经网络的学习旅程吧
–—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-——-—-—-–
–—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-——-—-—-–
1. 本神经元接收来自N个外界(或其他神经元)的输入信号,
2. 这些输入信号通过带权重的连接进行传递给本神经元;
3. 本神经元接收到的总输入将与本神经元的阈值进行比较;
4. 比较后,通过“激活函数”处理,产生输出
这篇单层感知器的实现具体是为了研究:已知标签的情况下,平面上的二分类问题
–—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-——-—-—-–
这里我用到的外界输入是4个值,相当于上图中有4个输入支,但是这4个输入支中,后两个相当于每一次输入的Xi=[1,1,xi,yi]中,可以确定平面上的一个点;前两个相当于偏置值,也可以说与阈值的意义相同。实验中一共输入了5组值,每组值对应的正负标签由Y存储,我们需要做的就是找到一条直线,将正负值区域划分开。
随机生成权重,且要求权重范围在(-1,1),权重的个数与输入支个数相同
注:手写说明斜率与截距怎么求得,哈哈
源代码附上:
效果展示:
用多个线性函数对区域进行划分,然后再对每个神经元的输出做出逻辑运算。
对神经元添加非线性项输入,使等效的输入维度变大:我们的输入还只是x1,x2,但是我们添加x1^2, x1*x2, x2^2项后,就由以前的两项可以生成后三项,而且这五项不再是线性的了
方法2的代码如下:
效果展示:
不悲不气,闲话不多说了,开始自己神经网络的学习旅程吧
–—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-——-—-—-–
–—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-——-—-—-–
第一部分:单层感知器工作原理
感知器的原型是——神经元模型。是在1943年,由McCulloch 和 Pitts提出,所以也被叫做“M-P神经元模型”。这个模型的工作原理可由下图展示:1. 本神经元接收来自N个外界(或其他神经元)的输入信号,
2. 这些输入信号通过带权重的连接进行传递给本神经元;
3. 本神经元接收到的总输入将与本神经元的阈值进行比较;
4. 比较后,通过“激活函数”处理,产生输出
第二部分:单层感知器部分说明
–—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-——-—-—-–这篇单层感知器的实现具体是为了研究:已知标签的情况下,平面上的二分类问题
–—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-——-—-—-–
1、输入数据集与标签集说明
# 输入数据 X = np.array([[1,1,2,3], [1,1,4,5], [1,1,1,1], [1,1,5,3], [1,1,0,1]]) # 标签 Y = np.array([1,1,-1,1,-1])
这里我用到的外界输入是4个值,相当于上图中有4个输入支,但是这4个输入支中,后两个相当于每一次输入的Xi=[1,1,xi,yi]中,可以确定平面上的一个点;前两个相当于偏置值,也可以说与阈值的意义相同。实验中一共输入了5组值,每组值对应的正负标签由Y存储,我们需要做的就是找到一条直线,将正负值区域划分开。
2、权重的初始化
# 权重初始化,取值范围-1到1 W = (np.random.random(X.shape[1])-0.5)*2 print('初始化权值:',W)
随机生成权重,且要求权重范围在(-1,1),权重的个数与输入支个数相同
3、更新权重函数
实现思路:当随机生成的权重W不能将正负值区域划分开来,就要根据当前输出集和原有标签集差值的大小,乘以输入集Xi,再乘以学习率lr,得到改变权重;改变权重加上旧权重,就得到新权重#更新权值函数 def get_update(): global X,Y,W,lr,n n += 1 #新输出:X与W的转置相乘,得到的结果再由阶跃函数处理,得到新输出 new_output = np.sign(np.dot(X,W.T)) #调整权重: 新权重 = 旧权重 + 改变权重 new_W = W + lr*((Y-new_output.T).dot(X))/int(X.shape[0]) W = new_W
4、展示函数:求分割线,并画图展示
def get_show(): # 所有样本的坐标 all_x = X[:, 2] all_y = X[:, 3] # 额外注释标签为-1的负样本的坐标 all_negative_x = [1, 0] all_negative_y = [1, 1] # 计算分界线斜率与截距 k = -W[2] / W[3] b = -(W[0] + W[1])/ W[3] print('斜率 k=', k) print('截距 b=', b) print('分割线函数:y = ', k,'x +(', b, ')') xdata = np.linspace(0, 5) plt.figure() plt.plot(xdata,xdata*k+b,'r') plt.plot(all_x, all_y,'bo') plt.plot(all_negative_x, all_negative_y, 'yo') plt.show()
注:手写说明斜率与截距怎么求得,哈哈
第三部分:单层感知器Python实现
注:由于每次随机生成的初始权重不同,导致每次运行迭代次数不同,求得的分割线也不同,当数据集很大时候,分割线也会越来越精准源代码附上:
# -*- coding:utf-8 -*-
# -*- author:z
4000
zZ_CMing
# -*- 2018/01/11;10:05
# -*- python3.5
import numpy as np
import matplotlib.pyplot as plt
n = 0 #迭代次数
lr = 0.11 #学习速率
# 输入数据 X = np.array([[1,1,2,3], [1,1,4,5], [1,1,1,1], [1,1,5,3], [1,1,0,1]]) # 标签 Y = np.array([1,1,-1,1,-1])
# 权重初始化,取值范围-1到1 W = (np.random.random(X.shape[1])-0.5)*2 print('初始化权值:',W)
def get_show():
# 所有样本的坐标
all_x = X[:, 2]
all_y = X[:, 3]
# 额外注释标签为-1的负样本的坐标
all_negative_x = [1, 0]
all_negative_y = [1, 1]
# 计算分界线斜率与截距
k = -W[2] / W[3]
b = -(W[0] +W[1])/ W[3]
print('斜率 k=', k)
print('截距 b=', b)
print('分割线函数:y = ', k,'x +(', b, ')')
xdata = np.linspace(0, 5)
plt.figure()
plt.plot(xdata,xdata*k+b,'r')
plt.plot(all_x, all_y,'bo')
plt.plot(all_negative_x, all_negative_y, 'yo')
plt.show()
#更新权值函数 def get_update(): global X,Y,W,lr,n n += 1 #新输出:X与W的转置相乘,得到的结果再由阶跃函数处理,得到新输出 new_output = np.sign(np.dot(X,W.T)) #调整权重: 新权重 = 旧权重 + 改变权重 new_W = W + lr*((Y-new_output.T).dot(X))/int(X.shape[0]) W = new_W
def main():
for _ in range(100):
get_update()
print('第',n,'次改变后的权重:',W)
new_output = np.sign(np.dot(X, W.T))
if (new_output == Y.T).all():
print("迭代次数:", n)
break
get_show()
if __name__ == "__main__":
main()
效果展示:
第四部分:感知器解决异或问题
感知器解决异或问题有两种方式:用多个线性函数对区域进行划分,然后再对每个神经元的输出做出逻辑运算。
对神经元添加非线性项输入,使等效的输入维度变大:我们的输入还只是x1,x2,但是我们添加x1^2, x1*x2, x2^2项后,就由以前的两项可以生成后三项,而且这五项不再是线性的了
方法2的代码如下:
# -*- coding:utf-8 -*-
# -*- author:zzZ_CMing
# -*- 2018/01/11;16:30
# -*- python3.5
'''
异或问题的解决方式有:增加非线性项:
输入x1,x2;
增加x1^2,x1*x2,x2^2
'''
import numpy as np
import matplotlib.pyplot as plt
n = 0 #迭代次数
lr = 0.11 #学习速率
#输入数据分别:偏置值,x1,x2,x1^2,x1*x2,x2^2
X = np.array([[1,0,0,0,0,0],
[1,0,1,0,0,1],
[1,1,0,1,0,0],
[1,1,1,1,1,1]])
#标签
Y = np.array([-1,1,1,-1])
# 权重初始化,取值范围-1到1 W = (np.random.random(X.shape[1])-0.5)*2 print('初始化权值:',W)
def get_show():
# 正样本
x1 = [0, 1]
y1 = [1, 0]
# 负样本
x2 = [0,1]
y2 = [0,1]
xdata = np.linspace(-1, 2)
plt.figure()
plt.plot(xdata, get_line(xdata,1), 'r')
plt.plot(xdata, get_line(xdata,2), 'r')
plt.plot(x1, y1, 'bo')
plt.plot(x2, y2, 'yo')
plt.show()
def get_line(x,root):
a = W[5]
b = W[2] + x*W[4]
c = W[0] + x*W[1] + x*x*W[3]
if root == 1:
return (-b+np.sqrt(b*b-4*a*c))/(2*a)
if root == 2:
return (-b-np.sqrt(b*b-4*a*c))/(2*a)
#更新权值函数
def get_update():
global X,Y,W,lr,n
n += 1
#新输出:X与W的转置相乘,得到的结果再由阶跃函数处理,得到新输出
new_output = np.dot(X,W.T)
#调整权重: 新权重 = 旧权重 + 改变权重
new_W = W + lr*((Y-new_output.T).dot(X))/int(X.shape[0])
W = new_W
def main():
for _ in range(10000):
get_update()
get_show()
last_output = np.dot(X,W.T)
print('最后逼近值:',last_output)
if __name__ == "__main__":
main()
效果展示:
相关文章推荐
- 机器学习+周志华+第五章习题+解决异或问题的单层RBF神经网络
- 【神经网络】BP算法解决XOR异或问题MATLAB版
- 线性神经网络(解决异或问题
- 【神经网络】3:BP神经网络解决异或问题
- 机器学习/深度学习测试题(二)—— 单层线性神经网络求解异或问题
- Tricks(四十)—— 神经网络解决与(或)及异或问题
- 神经网络解决分类问题步骤
- 线性神经网络处理异或问题
- 神经网络学习之单层感知器
- 【神经网络与深度学习】caffe静态链接库“Unknown layer type: Convolution (known types: )”和“ 磁盘空间不足”问题的解决办法
- TensorFlow训练神经网络解决二分类问题
- 两层感知器网络实现异或问题
- 神经网络,如何解决非线性问题
- 单层感知器神经网络
- 韩国庆尚大学jinju的神经网络解决XOR问题
- 【深度学习】神经网络异或问题
- 神经网络学习笔记(十二):异或问题
- 文本分类算法之--单层感知器的神经网络
- Tensorflow实例:神经网络解决二分类问题
- 深度学习与神经网络学习与遇到的问题及解决(第一章)