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

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)}]");
            }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IT服务团队建设与管理

在 IT 服务团队中&#xff0c;需要明确各种角色。例如系统管理员负责服务器和网络设备的维护与管理&#xff1b;软件工程师专注于软件的开发、测试和维护&#xff1b;运维工程师则保障系统的稳定运行&#xff0c;包括监控、故障排除等。通过清晰地定义每个角色的职责&#xff0…

初学 flutter 问题记录

windows搭建flutter运行环境 一、运行 flutter doctor遇到的问题 Xcmdline-tools component is missingRun path/to/sdkmanager --install "cmdline-tools;latest"See https://developer.android.com/studio/command-line for more details.1&#xff09;cmdline-to…

神经网络(系统性学习二):单层神经网络(感知机)

此前篇章&#xff1a; 神经网络中常用的激活函数 神经网络&#xff08;系统性学习一&#xff09;&#xff1a;入门篇 单层神经网络&#xff08;又叫感知机&#xff09; 单层网络是最简单的全连接神经网络&#xff0c;它仅有输入层和输出层&#xff0c;没有隐藏层。即&#x…

H.265流媒体播放器EasyPlayer.js播放器提示MSE不支持H.265解码可能的原因

随着人工智能和机器学习技术的应用&#xff0c;流媒体播放器将变得更加智能&#xff0c;能够根据用户行为和偏好提供个性化的内容推荐。总体而言&#xff0c;流媒体播放器的未来发展将更加注重技术创新和用户互动&#xff0c;以适应不断变化的市场需求和技术进步。 提示MSE不支…

MySQL原理简介—6.简单的生产优化案例

大纲 1.MySQL日志的顺序写和数据文件的随机读指标 2.Linux存储系统软件层原理及IO调度优化原理 3.数据库服务器使用的RAID存储架构介绍 4.数据库Too many connections故障定位 1.MySQL日志的顺序写和数据文件的随机读指标 (1)磁盘随机读操作 (2)磁盘顺序写操作 (1)磁盘随…

svn 崩溃、 cleanup失败 怎么办

在使用svn的过程中&#xff0c;可能出现整个svn崩溃&#xff0c; 例如cleanup 失败的情况&#xff0c;类似于 这时可以下载本贴资源文件并解压。 或者直接访问网站 SQLite Download Page 进行下载 解压后得到 sqlite3.exe 放到发生问题的svn根目录的.svn路径下 右键呼出pow…

前后端分离,解决vue+axios跨域和proxyTable不生效等问题

看到我这篇文章前可能你以前看过很多类似的文章。至少我是这样的&#xff0c;因为一直没有很好的解决问题。 正文 当我们通过webstorm等IDE开发工具启动项目的时候&#xff0c;通过命令控制台可以观察到启动项目的命令 如下&#xff1a; webpack-dev-server --inline --prog…

在win10环境部署opengauss数据库(包含各种可能遇到的问题解决)

适用于windows环境下通过docker desktop实现opengauss部署&#xff0c;请审题。 文章目录 前言一、部署适合deskdocker的环境二、安装opengauss数据库1.配置docker镜像源2.拉取镜像源 总结 前言 注意事项&#xff1a;后面docker拉取镜像源最好电脑有科学上网工具如果没有科学上…

Java开发经验——Spring Test 常见错误

摘要 本文详细介绍了Java开发中Spring Test的常见错误和解决方案。文章首先概述了Spring中进行单元测试的多种方法&#xff0c;包括使用JUnit和Spring Boot Test进行集成测试&#xff0c;以及Mockito进行单元测试。接着&#xff0c;文章分析了Spring资源文件扫描不到的问题&am…

2024年亚太地区数学建模大赛D题-探索量子加速人工智能的前沿领域

量子计算在解决复杂问题和处理大规模数据集方面具有巨大的潜力&#xff0c;远远超过了经典计算机的能力。当与人工智能&#xff08;AI&#xff09;集成时&#xff0c;量子计算可以带来革命性的突破。它的并行处理能力能够在更短的时间内解决更复杂的问题&#xff0c;这对优化和…

