感知机与、或、 非门的训练

当我写到这个标题的时候感觉超级激动,因为一直以为那是一种被束之高阁的技术,哈哈;但是当我读到这一章的时候,感觉还可以。下面介绍一些,相关的概念和术语;

  • 阈(yu)值[threshold]:
    就是一个限制,如果值超过threshold 神经元就会兴奋,也就是输出正样本1
  • sigmoid函数
    激活函数,将实数域的取值压缩到(0-1)
  • M-P神经元
    在M-P神经元模型中,神经元接收来自n个其他神经元传递过来的输入信号,再将接收到的输入信号按照某种权重叠加起来,叠加起来的刺激强度S可用公式 S = ∑ i = 1 n w i x i S=\sum_{i=1}^{n}w_{i}x_{i} S=i=1nwixi来表示。得到S后,好要与当前神经元的阈值进行比较,然后通过激活函数向外表达输出。
  • 感知机
    有两层神经元组成的,输入层收到外界输入信号后传递给输出层,输出层是M-P神经元,亦称阈值逻辑单元。如下图所示。有没有感觉,感知机很像线性分类器。
    在这里插入图片描述

但是,这种双层的感知机,只能进行线性可分的样本,对于线性不可分的数据集 比如说,”异或“,就无法用单个感知机实现;但是,我们可以用两个感知机实现异或。
害,口说无凭,下面从单层感知机学习与门开始实现

分析下问题 :我们有两个输入,然后会有一个输出true or false
有上面的M-p模型可以得知,我们会有一个模型形如:
f ( x 1 , x 2 ) = w 1 ∗ x 1 + w 2 ∗ x 2 + b f(x_1,x_2)=w_1*x_1+w_2*x_2 +b f(x1,x2)=w1x1+w2x2+b
是不是像极了线性分类器,其实 感知机就是一个线性分类器。
我们也可以把x和w写成矩阵的形式
f ( x 1 , x 2 ) = [ x 1 , x 2 ] [ w 1 , w 2 ] T + b f(x_1,x_2)=[x_1 ,x_2] [w_1,w_2]^T +b f(x1,x2)=[x1,x2][w1,w2]T+b
但是,这里的正样本和负样本,是用(1,-1)表示的。之前习惯用1,0 表示。
下面我们写一下数据集,因为与门只有四种可能

data_set=[[1,1,1],
		  [1,0,-1],
		  [0,1,-1],
  		  [0,0,-1]]

然后,我们初始化一下w矩阵和系数b

w= [0,0]
b=0

