dotnet 从零开始写一个人工智能 网络模型

本文将不使用任何人工智能框架,只用简单的 dotnet 的类,自己搭建一个人工智能网络。本文适合小伙伴跟着一步步写

特别感谢老马的程序人生的帮助,本文有大量代码都是从如何利用 C# 抽象神经网络模型抄的

在人工智能模型有不同的问题可以选用不同的模型,本文主要写一个 BP 网络用于做分类,也就是写出一个简单的多分类人工智能和一个模拟二进制 与 计算和 或 计算。请不要认为本文会告诉大家如何写一个会和你聊QQ的人工智能,这里的人工智能其实也就是一个工具,和想象的智能差距有点大。本文的人工智能只能做对数值输入进行分类或实现模拟二进制计算

在一个人工智能模型,可以将人工智能模型作为网络模型建立,一个人工智能模型是一个网络模型,一个网络里面会有很多层,每一层有很多元。本文将从小到大进行定义,先从元定义,然后再从层定义,最后定义网络

在人工智能模型里面,最小单元都是神经元。一个神经元可以收到多个输入,而只有一个输出。在代码里面,将输入和输出的值都定义为double值。而本文写的神经元是固定输入数量,也就是在神经元对象创建的时候需要告诉这个神经元可以收到多少个数量的输入

在神经元里面将会对每个输入添加一个权值,在神经网络的每个元可以收到多个输入,而对每个输入需要使用不同的权值计算

最简单的神经元就是将每个输入的值乘以一个权值然后加起来然后输出。当然稍微复杂一点的是加起来之后需要加一个阈值然后调用激活函数计算输出

先忽略元的计算,定义元的数据结构

上面的模型感谢老马的程序人生大佬提供,只是定义了基础数据结构,而计算方法作为抽象方法。在 Compute 方法接受多个输入,然后有一个 double 输出

在 Randomize 方法给了权值数组一些随机值,其实有一句话是人工智能和随机猜是差不多的。本文下面将写一个随机给权值的训练方法

上面的 DoubleRange 是自己定义的,用来创建范围内的随机数,只需要看代码就知道是如何做的

接下来定义一个 ActivationNeuron 继承 Neuron 这里定义了阈值和激活函数

计算的方法是将多个输入的每个输入乘以权值加起来,然后加上阈值,接下来放入激活函数计算输出。为什么需要激活函数?原因是计算的 sum 的值需要输出到下一层需要将 sum 的值处理,如本文需要让每一层的输入的值都是 1 和 0而因为每一层的输出会作为下一层的输入,所以需要将 sum 值计算为 1 和 0 也就是通过 阈值函数 将一个值按照是否大于等于 0 分为 1 和 0 两个值

那么 阈值函数 的定义是什么,阈值就是临界值,函数的目的是大于这个临界值会怎么样,小于这个临界值会怎么样。本文只是让大于等于 0 输出为 1 否则输出 0 这个值

激活函数的定义是

和 阈值函数 相应的激活函数还有符号函数等,符号函数就是按照一定的范围,将输入转换为 1 或 -1 因为负数叫符号,这也就是符号函数的名字。详细定义请看 符号函数

也就是在接受多个输入,对多个输入乘以权值加起来,再加上阈值,放入激活函数,计算后输出。这就是最简单的元的定义

定义完成了元,接下来就是定义层的概念,每一层可以有多个元,每一层可以收到上一层的数据。而第一层叫输入层,输入层将会接受用户的输入。最后一层叫输出层,输出层的值将会作为输出。简单的网络只需要一个元,一个元作为一层,而这个网络也只有一层。这一层只有一个元,是输入层也是输出层。这是最简单的模型,也就是本文接下来告诉大家的模型。也就是元是核心,只有一个元也能做出人工智能