基于 RBF 神经网络整定的 PID 控制

基于 RBF 神经网络整定的 PID 控制 是结合了传统 PID 控制和 RBF&#xff08;径向基函数&#xff09;神经网络的自适应控制方法。在这种方法中&#xff0c;RBF 神经网络用于自适应地调整 PID 控制器的增益&#xff08;比例增益 KpK_pKp​&#xff0c;积分增益 KiK_iKi​ 和微分…

空间注意力网络的性能优化与多维评估

在本文中&#xff0c;首先分析空间注意力网络&#xff08;Spatial Attention Neural Network&#xff09;在五个不同数据集上的训练结果。这些数据集包括Daily_and_Sports_Activities、WISDM、UCI-HAR、PAMAP2和OPPORTUNITY。通过对比这些结果&#xff0c;我们可以深入理解空间…

Linux——1_系统的延迟任务及定时任务

系统的延迟任务及定时任务 在系统中我们的维护工作大多数时在服务器行对闲置时进行 我们需要用延迟任务来解决自动进行的一次性的维护 延迟任务时一次性的&#xff0c;不会重复执行 当延迟任务产生输出后&#xff0c;这些输出会以邮件的形式发送给延迟任务发起者 在RHEL9中…

【数据结构】—— 线索二叉树

引入 我们现在提倡节约型杜会&#xff0c; 一切都应该节约为本。对待我们的程序当然也不例外&#xff0c;能不浪费的时间或空间&#xff0c;都应该考虑节省。我们再观察团下图的二叉树&#xff08;链式存储结构)&#xff0c;会发现指针域并不是都充分的利用了&#xff0c;有许…

NVR管理平台EasyNVR多个NVR同时管理:全方位安防监控视频融合云平台方案

EasyNVR是基于端-边-云一体化架构的安防监控视频融合云平台&#xff0c;具有简单轻量的部署方式与多样的功能&#xff0c;支持多种协议&#xff08;如GB28181、RTSP、Onvif、RTMP&#xff09;和设备类型&#xff08;IPC、NVR等&#xff09;&#xff0c;提供视频直播、录像、回放…

虚幻引擎---初识篇

一、学习途径 虚幻引擎官方文档&#xff1a;https://dev.epicgames.com/documentation/zh-cn/unreal-engine/unreal-engine-5-5-documentation虚幻引擎在线学习平台&#xff1a;https://dev.epicgames.com/community/unreal-engine/learning哔哩哔哩&#xff1a;https://www.b…

汽车HiL测试:利用TS-GNSS模拟器掌握硬件性能的仿真艺术

一、汽车HiL测试的概念 硬件在环&#xff08;Hardware-in-the-Loop&#xff0c;简称HiL&#xff09;仿真测试&#xff0c;是模型基于设计&#xff08;Model-Based Design&#xff0c;简称MBD&#xff09;验证流程中的一个关键环节。该步骤至关重要&#xff0c;因为它整合了实际…

C++编程库与框架实战——sqlite3数据库

一,SQLite数据库简介 SQLite是可以实现类似于关系型数据库中各种操作的事务性SQL数据库引擎。 SQLite可以为应用程序提供存储于本地的嵌入式数据库,帮助应用程序实现轻量级的数据存储。 SQLite是一个库文件,并不是单独的进程,它可以静态或动态链接到C++应用程序中,然后…

STM32F10x 定时器

使用定时器实现&#xff1a;B5 E5的开关 添加相关的.h路径文件 添加相关的.c配置文件 led.h文件 用于声明LED函数 #ifndef __LED_H //没有定义__LED_H #define __LED_H //就定义__LED_H #define LED1_ON GPIO_ResetBits(GPIOB,GPIO_Pin_5) #defi…

PyQt6+pyqtgraph折线图绘制显示

1、实现效果 2、环境&#xff1a; 确认已经安装pyqtgraph的模块&#xff0c;如果没有安装&#xff0c;使用命令安装&#xff1a; pip install pyqtgraph 3、代码实现&#xff1a; 绘制折线函数&#xff1a; import sys import random from PySide6.QtWidgets import QAppl…