感知器代码实现--机器学习随笔2

这里主要是贴出我个人实现的代码
做出以下测试说明
1 分类并不能百分百正确,可能存在一些点无法正确分类的情况
2 由于没有引入代价函数,也没有使用梯度算法,这个学习率并不是非常准确,分离超平面可能不正确。同样的参数下,可以多运行几次,会出现正确的结果的。
3 希望感兴趣的朋友可以去实验以下,调整双月间距,多做几次实验。

这个算法主要验证了感知器算法是可以收敛的,并不保证能百分百分类正确!原因在前文也说明了。

希望大家能和我一起思考:如果改变数据的迭代方式(训练数据集)会对分类效果造成什么影响,为什么会有这些影响,如何消除?

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import random
import matplotlib.pyplot as plt
import numpy as np
import math

# 生成上部的半月
def gernarateUp(radius,center,alf):
        xsiy = []
        ysiy= []
        for x in range(center[0]-radius,center[0]+radius,1):
            counts = random.randint(0, alf*radius)
            for y in range(counts):
                r= random.randint(center[1], center[1] + radius)
                if np.sqrt((x-center[0])**2+(r-center[1])**2)>=alf*radius and np.sqrt((x-center[0])**2+(r-center[1])**2)<=radius:
                    xsiy.append(x)
                    ysiy.append(r)
        return [xsiy,ysiy]

#生成下部的半月
def gernaratefloor(radius,center,alf):
        xsiy = []
        ysiy= []
        for x in range(center[0]-radius,center[0]+radius,1):
            counts = random.randint(0, alf*radius)
            for y in range(counts):
                r= random.randint(center[1] - radius,center[1])
                if np.sqrt((x-center[0])**2+(r-center[1])**2)>=alf*radius and np.sqrt((x-center[0])**2+(r-center[1])**2)<=radius:
                    xsiy.append(x)
                    ysiy.append(r)

        return [xsiy,ysiy]

#生成双半月
# radius -- 半径
# center -- 上月圆心位置
# akf  --  内径比例
# x -- 下月圆心与上月圆心 在x轴上的距离 大于零时 往右移动
#y --- 下月圆心与上月圆心 在y 轴上的距离  大于零时 往上移动
def gernarate(radius,center,alf,x,y):
        floorCenter=[center[0]+x,center[1]+y]
        upCenter=center
        upSet = gernarateUp(radius,upCenter,alf)
        floorSet = gernaratefloor(radius,floorCenter,alf)
        return upSet,floorSet

# 感知器模型实现
def perceptron(w,x):
    # 线性计算部分
    z = np.sum(np.dot(w,x))
    # 激活函数部分
    if z>0:
        return 1
    if z<=0:
        return -1
# 学习率计算
def learningRate(w,x):
    z = np.sum(np.dot(w, x))
    xx = np.sum(np.dot(x, x))
    r = math.ceil(abs(z) / xx) + 1
    return r
# 针对每个输入的权值更新操作
def wRefresh(w,x,d):
    a=0
    flag =True
    while flag:
        a=a+1
        y=perceptron(w,x)
        r=learningRate(w,x)
        w = w + r * (d - y) * x
        if (d - y)==0:
            flag=False
    return w