定义的层需要知道输入的数量,而层里每个元都会被定义相同数量的输入。此时的连接和全连接差不多,也就是每个元都接受到相同的输入。其实这样的定义对于某个元只需要特定的几个输入也是可以实现的,因为每个元会对每个输入一个权值,如果设置某个输入的权值为 0 那么相当于放弃这个输入。这样就可以做到某个元只接受特定的几个输入而不是收到所有的输入。而为什么一些高级的模型不会让同一层的所有元收到的输入相同?刚才不是说可以让元自己控制放弃哪些输入,原因是虽然可以让元自己控制放弃一些输入,但是这样做的效率比较低,高级的模型需要提升效率,本文这里无视所以可以使用每一层的所有元收到相同的输入

本文这里使用的模型是每一层的元数量不可变,在定义层时就知道这一层有多少元。这样的模型功能会比较差,但是作为入门的博客,这样的定义差不多可以使用了

每一个元只有一个输入,所以每一层的输出数量和每一层的元数量相同

接下来定义 ActivationLayer 作为实际的神经网络层,其实从代码可以看到连个类可以合并在一起,只是老马的程序人生大佬作为两篇博客,我这里也就跟着他写了

一个网络可以包含多个层

请看一下代码里面的注释

实现一个网络

上面代码的实现有些诡异,原因是我的参数没有写好。在 ActivationNetwork 的最后一个参数是一个数组,指定神经网络每层中的神经元数量。也就是输入 [1,2] 表示有两层,其中第一层有 1 个神经元,第二层有两个。输入 [1,1,5] 表示有三层

而根据人工智能的教程,第一层是输入层,也就是 i == 0 设置这一层的输入为用户输入数量。从第二层开始,每一层的输入数量为上一层的输出数量

定义完成了人工智能模型,一个模型不会自动运行,还需要定义一个训练方法。作为可以自己学习的人工智能,学习方法可以分为监督学习和无监督学习,在代码里面我用老马的程序人生的说法非监督学习。这两个方法的不同在于监督学习是我知道输入内容和结果,我将输入放入模型,对比模型输出的值和我知道的结果,按照模型输出的值和我知道的结果的误差反馈给模型,让模型修改参数,如修改权值参数。而无监督学习是我也不知道结果,这个比较难理解,详细请看监督学习和无监督学习 或 小白都看得懂的监督学习与无监督学习 本文用到的是监督学习

这里的输入分为多样本训练和单样本训练也就是我给一堆数据就是多样本训练。从方法参数可以看到输入的都是二维数组,当然这里说二维数组是不对的,应该是数组的数组。从单样本训练方法可以看到每个数据都是输入是一个 double 数组,而输出也是一个 double 数组,那么多个输入和多个输出就是数组的数组

刚才也有说到,人工智能和随机猜是一样的,在人工智能的训练很重要的是反馈,也就是我告诉人工智能说算错了,他应该如何修改参数?这部分看起来有点难,假设这个人工智能我告诉他算错了,他就随机修改他的参数,这就是本文的 Slow 训练方法,这个方法只是慢,和其他训练方法差不多

用随机修改参数方法要求模型很简单,本文要求的模型只是一层,也就是输入层和输出层是相同的一层。在 单个训练样本 方法将会使用模型计算出一个值,通过 double[] networkOutput = _network.Compute(input); 然后对比误差 double e = output[j] - networkOutput[j]; 如果存在误差,那么用 perceptron.Weights[i] = RandRange.GetRan(); 更新每个元的每个参数的值

现在大概写完了代码,本文的代码放在 github 下载用 VisualStudio 打开 Bp.sln 文件,然后按下 F5 就可以运行

尝试用这个模型和训练方法做出一个模拟二进制 与 的计算,也就是输入有两个,输出是件这两个输入进行 与 运算

这个人工智能网络使用输入层有两个,只有一层网络,一层网络里面只有一个神经元

创建训练方法

尝试运行代码,可以看到我没有告诉人工智能如何做 与 运算,但是人工智能模拟了方法

尝试训练人工智能模型模拟二进制或计算

我没有告诉人工智能或计算的方法,但是人工智能可以训练如何计算

这样的太简单了,其实上面的模型可以做出多分类,多分类就是将一些输入分为几类。如按照二维几何距离将数据分为几类,然后让人工智能分类

