C#构建一个简单的前馈神经网络

embedded/2024/11/25 12:28:35/
1. 神经网络的基本概念

神经网络是一种模拟人脑神经元结构的计算模型,由多个神经元(节点)组成,这些神经元通过连接(边)相互作用。每个连接都有一个权重,用于表示连接的重要性。神经网络通常分为输入层、隐藏层和输出层。

2. 神经元

神经元是神经网络的基本单元,它接收输入信号,通过激活函数处理这些信号,然后产生输出。常见的激活函数包括Sigmoid、ReLU、Tanh等。

3. 前向传播

前向传播是从输入层到输出层的信号传递过程。每个神经元的输出作为下一层神经元的输入,直到最终产生输出。

4. 反向传播

反向传播是训练神经网络的关键步骤,通过计算损失函数的梯度并调整权重,使得网络的预测误差最小化。

using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Project.NeuralNetwork
{/// <summary>/// 构建神经网络/// 简单的前馈神经网络/// </summary>public class NeuralNetwork{/// <summary>/// 定义神经网络的层数和每层的神经元数量/// </summary>private readonly int[] layers;/// <summary>/// 存储每层的神经元值/// </summary>private double[][] neurons;/// <summary>/// 存储每层之间的权重/// </summary>private double[][][] weights;/// <summary>/// 存储每层的偏置/// </summary>private double[][] biases;/// <summary>/// 初始化/// </summary>/// <param name="layers"></param>public NeuralNetwork(int[] layers){this.layers = layers;InitializeNeurons();InitializeWeightsAndBiases();}/// <summary>/// 初始化神经元数组/// </summary>private void InitializeNeurons(){neurons = new double[layers.Length][];for (int i = 0; i < layers.Length; i++){neurons[i] = new double[layers[i]];}}/// <summary>/// 随机初始化权重和偏置/// </summary>private void InitializeWeightsAndBiases(){Random random = new Random();weights = new double[layers.Length - 1][][];biases = new double[layers.Length - 1][];for (int i = 0; i < layers.Length - 1; i++){weights[i] = new double[layers[i]][];for (int j = 0; j < layers[i]; j++){weights[i][j] = new double[layers[i + 1]];for (int k = 0; k < layers[i + 1]; k++){weights[i][j][k] = random.NextDouble() * 2 - 1;}}biases[i] = new double[layers[i + 1]];for (int j = 0; j < layers[i + 1]; j++){biases[i][j] = random.NextDouble() * 2 - 1;}}}/// <summary>/// sigmoid激活函数/// </summary>/// <param name="x"></param>/// <returns></returns>private double Sigmoid(double x){return 1.0 / (1.0 + Math.Exp(-x));}/// <summary>/// sigmoid激活函数的导数/// </summary>/// <param name="x"></param>/// <returns></returns>private double SigmoidDerivative(double x){return x * (1 - x);}/// <summary>/// 前向传播/// </summary>/// <param name="inputs"></param>public void Forward(double[] inputs){Array.Copy(inputs, neurons[0], inputs.Length);for (int i = 1; i < layers.Length; i++){for (int j = 0; j < layers[i]; j++){double sum = biases[i - 1][j];for (int k = 0; k < layers[i - 1]; k++){sum += neurons[i - 1][k] * weights[i - 1][k][j];}neurons[i][j] = Sigmoid(sum);}}}/// <summary>/// 反向传播/// </summary>/// <param name="target"></param>/// <param name="learningRate"></param>public void Backward(double[] target, double learningRate){double[][] deltas = new double[layers.Length - 1][];// 计算输出层deltas[layers.Length - 2] = new double[layers[layers.Length - 1]];for (int i = 0; i < layers[layers.Length - 1]; i++){double error = target[i] - neurons[layers.Length - 1][i];deltas[layers.Length - 2][i] = error * SigmoidDerivative(neurons[layers.Length - 1][i]);}// 计算隐藏层for (int i = layers.Length - 3; i >= 0; i--){deltas[i] = new double[layers[i + 1]];for (int j = 0; j < layers[i + 1]; j++){double error = 0.0;for (int k = 0; k < layers[i + 2]; k++){error += deltas[i + 1][k] * weights[i + 1][j][k];}deltas[i][j] = error * SigmoidDerivative(neurons[i + 1][j]);}}// 更新权重和偏差for (int i = 0; i < layers.Length - 1; i++){for (int j = 0; j < layers[i]; j++){for (int k = 0; k < layers[i + 1]; k++){weights[i][j][k] += learningRate * neurons[i][j] * deltas[i][k];}}for (int j = 0; j < layers[i + 1]; j++){biases[i][j] += learningRate * deltas[i][j];}}}/// <summary>/// 训练神经网络,使用反向传播算法更新权重和偏置/// </summary>/// <param name="inputs">输入</param>/// <param name="targets">目标</param>/// <param name="epochs">数据运算次数</param>/// <param name="learningRate">学习速率</param>public void Train(double[][] inputs, double[][] targets, int epochs, double learningRate){for (int epoch = 0; epoch < epochs; epoch++){for (int i = 0; i < inputs.Length; i++){Forward(inputs[i]);Backward(targets[i], learningRate);}}}/// <summary>/// 使用训练好的模型进行预测/// </summary>/// <param name="input"></param>/// <returns></returns>public double[] Predict(double[] input){Forward(input);return neurons[layers.Length - 1];}}
}
  • 准备训练数据
  • 训练网络
  • 测试网络并输出结果
           //1. 数据准备double[][] inputs = new double[][]{new double[] { 0, 0 },new double[] { 0, 1 },new double[] { 1, 0 },new double[] { 1, 1 }};double[][] targets = new double[][]{new double[] { 0 },new double[] { 1 },new double[] { 1 },new double[] { 0 }};//2. 构建神经网络// 定义神经网络结构:输入层2个神经元,隐藏层3个神经元,输出层1个神经元int[] layers = { 2, 3, 1 };NeuralNetwork model = new NeuralNetwork(layers);//3. 训练和评估//使用训练数据训练神经网络,并评估其性能。model.Train(inputs, targets, 10000, 0.01);//4. 训练神经网络model.Train(inputs, targets, epochs: 10000, learningRate: 0.5);// 预测数据foreach (var input in inputs){double[] prediction = model.Predict(input);Console.WriteLine($"输入: [{string.Join(", ", input)}] => 输出: [{string.Join(", ", prediction)}]");}


