感知机原理解析与python实现

       讲完线性回归本来应该乘热打铁讲讲逻辑回归的,但是我觉得应该先讲讲感知机的原理,它不仅可以帮助理解分类和回归,也能帮助理解逻辑回归。

引言

       上一篇博客讲解了线性回归,我们知道线性模型可以表示为y=wx+b,由于线性模型的输出y值是连续的数值类型,所以它用来做回归分析,那么线性模型能否用来做分类任务呢?当然可以!只需要将线性模型的输出y离散化就可以了。

感知机原理

        感知机就实现了用线性模型来完成分类任务,那么它是怎么实现这个功能的?通过一个sign()函数将线性模型的输出y进行处理,使得最终的输出变成[1,-1],1和-1各代表一个类别,这样就相当于一个二分类的模型了

  • 数学模型

       感知机的数学模型也比较简单,可以表示为如下形式

                                                                  

注:sign()函数也可以理解为神经网络中的激活函数

  • 感知机思想

       我们知道感知机是为了实现分类任务而设计的,那么它是如何进行二分类任务的?它在特征空间(特征向量x的集合)寻找一个将正负样本完全正确分离的超平面,超平面的两侧即为分类的两个类别。下图直观的表现了感知机的思想

                                                                        

       超平面是指在n维空间中的一个n-1维平面,例如三维空间的超平面是一个二维平面,二维空间的超平面是一条直线。为什么是平面而不是曲面呢?因为在进入激活函数之前的模型是线性模型。

模型求解

        感知机的模型求解就是找到一个超平面将两个类别分离开,那么我们期望错误分类的样本到超平面的距离之和最小,最好小到为0,那么就没有错误分类的样本点了。

  • 点到直线距离

       错分样本点到超平面的距离可以根据数学中点到平面距离公式求得,如下

                                                              d=\frac{wx+b}{\sqrt{w^{2}+1}}

       简化后的公式如下

                                                              d=\frac{1}{\left \| w \right \|}(wx+b)

  • 损失函数

       根据感知机的数学公式可知,wx+b>0则y=1,wx+b<0则y=-1,那么y(wx+b)<0即可表示样本错分,因此只需通过y(wx+b)的正负就可以判断样本是否错分。我们的目标是期望错误分类的样本到超平面的距离之和最小,损失函数可以设计如下

                                               

注:损失函数设计时将距离公式中的\left \| w \right \|简化掉了,损失函数只计算错分的样本点,由于错分样本存在y(wx+b)<0,所以在前面添加一个负号,整个优化目标就变成最小化损失函数了,其实不加负号也可以,那么优化目标就是最大化损失函数

  • 最优化方法

       求解模型即需要最小化损失函数L(w,b),这里主要采用梯度下降法来实现,因为损失函数定义的是只有误分类样本才能参与,所以不能使用批量梯度下降法(BGD),只能使用随机梯度下降法(SGD)。

       这里梯度下降法的实现有两种形式,不同形式是为了应对不同的情况,下面会详细介绍

1)原始形式

注:最小化损失函数时,更新梯度本来是w=w-梯度,但是损失函数前有负号,求导后的梯度前也有负号,最终就变成加号了

2)对偶形式

     当特征空间的维度很高(x的维度很高)时,原始形式会带来很大的计算量,为了减少计算量将原始形式进行改进得到了对偶形式

代码实现

def Perceptron(data, label, lr=0.001, iter=50):
    '''
    因为是随机梯度下降,所以是单样本进行梯度更新
    :param data: 样本 (m,n) m个样本,每个样本n维
    :param label: 标签  (m,1) m个样本的标签
    :param lr: 学习率
    :param iter: 迭代次数
    :return: w,b
    '''

    m = data.shape[0]
    n = data.shape[1]

    W = np.zeros((n, 1))  # 权重  (n,1)
    b = 0.0              # 偏置bias  (1)

    for k in range(iter):
        for i in range(m):
            x = np.array([data[i]])    # (1,n)
            y = label[i]
            d = -y*(np.dot(x, W) + b)
            if d >= 0:
                W = W + lr*y*np.transpose(x)  # (n,1)
                b = b + lr*y

    return W, b


def test(data, label, W, b):
    m = data.shape[0]

    errorcount = 0.0
    for i in range(m):
        x = data[i]
        y = label[i]
        result = -y * (np.dot(x, W) + b)
        if result >= 0:
            errorcount += 1

    accuracy = 1 - errorcount/m

    return accuracy


if __name__ == '__main__':
    #加载训练集和验证集
    traindata, trainlabel = loadData('../Mnist/mnist_train.csv')
    evaldata, evallabel = loadData('../Mnist/mnist_test.csv')

    W, b = Perceptron(traindata, trainlabel)

    accuracy = test(evaldata, evallabel, W, b)
    print('accuracy rate is:', accuracy)

       利用mnist数据进行训练(0-4为一类,5-9为另一类),最终测试结果如下图

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值