这个数据是如何利用 C# 实现神经网络的感知器模型用到的数据

上面的数据的输入是两个数,而输出是三个数。在输出用 0 和 1 表示属于哪个类型

本文定义一层网络,在这一层网络的输出需要三个数也就是需要三个元

这就是一个简单的人工智能模型,所有代码都没有用到现有人工智能框架,都是使用 dotnet 基础的代码。用 C# 实现人工智能模型最成熟的是 ML.NET 但是这个库没有基础很难知道是做什么

本文的代码放在github 欢迎小伙伴访问

其实人工智能的一个核心是训练算法,本文告诉大家的是 Slow 算法,这个算法就是在人工智能模型输出的值和我知道的值不同时,让模型随机更新参数。这个做法虽然能完成,但是效率很低,特别在元的数量多的时候。此时就需要用到比较高级的训练方法,如如何利用 C# 实现神经网络的感知器模型

特别感谢老马的程序人生提供的模型

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

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

相关文章

深度学习之tensorflow环境搭建

深度学习之tensorflow环境搭建: 1.搭建的步骤 1-1.破解版的Pycharm软件包下载 1-2.Ananconda软件包的下载 1-3.使用Anaconda Prompt 命令,首先输入 “conda create -n py37 python3.7 anaconda” 然后回车等待包的下载,其次激活py37&am…

SkyWalking学习笔记(CentOS环境)

基于 CentOS 环境使用 SkyAPM-dotnet 来介绍一下 SkyWalking, SkyAPM-dotnet 是 SkyWalking 的 .NET Agent环境要求JDK8Elasticsearch8080,9200,10800,11800,12800 端口不被占用Elasticsearch安装Elasticsearch下载安装(CentOS为例) 参考官方教程.下载并安装公共签名…

[蓝桥杯2019初赛]最大降雨量-模拟

题目描述 由于沙之国长年干旱,法师小明准备施展自己的一个神秘法术来求雨。 这个法术需要用到他手中的49 张法术符,上面分别写着1 至49 这49 个数字。 法术一共持续7 周,每天小明都要使用一张法术符,法术符不能重复使用。 每周&a…

用户登录的电话号码和密码进行测试PythonGUI实验

用户登录的电话号码和密码进行测试PythonGUI实验: 1.要求:对用户登录的电话号码和密码进行测试 2.电话号码:分为首字母不为0,长度必须为11为,类型全部为数字 3.密码:分为长度为6-12位,类型为AS…

武汉坚守第十二日——爆发期的困守待破

已经到了第十二天,不能出门的日子,浑身都是难受的,尤其对于我这样一个日常一天要步行10公里每年4000公里步行的人来说,坚持了四年的习惯变成这样,真心不舒服,于是在室内开始了一些自救——自救运动&#xf…

[蓝桥杯2019初赛]完全二叉树的权值-完全二叉树的性质

注意: j < n不能少!!! 代码如下&#xff1a; #include <iostream> using namespace std; const int N 100010; typedef long long LL; int a[N];int main() {int n;LL maxv -1e18;cin >> n;int depth 0;for (int i 1; i < n; i)cin >> a[i];for …

机器学习前的热身(必备)

机器学习前的热身&#xff08;必备&#xff09; 备注&#xff1a; 本内容参考李航的《统计学习方法第二版》第一章 注&#xff1a;如果本篇内容存在错误&#xff0c;望大家留言批评指正。

WTM系列视频教程:初体验

WTM系列视频教程第一章&#xff1a;初体验文字摘要&#xff1a;“如果你没用过wtm&#xff0c;今天的教程肯定能让你眼前一亮&#xff0c;这个框架竟然这么牛逼么&#xff1f;开发速度这么快么&#xff1f;”“至于为什么叫WTM&#xff0c;他的全称是WalkingTec MVVM&#xff0…

[蓝桥杯2019初赛]修改数组-并查集

