用C#实现感知器算法——从零开始打造一个简单的机器学习模型!

news/2024/12/20 21:21:58/文章来源:https://www.cnblogs.com/forges/p/18619991
感知器(Perceptron)是一个经典的机器学习算法,常用于二分类问题。它是神经网络的基础,最早由Frank Rosenblatt在1958年提出。今天,我们将用C#实现一个简单的感知器算法,让你理解感知器的工作原理,并能够亲自编码一个可用的模型。

一、感知器算法概述

感知器是一种线性分类器,其核心思想是通过调整权重(weights)和偏置(bias),使得模型能够根据输入数据进行分类。感知器通过迭代优化这些参数,最终得到一个超平面来分割不同类别的数据。

1. 感知器模型的工作原理

感知器的基本结构如下:

  1. 输入层:接收输入数据。

  2. 加权求和:每个输入与对应的权重相乘,并加上偏置项。

  3. 激活函数:将加权和通过一个阈值(通常为零)转换为输出。

感知器的输出 ( y ) 可以通过以下公式表示: [ y = \text{sign}(w_1x_1 + w_2x_2 + ... + w_nx_n + b) ]

  • ( w ):权重向量

  • ( x ):输入向量

  • ( b ):偏置

  • (\text{sign}) 是符号函数,输出1或-1

感知器的目标是找到最优的权重和偏置,使得分类误差最小。

2. 感知器的训练过程

感知器的训练过程就是不断调整权重和偏置,以最小化预测值和真实标签之间的差异。更新规则如下:

  • 如果预测正确,权重保持不变。

  • 如果预测错误,则更新权重和偏置: [ w = w + \eta \cdot (y{\text{true}} - y{\text{pred}}) \cdot x ] [ b = b + \eta \cdot (y{\text{true}} - y{\text{pred}}) ] 其中,(\eta) 是学习率,( y{\text{true}} ) 和 ( y{\text{pred}} ) 分别是实际标签和预测标签。


二、用C#实现感知器

现在,让我们用C#来实现一个简单的感知器算法,应用于经典的“与(AND)”或“或(OR)”二分类问题。

1. 感知器类的实现

我们首先定义一个感知器类,包含初始化权重、训练模型和预测函数。

using System;

public class Perceptron
{
   private double[] weights;
   private double bias;
   private double learningRate;

   public Perceptron(int inputSize, double learningRate = 0.1)
  {
       weights = new double[inputSize];
       bias = 0;
       this.learningRate = learningRate;
  }

   // 激活函数
   private int Activate(double sum)
  {
       return sum >= 0 ? 1 : -1;  // 阈值函数
  }

   // 训练感知器
   public void Train(double[][] inputs, int[] labels, int epochs)
  {
       for (int epoch = 0; epoch < epochs; epoch++)
      {
           for (int i = 0; i < inputs.Length; i++)
          {
               // 计算加权和
               double sum = 0;
               for (int j = 0; j < weights.Length; j++)
              {
                   sum += inputs[i][j] * weights[j];
              }
               sum += bias;

               // 获取预测结果
               int prediction = Activate(sum);

               // 更新权重和偏置
               if (prediction != labels[i])
              {
                   for (int j = 0; j < weights.Length; j++)
                  {
                       weights[j] += learningRate * (labels[i] - prediction) * inputs[i][j];
                  }
                   bias += learningRate * (labels[i] - prediction);
              }
          }
      }
  }

   // 预测
   public int Predict(double[] input)
  {
       double sum = 0;
       for (int i = 0; i < weights.Length; i++)
      {
           sum += input[i] * weights[i];
      }
       sum += bias;
       return Activate(sum);
  }

   // 输出当前权重和偏置
   public void PrintWeights()
  {
       Console.WriteLine("Weights: " + string.Join(", ", weights));
       Console.WriteLine("Bias: " + bias);
  }
}

2. 训练和测试感知器

接下来,我们来创建一个简单的训练集,应用感知器训练和预测。

class Program
{
   static void Main(string[] args)
  {
       // 定义“与(AND)”问题的输入和输出
       double[][] inputs = {
           new double[] {0, 0},
           new double[] {0, 1},
           new double[] {1, 0},
           new double[] {1, 1}
      };

       // 输出:与(AND)问题的期望结果
       int[] labels = { -1, -1, -1, 1 };  // 0 AND 0 = 0, 0 AND 1 = 0, 1 AND 0 = 0, 1 AND 1 = 1

       // 创建感知器实例
       Perceptron perceptron = new Perceptron(inputSize: 2);

       // 训练感知器
       perceptron.Train(inputs, labels, epochs: 10);

       // 输出训练结果
       perceptron.PrintWeights();

       // 测试预测
       Console.WriteLine("Prediction for [1, 1]: " + perceptron.Predict(new double[] { 1, 1 }));
       Console.WriteLine("Prediction for [0, 0]: " + perceptron.Predict(new double[] { 0, 0 }));
  }
}

三、代码分析

  1. 感知器初始化:我们为每个输入分配了一个初始权重,并设置了一个学习率。初始化时,偏置设为0,权重随机设置。

  2. 训练过程:每一轮训练(epochs)都会遍历整个训练集,计算加权和,并更新权重。如果预测错误,权重和偏置会根据公式进行调整。

  3. 预测:对于新的输入,感知器会计算加权和,并通过激活函数得到最终的预测值。