下面进行一次模拟运算
f ( 1 , 1 ) = [ 1 , 1 ] [ 0 , 0 ] T + 0 = 0 f(1,1)=[1 ,1] [0,0]^T +0=0 f(1,1)=[1,1][0,0]T+0=0
我们把0 规定为负样本,而 1,1 应该得到的是正样本;此时,这个系统并没有训练完成,我们要对参数进行修正;修正方案为:
{ w = w + η ∗ y i ∗ x i b = b + η ∗ y i \begin{cases} w=w+\eta *y_i*x_i \\ b= b+\eta*y_i \end{cases} {w=w+ηyixib=b+ηyi
如果觉得有点看不懂的话,其实可以看这个,设我们预测的结果为Y:
{ w = w + η ∗ ( Y ) ∗ x i b = b + η ∗ ( y i − Y ) \begin{cases} w=w+\eta *(Y)*x_i \\ b= b+\eta*(y_i-Y) \end{cases} {w=w+η(Y)xib=b+η(yiY)
用二者的插值来修正,就容易理解了。但是转念一想,Y和 y i y_i yi的取值只能使{-1,1}两个 ,如果他们不相同,也只会差一个2 ,无非就是正负而已
如果预测值是-1 而真实值 是 1 那么这次的差值为 1-(-1)=2
如果预测值是1 而真实值 是 -1 那么这次的差值为 -1-1=-2
也就是说,我们的差值和真实值是同号的,只是差了一个系数。所以我们完全可以用真实值来代替这个差值,只不过是收敛的时间慢一点。
【我有几个疑问】

  • 只正w不就行了,为什么一定要b一起修正?
  • w和b修正公式的意义是什么?
  • 为什么公式要设计成这个样子?

这些疑问都还没有解决,我们要知其然并且知其所以然;
先插个眼,哈哈
下面先说说怎么实现的吧!
肯定先开始写最核心的学习部分了

for k in range(20):# 这种简单的模型20次肯定收敛了
    for i in range(data.shape[0]):# 这只是数据集一次循环,我们要循环多次
        if y[i]*sign(np.dot(x[i],w)+b)<=0 :
            w=w+eta*(y[i]-sign(np.dot(x[i],w)+b))*x[i]
            b=b+eta*(y[i]-sign(np.dot(x[i],w)+b))

上面的判断条件很巧妙,如果是正值,且预测准确,那肯定乘积大于零,同理可得同负也是如此,因此只有小于零的时候,两者异号,才会判断出错。
害,其实没啥东西,就是把数据集过一遍,把有问题的数据修正一下,这个有点像梯度下降里面的随机梯度下降法,就是每一个数据进行修正,与之对应的还有batch 和mini-batch.
下面只需要从数据集中提取出,属性列和标签列就可以了

import numpy as  np
data_set=[[1,1,1],
          [1,0,-1],
          [0,1,-1],
          [0,0,-1]]
data= np.array(data_set)
# np 有一个花式索引很好用
#逗号前,表示取几行,逗号后,表示取第几列。清晰明了
x=data[:,:-1] # 取全部行  除去最后一列
y=data[:,-1:]# 取全部行的最后一列

现在都准备好了,就差一个测试函数了,就是将两个属性带入到模型中,求出结果

def Test(x1,x2):
    x=np.array([x1,x2])
    return sign(np.dot(x,w)+b)
#测试
print("1 and 1=",Test(1,1))
print("1 and 0=",Test(1,0))
print("0 and 1=",Test(0,1))
print("0 and 0=",Test(0,0))
#输出

1 and 1= 1
1 and 0= -1
0 and 1= -1
0 and 0= -1

其中或门和非门,只要相应的改动数据集就可以实现了,这里不做赘述。
源代码

# 单个感知机 实现 与或非
import matplotlib.pyplot as plt
import numpy as  np
data_set=[[1,1,1],
          [1,0,-1],
          [0,1,-1],
          [0,0,-1]]
data= np.array(data_set)
x=data[:,:-1]
y=data[:,-1:]
w=np.array([1 for i in range(data.shape[1]-1)])
b=1 #偏置
eta=1#  学习率
def sign(p):
    return 1 if p>0 else -1
for j in range(5):
    for i in range(data.shape[0]):
        if y[i]*sign(np.dot(x[i],w)+b)<=0 :
            w=w+eta*(y[i]-sign(np.dot(x[i],w)+b))*x[i]
            b=b+eta*(y[i]-sign(np.dot(x[i],w)+b))


def Test(x1,x2):
    x=np.array([x1,x2])
    return sign(np.dot(x,w)+b)
print("1 and 1=",Test(1,1))
print("1 and 0=",Test(1,0))
print("0 and 1=",Test(0,1))
print("0 and 0=",Test(0,0))

下面我们挑战一下高难度的吧,两层感知机,叠加在一起,来实现线性不可分的异或问题。
在这里插入图片描述周老师的这个图,已经给了很大帮助了,我们训练两个感知机,决策边界一上一下,这样正好将数据完整划分。我们需要三个感知机,所以一共有3*3=9 个参数
也许我们可以将他们放入到一个矩阵中形如

[
[w1,w2,b1],
 [w3,w4,b2],
 [w5,w6,b3],
]

当然也可能有更好的办法,这里只是思考的一部分。那这三个感知机,我们是一起训练呢,还是一个一个训练呢? 肯定是一起训练,可是9个参数 ,可以组成无穷种变化,又该如何下手呢?或者说,如果输出结果不准确,那这三个神经元,主要修正哪一个呢,有权重吗,这些都是问题。研究就是提出问题解决问题的过程,有了这些问题,下面我们去找找资料看看人家是怎么解决的;

看了花书的前馈神经网络,看了B站shuhuai008的白板推到系列(二十三)。得出结论,自己无意间触发了一个大boss,下面我准备单独写一篇文章,记录我攻克这个大boss的过程。

  • 8
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值