JAVA实现感知器算法

简述

随着互联网的高速发展,A(AI)B(BigData)C(Cloud)已经成为当下的核心发展方向,假如三者深度结合的话,AI是其中最核心的部分。所以如果说在未来社会,每个人都必须要学会编程的话,那么对于程序员来说,人工智能则是他们所必须掌握的技术(科技发展真tm快)。

这篇文章介绍并用JAVA实现了一种最简单的感知器网络,不纠结于公式的推导,旨在给大家提供一下学习神经网络的思路,对神经网络有一个大概的认识。

感知器网络模型分析

首先看一张图

如果稍微对神经网络感兴趣的一定对这张图不陌生,这张图是神经元的结构图
X1~Xm表示输入,W1~Wm表示突触权值,Σ表示求和结点,Activation function表示激活函数,之后输出一个结果,具体的流程是

神经元接收到输入,每个输入都会与其相对路径上的权值相乘,到了求和结点进行求和,这里把求和结点的结果设为z :

z = X1 * W1 + X2 * W2 + X3 * W3 + ...... + Xm * Wm

之后将 z 传入到激活函数(这里我们称激活函数为 f)进行二分类模式识别 :

if f(x) > e,y = 1
else y = -1

e 为阈值
y 为分类结果

这里可以看出,如果 f(x) 的值大于阈值,得到分类 y = 1,反之 y = -1
注:相对于生物神经元受到刺激表示的反应,如果刺激在可接受范围之内,则神经元会抑制刺激(y = -1),如果超过范围则会兴奋(y = 1),而这个范围的分水岭就是阈值(e)

学习

我们发现,如果权值和阈值都固定的话,那么这个神经网络就没有存在的意义了,所以我们引入学习的概念,通过学习,让神经网络去修改权值和阈值,从而可以动态的修正模式识别的正确率,这才是机器学习的本质。

那么如何学习呢?当我们在使用之前我们需要提供给此网络一组样本数据(这里采取的是有教师模式学习),样本数据包括输入数据x和正确的识别结果y'。
当我们输入训练数据x得到模式识别y之后进行判断,如果 y != y' ,则会去调整此网络的权值和阈值,调整请看公式,μ 表示学习率(修正率),update 表示需要修正值:

update = μ * (yi - y')
update = (f(x) - y')

m
Σ  Wi += update * Xi
i=1

e += update

当感知器分类结果等于正确分类,update = 0,不调整网络;如果不等于正确分类,则会调整全部的权值(w)与阈值(e)

以上就是我所介绍的感知器最简单的学习流程:

输入数据->求和得到z->通过激活函数等到分类结果->分类结果与正确结果不符则调整网络

下面就让我们来实现这个简单的神经网络吧

Java代码实现

这里我所实现的是通过神经网络学习识别整数的正负
首先定义一个感知器的类

/**
 * Created by CimZzz on 12/2/17.
 *
 */
public class Perceptron {
  /**
   * 学习率
   */
  private final float learnRate;

  /**
   * 学习次数
   */
  private final int studyCount;

  /**
   * 阈值
   */
  private float e;

  /**
   * 权值
   * 因为判断整数正负只需要一条输入,所以这里只有一个权值,多条输入可以设置为数组
   */
  private float w;

  /**
   * 每次学习的正确率
   */
  private float[] correctRate;

  //

  /**
   * 构造函数初始化学习率,学习次数,权值、阈值初始化为0
   * @param learnRate 学习率(取值范围 0 < learnRate < 1)
   * @param studyCount 学习次数
   */
  public Perceptron(float learnRate, int studyCount) {
    this.learnRate = learnRate;
    this.studyCount = studyCount;

    this.e = 0;
    this.w = 0;

    this.correctRate = new float[studyCount];
  }

  /**
   * 学习函数,samples 是一个包含输入数据和分类结果的二维数组,
   * samples[][0] 表示输入数据
   * samples[][1] 表示正确的分类结果
   * @param samples 训练数据
   */
  public void fit(int[][] samples) {
    int sampleLength = samples.length;

    for(int i = 0 ; i < studyCount ; i ++) {
      int errorCount = 0;

      for (int[] sample : samples) {
        float update = learnRate * (sample[1]-predict(sample[0]));

        //更新权值、阈值
        w += update * sample[0];
        e += update;

        //计算错误次数
        if (update != 0)
          errorCount++;
      }

      //计算此次学习的正确率
      correctRate[i] = 1 - errorCount * 1.0f / sampleLength;
    }
  }

  /**
   * 求和函数,模拟求和结点操作 输入数据 * 权值
   * @param num 输入数据
   * @return 求和结果 z
   */
  private float sum(int num) {
    return num * w + e;
  }

  /**
   * 激活函数,通过求和结果 z 和阈值 e 进行判断
   * @param num 输入数据
   * @return 分类结果
   */
  public int predict(int num) {
    return sum(num) >= 0 ? 1 : -1;
  }

  /**
   * 打印正确率
   */
  public void printCorrectRate() {
    for (int i = 0 ; i < studyCount ; i ++)
      System.out.printf("第%d次学习的正确率 -> %.2f%%\n",i + 1,correctRate[i] * 100);
  }
}

然后写生成训练数据的函数

  /**
   * 生成训练数据
   * @return 训练数据
   */
  private static int[][] genStudyData() {
    //这里我们取 -100 ~ 100 之间的整数,大于0的设为模式 y = 1,反之为 y = -1
    int[][] data = new int[201][2];

    for(int i = -100 , j = 0; i <= 100 ; i ++ , j ++) {
      data[j][0] = i;
      data[j][1] = i >= 0 ? 1 : -1;
    }

    return data;
  }

  /**
   * 生成训练数据
   * @return 训练数据
   */
  private static int[][] genStudyData2() {
    //这里我们取 1~250 之间的整数,大于125的设为模式 y = 1,反之为 y = -1
    int[][] data = new int[250][2];

    for(int i = 1 , j = 0; i <= 250 ; i ++ , j ++) {
      data[j][0] = i;
      data[j][1] = i >= 125 ? 1 : -1;
    }

    return data;
  }

最后是主函数

public static void main(String[] args) {
    //这里的学习率和训练次数可以根据情况人为调整
    Perceptron perceptron = new Perceptron(0.4f,500);

    perceptron.fit(genStudyData());
    perceptron.printCorrectRate();

    System.out.println(perceptron.predict(-1));
    System.out.println(perceptron.predict(126));
  }

大家可以测试一下

局限性

这个感知器神经网络比较简单,是适用于可线性划分的数据,比如一维的话正数和负数,二维的坐标象限分类;对于不可线性划分的数据无法进行正确的分类,如寻找质数等

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Python实现感知器模型、两层神经网络

    本文实例为大家分享了Python实现感知器模型.两层神经网络,供大家参考,具体内容如下 python 3.4 因为使用了 numpy 这里我们首先实现一个感知器模型来实现下面的对应关系 [[0,0,1], --- 0 [0,1,1], --- 1 [1,0,1], --- 0 [1,1,1]] --- 1 从上面的数据可以看出:输入是三通道,输出是单通道. 这里的激活函数我们使用 sigmoid 函数 f(x)=1/(1+exp(-x)) 其导数推导如下所示: L0=W*X; z=f(L0);

  • python实现感知器算法详解

    在1943年,沃伦麦卡洛可与沃尔特皮茨提出了第一个脑神经元的抽象模型,简称麦卡洛可-皮茨神经元(McCullock-Pitts neuron)简称MCP,大脑神经元的结构如下图.麦卡洛可和皮茨将神经细胞描述为一个具备二进制输出的逻辑门.树突接收多个输入信号,当输入信号累加超过一定的值(阈值),就会产生一个输出信号.弗兰克罗森布拉特基于MCP神经元提出了第一个感知器学习算法,同时它还提出了一个自学习算法,此算法可以通过对输入信号和输出信号的学习,自动的获取到权重系数,通过输入信号与权重系数的乘积来

  • python实现感知器

    上篇博客转载了关于感知器的用法,遂这篇做个大概总结,并实现一个简单的感知器,也为了加深自己的理解. 感知器是最简单的神经网络,只有一层.感知器是模拟生物神经元行为的机器.感知器的模型如下: 给定一个n维的输入 ,其中w和b是参数,w为权重,每一个输入对应一个权值,b为偏置项,需要从数据中训练得到. 激活函数 感知器的激活函数可以有很多选择,比如我们可以选择下面这个阶跃函数f来作为激活函数: 输出为: 事实上感知器可以拟合任何线性函数,任何线性分类或线性回归的问题都可以用感知器来解决.但是感知器不

  • JAVA实现感知器算法

    简述 随着互联网的高速发展,A(AI)B(BigData)C(Cloud)已经成为当下的核心发展方向,假如三者深度结合的话,AI是其中最核心的部分.所以如果说在未来社会,每个人都必须要学会编程的话,那么对于程序员来说,人工智能则是他们所必须掌握的技术(科技发展真tm快). 这篇文章介绍并用JAVA实现了一种最简单的感知器网络,不纠结于公式的推导,旨在给大家提供一下学习神经网络的思路,对神经网络有一个大概的认识. 感知器网络模型分析 首先看一张图 如果稍微对神经网络感兴趣的一定对这张图不陌生,这张

  • python实现神经网络感知器算法

    现在我们用python代码实现感知器算法. # -*- coding: utf-8 -*- import numpy as np class Perceptron(object): """ eta:学习率 n_iter:权重向量的训练次数 w_:神经分叉权重向量 errors_:用于记录神经元判断出错次数 """ def __init__(self, eta=0.01, n_iter=2): self.eta = eta self.n_iter

  • python实现感知器算法(批处理)

    本文实例为大家分享了Python感知器算法实现的具体代码,供大家参考,具体内容如下 先创建感知器类:用于二分类 # -*- coding: utf-8 -*- import numpy as np class Perceptron(object): """ 感知器:用于二分类 参照改写 https://blog.csdn.net/simple_the_best/article/details/54619495 属性: w0:偏差 w:权向量 learning_rate:学习率

  • 详解如何用Python实现感知器算法

    目录 一.题目 二.数学求解过程 三.感知器算法原理及步骤 四.python代码实现及结果 一.题目 二.数学求解过程 该轮迭代分类结果全部正确,判别函数为g(x)=-2x1+1 三.感知器算法原理及步骤 四.python代码实现及结果 (1)由数学求解过程可知: (2)程序运行结果 (3)绘图结果 ''' 20210610 Julyer 感知器 ''' import numpy as np import matplotlib.pyplot as plt def get_zgxl(xn, a):

  • 基于 Python 实践感知器分类算法

    Perceptron是用于二进制分类任务的线性机器学习算法.它可以被认为是人工神经网络的第一种和最简单的类型之一.绝对不是"深度"学习,而是重要的组成部分.与逻辑回归相似,它可以快速学习两类分类任务在特征空间中的线性分离,尽管与逻辑回归不同,它使用随机梯度下降优化算法学习并且不预测校准概率. 在本教程中,您将发现Perceptron分类机器学习算法.完成本教程后,您将知道: Perceptron分类器是一种线性算法,可以应用于二进制分类任务. 如何使用带有Scikit-Learn的Pe

  • python离散建模之感知器学习算法

    我们将研究一种判别式分类方法,其中直接学习评估 g(x)所需的 w 参数.我们将使用感知器学习算法.感知器学习算法很容易实现,但为了节省时间,我在下面为您提供了一个实现.该函数有几个输入:训练数据.训练标签.对权重的初始猜测和学习率.注意,对于这两个类,类标签的值必须为+1和-1. 它将返回一个元组,其中包含: 1.学习w参数 2.执行的迭代次数 3.错误分类的样本数 花些时间检查代码.如果不清楚每一行是如何工作的,不要担心,只要让你自己知道每一行的目的是什么就可以了.代码中有一些注释可以帮助大

  • Java垃圾回收机制算法详解

    概述 Java GC(Garbage Collection,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题,也不需要像C程序员那样战战兢兢.这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制.概括地说,该机制对JVM中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,永不停息的保证JVM中的内存空间,防止出现内存泄露和溢出问题. 在真实工作中的项目中,时不时的会发生内存溢

  • java 中平方根(sqrt)算法 的实例详解

    java 中平方根(sqrt)算法 平方根(sqrt, square root)是数学中常见的数学的公式; 使用程序进行求平方根主要分为两步: 第一步: while()循环, 控制循环次数及小数的位数, 防止无限循环和出现多位小数; 第二步: 通过分解平方根, 使用循环, 逐渐减小,接近平方根; 同理, 其他方根也可以类似扩展, 不过需要注意的是, 偶数次方根需要确保输入正数; 奇数次方根需要转换为正数, 确保循环收敛, 再进行结果正负判断; 代码如下: /* * Algorithms.java

随机推荐