if __name__ == ‘__main__‘:
    # 初始化 上下半月
    upSet, floorSet = gernarate(100,[60,60],0.6,60,-60)

    #初始化权值向量
    # 数据点的输入是二维的,第一个参数为偏置,第二参数为点的x坐标的权值,第三个参数为点的y坐标的权值
    # 这样处理的原因是我们后续的计算中将使用 感知器的简写形式来计算
    w = np.array([0,0,0])

    # 初始化输入向量

    # 上半月的数据长度
    upx =upSet[0]
    # 初始化1list
    bx = []
    for x in upSet[0]:
        bx.append(1)

    # 整合输入,将二维输入调整为3维度输入
    # [x,y]的形式变化为[1,x,y]
    upy= upSet[1]
    upInput = []
    upInput.append(bx)
    upInput.append(upx)
    upInput.append(upy)
    # 将数据转化为numpy类
    upInput = np.array(upInput).T

    # 同上,整合输入数据,这里只不过是针对下月做处理
    ax = []
    for x in floorSet[0]:
        ax.append(1)
    floorInput = []
    floorInput.append(ax)
    floorInput.append(floorSet[0])
    floorInput.append(floorSet[1])
    floorInput = np.array(floorInput).T

    # 由于上月与下月的数据点的数量不一定一致,这里做一个边缘处理

    # 获取数据长度较小的那个 长度
    min =  min(upInput.shape[0],floorInput.shape[0])

    # 逐行迭代
    # 这里要说明一点,以下采用了上月和下月数据交替运算的方式。
    for x in range(min):
        w = wRefresh(w, upInput[x,], 1)
        w = wRefresh(w, floorInput[x,], -1)

    # 对多出来的部分做处理
    temp=None
    tempD=None
    if upInput.shape[0]>floorInput.shape[0]:
        temp=upInput
        tempD=1
    else:
        temp=floorInput
        tempD=-1
    #由于数据长度较短的 那个半月已经迭代完毕,这里对剩余的数据进行迭代
    for x in range(min,max((upInput.shape[0],floorInput.shape[0]))):
        w = wRefresh(w, temp[x,], tempD)

    # 下面是分开迭代的方法,大家可以试一试,这样可能会出现无法正确分类的情况,思考下为什么!
    # for x in upInput:
    #     w = wRefresh(w,x,1)
    # print w
    # for x in floorInput:
    #     w = wRefresh(w,x,-1)

    # 数据描点(双月数据描点)
    plt.scatter(upSet[0], upSet[1])
    plt.scatter(floorSet[0], floorSet[1])

    # 超平面绘制
    # 0 = w[1]x+w[2]y+w[0] 由此式子活得y与x的关系
    xxxi=[]
    yyyyi=[]
    for x in range(-150,280):
        xxxi.append(x)
        yyyyi.append(x*(-w[1]/w[2])+w[0]/w[2])

    # 数据描点(超平面描点)
    plt.scatter(xxxi, yyyyi)
    #数据展示
    plt.show()

时间: 2024-10-09 15:42:22

感知器代码实现--机器学习随笔2的相关文章

TFboy养成记 多层感知器 MLP

内容总结与莫烦的视频. 这里多层感知器代码写的是一个简单的三层神经网络,输入层,隐藏层,输出层.代码的目的是你和一个二次曲线.同时,为了保证数据的自然,添加了mean为0,steddv为0.05的噪声. 添加层代码: def addLayer(inputs,inSize,outSize,activ_func = None):#insize outsize表示输如输出层的大小,inputs是输入.activ_func是激活函数,输出层没有激活函数.默认激活函数为空 with tf.name_sco

Coursera机器学习基石 第2讲:感知器

第一讲中我们学习了一个机器学习系统的完整框架,包含以下3部分:训练集.假设集.学习算法 一个机器学习系统的工作原理是:学习算法根据训练集,从假设集合H中选择一个最好的假设g,使得g与目标函数f尽可能低接近.H称为假设空间,是由一个学习模型的参数决定的假设构成的一个空间.而我们这周就要学习一个特定的H——感知器模型. 感知器模型在神经网络发展历史中占有特殊地位,并且是第一个具有完整算法描述的神经网络学习算法(称为感知器学习算法:PLA).这个算法是由一位心理学家Rosenblatt在1958年提出

机器学习——感知器算法实现

本次也是用processing3.0+写的,其官方网站https://processing.org/,建议直接看reference的例子进行学习. 感知器算法用的是我们老师给的ppt,实现的是二维的感知器,为了方便看,实际上多维的也是一样的: 运行效果是: 为了试验方便,我这是用了点击取点,键盘按一下t,大小写均可,下一个点的就是正例,按一下f,大小写均可,下一个点就是负例. 按s是开始进行学习度为1的迭代.结束会直接出直线,按2会出学习率为2的直线,迭代次数会打在程序底下,值是2. 代码仅供参