http://www.ppmy.cn/embedded/140373.html

相关文章

13、常用类:

13、常用类&#xff1a; 包装&#xff08;Wrapper&#xff09;类&#xff1a; 包装类的分类&#xff1a; 针对八种基本数据类型相应的引用类型——包装类&#xff1b;有了类的特点&#xff0c;就可以调用类中的方法。 基本数据类型包装类booleanBooleancharCharacterbyteBy…

深信服技术服务工程师(网络安全、云计算方向)面试题

1.tcp3次握手和四次挥手的过程。 2.简述ospf动态路由。 3.哪些地方用静态路由&#xff0c;哪些地方用动态路由&#xff0c;说说他们的区别 4.在数据包在二层交换机中是如何转发的 5.两个三层交换机如何进行通信 6.trunk和access模式区别 7.对http协议的了解&#xff08;https&a…

利用浏览器录屏

以下内容参考自网络 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title></title> </head> <body> <div class"left"> <di…

Spring Boot教程之五:在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序

在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序 IntelliJ IDEA 是一个用 Java 编写的集成开发环境 (IDE)。它用于开发计算机软件。此 IDE 由 Jetbrains 开发&#xff0c;提供 Apache 2 许可社区版和商业版。它是一种智能的上下文感知 IDE&#xff0c;可用于在各种应用程序…

spring循环依赖问题

这里写自定义目录标题 什么是循环依赖循环依赖是个问题吗Bean的创建过程如何解决循环依赖问题为什么需要singletonFactories三级缓存机制三级缓存的作用 什么是循环依赖 很简单&#xff0c;就是A对象依赖了B对象&#xff0c;B对象依赖了A对象 循环依赖是个问题吗 如果不考虑…

JavaScript将至

JS是什么&#xff1f; 是一种运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;实现人机交互效果 作用捏&#xff1f; 网页特效 (监听用户的一些行为让网页作出对应的反馈) 表单验证 (针对表单数据的合法性进行判断) 数据交互 (获取后台的数据, 渲染到前…

C++中定义类型名的方法

什么是 C 中的类型别名和 using 声明&#xff1f; 类型别名与using都是为了提高代码的可读性。 有两种方法可以定义类型别名 一种是使用关键字typedef起别名使用别名声明来定义类型的别名&#xff0c;即使用using. typedef 关键字typedef作为声明语句中的基本数据类型的一…

小程序-基于java+SpringBoot+Vue的流浪动物救助小程序设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…