代码如下&#xff1a; #include <iostream> using namespace std; const int N 1000010; int a[N];int find(int x) {if (a[x] ! x)a[x] find(a[x]);return a[x]; }int main() {int n;cin >> n;for (int i 1; i < N; i)a[i] i;for (int i 1; i < n; i)…

【听歌】GDB入门教程之查看函数调用堆栈

写在前面&#xff1a;又到周末啦~上上周忍痛买了个雅马哈声卡和 AKG 话筒&#xff0c;这周六才正式打开试用了下&#xff0c;效果还不错&#xff0c;我自己还挺享受的。不过这玩意儿太高端&#xff0c;还不会用 AI 调音。小伙伴们感觉下这首加了一点点电音效果的歌曲如何呢等我…

python通过tkinter界面库实现三角形成立的测试

python通过tkinter界面库实现三角形成立的测试 from tkinter import * from tkinter import messagebox login Tk() login.title(验证) login.geometry(800x600) Label(login,text实现三角形成立的验证).grid(row0,column0,columnspan2) Label(login,text边a&#xff1a;).gr…

研发协同平台持续集成实践

源宝导读&#xff1a;“持续集成”是敏捷最佳实践中&#xff0c;保证高质量交付的关键环节之一。本文将分享&#xff0c;在大规模研发在线协同的背景下&#xff0c;如何支撑在线持续集成的高性能和高可用。 一、什么是持续集成 在《持续集成》一书中&#xff0c;对持续集成的定…

机器学习朴素贝叶斯算法+tkinter库界面实现好瓜坏西瓜分类

机器学习朴素贝叶斯算法tkinter库界面实现好瓜坏西瓜分类 一、界面实现 from tkinter import * from tkinter import ttk import NBdef main():win Tk()win.title(甜的西瓜挑选系统)win.geometry(1000x600)lb2 Label(win, text"色泽", font"tahoma 12 norma…

《ASP.NET Core 微服务实战》-- 读书笔记(第3章)

第 3 章 使用 ASP.NET Core 开发微服务 微服务定义 微服务是一个支持特定业务场景的独立部署单元。它借助语义化版本管理、定义良好的 API 与其他后端服务交互。它的天然特点就是严格遵守单一职责原则。 为什么要用 API 优先 所有团队都一致把公开、文档完备且语义化版本管理的…

数据结构----------实现最小堆排序

数据结构----------实现最小堆排序 原理&#xff1a; 来源于---------------趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #define N 65535//最大个数排序 int r[N] { -1,1,4,590,4,2,8,7,5,89,67,5,2,1,67,86,54 };//存储要排序的数,第…

abp vnext2.0之核心组件模块加载系统源码解析

abp vnext是abp官方在abp的基础之上构建的微服务架构,说实话,看完核心组件源码的时候,很兴奋,整个框架将组件化的细想运用的很好,真的超级解耦.老版整个框架依赖Castle的问题,vnext对其进行了解耦,支持AutoFac或者使用.Net Core的默认容器.vnext依然沿用EF core为主,其余ORM为辅…

最大堆和最小堆排序

最大堆和最小堆排序 原理参考趣学数据结构 代码 #include<stdio.h> #include<stdlib.h> int r[] { -1,1,4,590,4,2,8,7,5,89,67,5,2,1,67,86,54 };//存储要排序的数,第一个元素不存储元素赋值为-1 int length sizeof(r) / sizeof(int);//待排序的数的个数 void s…

wordList01

wordList one 如果存在什么问题请批评指正&#xff01;谢谢

《ASP.NET Core 微服务实战》-- 读书笔记(第4章)

第 4 章 后端服务现实中的服务不可能处于真空之中&#xff0c;大多数服务都需要与其他服务通信才能完成功能。我们将这些支持性服务称为后端服务&#xff0c;接下来我们将通过创建一个新的服务并修改之前的团队服务与这个服务通信&#xff0c;以探索如何创建并消费后端服务。微…

WordList02

WordList 2 如果存在什么问题欢迎批评指正&#xff01;谢谢&#xff01;