机器学习之感知器算法原理和Python实现

(1)感知器模型 感知器模型包含多个输入节点:X0-Xn,权重矩阵W0-Wn(其中X0和W0代表的偏置因子,一般X0=1,图中X0处应该是Xn)一个输出节点O,激活函数是sign函数. (2)感知器学习规则 输入训练样本X和初始权重向量W,将其进行向量的点乘,然后将点乘求和的结果作用于激活函数sign(),得到预测输出O,根据预测输出值和目标值之间的差距error,来调整初始化权重向量W.如此反复,直到W调整到合适的结果为止. (3)算法的原始形式 (4)Python代码实现 1 import

python机器学习——感知器

最近在看机器学习相关的书籍,顺便把每天阅读的部分写出来和大家分享,共同学习探讨一起进步!作为机器学习的第一篇博客,我准备从感知器开始,之后会慢慢更新其他内容. 在实现感知器算法前,我们需要先了解一下神经元(neuron)的工作原理,神经元有很多树突和一个轴突,树突(Dendrites)可以从其他神经元接收信息并将其带到细胞体(Cell nucleus),轴突(Axon)可以从细胞体发送信息到其他神经元.树突传递过来的信息在细胞体中进行计算处理后,如果结果超过某个阈值,轴突会传递信号到其他的神经元

机器学习 —— 基础整理(六):线性判别函数——感知器、松弛算法、Ho-Kashyap算法

本文简单整理了以下内容: (一)线性判别函数与广义线性判别函数 (二)感知器 (三)松弛算法 (四)Ho-Kashyap算法 (一)线性判别函数与广义线性判别函数 一.线性判别函数 这篇总结继续关注分类问题.假设判别函数(Discriminant function)的参数形式已知,用训练的方法直接根据样本估计判别函数的参数.线性判别函数的形式为: $$g(\textbf x)=\textbf w^{\top}\textbf x+w_0$$ $\textbf x\in \mathbb R^d$ 是

Stanford大学机器学习公开课(三):局部加权回归、最小二乘的概率解释、逻辑回归、感知器算法

(一)局部加权回归 通常情况下的线性拟合不能很好地预测所有的值,因为它容易导致欠拟合(under fitting).如下图的左图.而多项式拟合能拟合所有数据,但是在预测新样本的时候又会变得很糟糕,因为它导致数据的 过拟合(overfitting),不符合数据真实的模型.如下图的右图. 下面来讲一种非参数学习方法——局部加权回归(LWR).为什么局部加权回归叫做非参数学习方法呢?首先,参数学习方法是这样一种方法:在训练完成所有数据后得到一系列训练参数,然后根据训练参数来预测新样本的值,这时不再依赖

Python_sklearn机器学习库学习笔记(七)the perceptron(感知器)

一.感知器 感知器是Frank Rosenblatt在1957年就职于Cornell航空实验室时发明的,其灵感来自于对人脑的仿真,大脑是处理信息的神经元(neurons)细胞和链接神经元细胞进行信息传递的突触(synapses)构成. 一个神经元可以看做将一个或者多个输入处理成一个输出的计算单元.一个感知器函数类似于一个神经元:它接受一个或多个输入,处理 他们然后返回一个输出.神经元可以实时,错误驱动的学习,神经元可以通过一个训练样本不断的更新参数,而非一次使用整套的数据.实时学习可能有效的处理

神经网络与机器学习笔记——Rosenblatt感知器

Rosenblatt感知器 感知器是用于线性可分模式(模式分别位于超平面两边)分类的最简单的神经网络模型,基本上由一个具有可调突触权值和偏置的神经元组成. Rosenblatt证明了当用来训练感知器的模式(向量)取自两个线性可分的类时,感知器算法是收敛的,并且决策面是位于两类之间的超平面.算法的收敛性称为感知器收敛定理.