四、如何使用感知器?

感知器适用于线性可分的二分类问题,例如:

  • “与(AND)”问题

  • “或(OR)”问题

  • 基于特征的分类问题,如文本分类等。

然而,感知器存在局限性:它无法解决线性不可分的问题(如异或问题),但它为后续神经网络的发展提供了基础。


五、总结

通过本篇文章,你已经学会了如何用C#实现一个简单的感知器模型,并且了解了感知器的工作原理和训练过程。虽然感知器在某些问题上具有局限性,但它依然是机器学习的入门模型,非常适合帮助你理解深度学习中的基本概念。

如果你想深入学习机器学习的其他算法,或者对神经网络有兴趣,可以从感知器开始,逐步扩展到更复杂的模型。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/856108.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gtest简单用法

当前开发环境中,无法把测试代码提交到仓库,所以单测另起一个目录 . ├── gtest │ ├── CMakeLists.txt # 这是最外层的cmake,用以管理所有内部的cmake │ └── sample_test # 这是sample_src对应的测试用例,该目录下有一个单独的cmake │ ├── CMakeList…

跨境电商速卖通实训教学平台课程题库答案

近年来,随着全球化的不断加深与国际电子商务市场的蓬勃发展,中国的跨境电商产业进入了迅猛增长期。速卖通作为阿里集团推出的跨境电商交易平台之一,在全球尤其是俄罗斯市场占据了显著地位,其交易规模的持续增长吸引了众多企业和个人投身其中。在此背景下,对具有速卖通专业…

20222418 2024-2025-1《网络与系统攻防技术》实验八实验报告

1.实验内容 (1)Web前端HTML 能正常安装、启停Apache。理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML。 (2)Web前端javascipt 理解JavaScript的基本功能,理解DOM。 在(1)的基础上,编写JavaScript验证用户名、密码的规则。在用户点击登陆按钮后回显“欢迎+…

Java 基础概览

1. Java 语言概述 1.1 Java 简史 Java是一种高级程序设计语言,由SUN(Stanford University Network,斯坦福大学网络公司)公司于1995年推出,James Gosling设计Java语言,并开发了Java编译器和Java虚拟机,因此也被人尊称为“Java 之父”。SUN公司在2009年被Oracle(甲骨文)…

Linux学习笔记(一) Linux目录结构

下图显示的为Linux中的目录结构:/bin[常用](/usr/bin、/usr/local/bin) 是Binary(二进制)的缩写,这个目录存放着经常使用的命令。 /sbin(/usr/sbin、/usr/local/sbin) s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。 /home[常用] 存放普通用户的家目…

数据库审计与监控

title: 数据库审计与监控 date: 2024/12/20 updated: 2024/12/20 author: cmdragon excerpt: 数据库审计与监控是确保数据库安全性和性能的关键环节。通过实施有效的审计策略,可以追踪用户活动,监控数据访问与修改,从而及时发现潜在的安全威胁和性能瓶颈。探讨数据库审计的基…

Java实现单词的翻译(详解爬虫操作)

JAVA通过Crawler实现英语单词的翻译首先声明一点,这种方法仅限于低频次的交互来获取翻译信息,一旦一秒内大量的请求会被重定向,那就直接不能用了 如果希望可以批量查询英语单词翻译,可以查看我的下一篇博客。接着我们上一讲Java如何用HaspMap统计次数并排序详解 - ivanlee7…

实用工具:Calibre 7.22最新版 一款Window电子书管理工具和阅读器便携版

📢提示:文章排版原因,链接放在文章结尾👇👇,往下翻就行 📢提示:文章排版原因,链接放在文章结尾👇👇,往下翻就行 前言 初识Calibre 最近有几本epub格式的电子书要看发现电脑上没有可以打开的软件,所以最近找到了这个软件。功能 功能亮点电子书管理:Calib…

VS2022 C++QT 中文乱码 设置UTF-8编码

说明 所有内容来源于网络 通过插件调整源文件编码FileEncoding:查看编码 Force UTF-8:用于保存为UTF-8 C++项目设置为utf-8 项目-属性-配置属性-C/C++-命令行-其它选项 中 增加/utf-8、

雷池 WAF 配置了多条人机验证规则,命中规则是怎样的?

优先级说明 频率限制(1 小时) > 自定义规则(1 小时) > 站点 BOT 防护(自定义时长) 配置人机验证的地方 【防护配置-频率限制】限制结果选择【人机验证】【防护配置-自定义规则】规则类型选择【人机验证】【防护站点-站点管理】的【BOT 防护】中开启【人机验证】命中…

如何在C#.NET中使用LINX(arduino的LabView库)

思路:使用LabView的导出为.NET互操作程序集,导出COM给.NET调用在LabView安装HubMaker插件,将预编译固件刷入Arduino设备中。这不是本文的重点,省略 根据需要,编写VI。注意:必须在此处使用全局变量或者其它方法避免LinxResource簇在C#中出现,否则在程序运行时有概率出现堆…

C#.Net NModbus库 简单代码案例(非Nmodbus4库)

在NuGet管理器中搜索NModbus。注意,如果需要使用串口通信需要同时选中相关包