当前位置: 首页 > news >正文

cnn突破一(先搞定三层反馈神经网络bpnet,c#实现)

惦记cnn很久了,一直搞机器视觉,走不出来,现在megauging已经实现,说明书也写了不少,该突破的突破了,该改进的也改进了,一个心病治好了,有空把人工智能在机器视觉上的延伸,补一补。自己也是一直认为,人工智能是在机器视觉上发展起来的,所以做这些事情,也是顺理成章。

前头有几篇自己研究bpnet的资料,不成气候,现在可以补齐。

后面的突破,那些个前面bpnet的公式推导仍然是必不可少,我这里就省略了。

网上看到有c++手写数字识别(基于mnist数据集),顺便翻译成c#,但没有成功,直觉上估计是自己在翻译二维数组过程中有问题,因为数学的推导,我已经反复核对过了!

c++有兴趣的可以参考:利用c++编写bp神经网络实现手写数字识别详解 - AlphaInf - 博客园

后来发现,直觉不对,二维数组没错,错了两处:

1,c++和c#的random函数使用不同

2,d【10】这个数组初始化不对

然后,我觉得学习的时间太长,就改进了一下,具体如下:

28*28的图像,使用3*3的高斯核平滑,然后隔行隔列取像素,形成14*14的图像,然后全连接:

196-》128-》10,或者196-》80-》10,训练结果都很好,自己要求不很高,达到95分就行。

下面是自己的c#代码:

  double learnRate = 0.2f; //学习率 
        int n = 196; //输入层点个数 
        int p = 128; //隐藏层节点个数 
        int q = 10; //输出层节点个数 

        //与推导公式保持一致 
        //double x[n],hi[p],ho[p],yi[q],yo[q],d[q];
        double[] xI = new double[14*14];
        double[] hI = new double[128];
        double[] hO = new double[128];

        double[] yi = new double[10];
        double[] yO = new double[10];
        //所训练的网络,采用两个矩阵表示 
        double[,] w1 = new double[196, 128];
        double[,] w2 = new double[128, 10];

  void init()
        {
            Random ran = new Random();
          
            for (int i = 0; i < n; i++)
                for (int j = 0; j < p; j++)
                {
                 
                    //  w1[i, j] = 0.1;
                 

                     w1[i,j]  = ran.Next(-100, 100)/100f;
                  //  w1[i][j] = ran.Next(0, 65535) % 10 / 5f - 1;
                }
            //zhege zhengfu yi zhijian henmiao20240912
           
            for (int i = 0; i < p; i++)
                for (int j = 0; j < q; j++)
                {
                   
                    // w2[i, j] = 0.1;


                    w2[i,j] = ran.Next(-100, 100) / 100f;
                    // w2[i][j] = ran.Next(0, 65535) % 10 / 5f - 1;
                }

}

以上初始化要说明的是:权重都初始化为【-1,1】之间的随机数,图像每个像素除以255,图像每个像素归一化到【0,1】

   int[] d = new int[10];
        int[] last = new int[60000];
        //激活函数 
        public double sigmoid(double x)
        {
            return 1 / (1f + Math.Exp(-x));
        }
        //前向传播函数 
        public void forward()
        {
            //计算hi前需要对其进行清空 
            //  memset(hi, 0, sizeof(hi));
            hI = new double[128];
            //通过w1计算输入层-隐藏层输入节点 
            for (int i = 0; i < n; i++)//196
                for (int j = 0; j < p; j++)//128

                    hI[j] += xI[i] * w1[i,j];

            //通过激活函数对隐藏层进行计算 
            for (int i = 0; i < p; i++)
                //hO[i] = sigmoid(hI[i]+bh[i]);
                hO[i] = sigmoid(hI[i] );
            计算yi前需要对其进行清空 
            //memset(yi, 0, sizeof(yi));
            yi = new double[10];
            //通过w2计算隐藏层-输出层
            for (int i = 0; i < p; i++)
                for (int j = 0; j < q; j++)

                    yi[j] += hO[i] * w2[i,j];

            //通过激活函数求yo
            for (int i = 0; i < q; i++)
                //yO[i] = sigmoid(yi[i]+by[i]);
                yO[i] = sigmoid(yi[i] );
        }
        //判断输出的答案是多少 
        int getAns()
        {
            int ans = 0;
            for (int i = 1; i < q; i++)
                if (yO[i] > yO[ans]) ans = i;
            return ans;
        }

下面是训练函数:

  void train(int cas)
        {
           
      
            xI = hello[cas];

         
            int num = labels[cas];
            d = new int[10]; 
            d[num] = 1;
           

            forward();
            int ans = getAns();
            if (num == ans)
                last[cas] = 1;
            back();
        }

上面训练函数中xI = hello[cas];来自下面对mnist数据集的解析:高斯化和归一化都在里头:

   double[][] hello = new double[60000][];
        void ReadMnistImages(string filePath)
        {
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            using (BinaryReader reader = new BinaryReader(fileStream))
            {
                // 跳过文件头的前16个字节
                reader.ReadBytes(16);
                int h = 28;
                int w = 28;
                while (fileStream.Position < fileStream.Length)
                {
                    byte[] image = reader.ReadBytes(28 * 28); // MNIST图像大小为28x28
                    处理图像数据
                    byte[] showoutput = new byte[28 * 28];
                    //Blur(image, showoutput, 28, 28, 5);
                    ...

                    for (int j = 1; j < (h - 1); j++)
                    {
                        for (int i = 1; i < (w - 1); i++)
                        {
                            int n0 = (j * w + i);
                            int wo = (image[n0 - w - 1] + 2 * image[n0 - w] + image[n0 - w + 1] +
                                                    2 * image[n0 - 1] + 4 * image[n0] + 2 * image[n0 + 1] +
                                                    image[n0 + w - 1] + 2 * image[n0 + w] + image[n0 + w + 1]);//未作除以16
                            showoutput[n0] = (byte)(wo >> 4);//完成除以16
                        }
                    }

                 
                    byte[] showoutput14 = new byte[14 * 14];
                    int k = 0;
                    for (int j = 1; j < 28; j += 2)
                    {
                        for (int i = 1; i < 28; i += 2)
                        {
                            int nn = j * 28 + i;
                            showoutput14[k] = showoutput[nn];
                           
                            k++;

                        }
                    }
                    gaoshoutuxiang196.Add(showoutput14);
                }
             //while循环完成60000图片的读取和高斯处理

//下面for循环完成60000图片在【0,1】的归一化

                for (int xx = 0; xx < 60000; xx++)
                {
                    hello[xx] = new double[196];
                    for (int i = 0; i < 196; i++)
                    {
                        hello[xx][i] = gaoshoutuxiang196[xx][i] / 255f;
                    }
                    
                }
            }
        }

下面是反传播back()函数:

 public double dsigmoid(double x)
        {
            return x * (1 - x);
        }
        //反向传播函数 
        void back()
        {
            //对w2进行更新 
            for (int i = 0; i < p; i++)//128
                for (int j = 0; j < q; j++)//10
                {
                  
                    double delta = (yO[j] - d[j]) * dsigmoid(yO[j]) ;//图像28*28是ling,则标签是0,d[]={1,0,0,0,0,0,0,0,0,0};图像28*28是wu,则标签是5,d[]={0,0,0,0,0,1,0,0,0,0}
                    w2[i, j] -= delta * learnRate * hO[i];
          
                }

            //对反向传播进行预处理 
           
            double[] W2 = new double[p];//p=128
            //    memset(W2,0,sizeof(W2));
            for (int j = 0; j < p; j++)
                for (int k = 0; k < q; k++)
                    W2[j] += (yO[k] - d[k]) * dsigmoid(yO[k]) * w2[j,k];//图像28*28是壹,则标签是1,d[]={0,1,0,0,0,0,0,0,0,0};图像28*28是jiu,则标签是9,d[]={0,0,0,0,0,0,0,0,0,1}

            //对w1进行更新
            for (int i = 0; i < n; i++)//196
                for (int j = 0; j < p; j++)
                {
                    double delta = dsigmoid(hO[j]) * xI[i] * W2[j];
                    w1[i,j] -= delta * learnRate;
                }
         
        }

最后就是调用执行,学习训练60000万次,以及把最后十次结果显示出来:

    private void button1trainMnist_Click(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
         
            for (int cas = 0; cas < 60000; cas++)
            {
                train(cas);
            }
       
            int P = 100;
       
            int he = 59000;
            for (int n = 0; n < 9; n++)
            {
                int hh = 0;
                for (int i = 0; i < P; i++)
                {
                    hh += last[he + i];

                }
                textBox42对比信息.Text += he.ToString() + "," + hh.ToString() + "\r\n";
                he += 100;
            }
           
            TimeSpan sp = DateTime.Now - dt;
            textBox44.Text = sp.ToString();
        }

c++程序和我这个程序都没有引入bias,其实正如c++作者所言,97分

后来我引入了bias【】,觉得正规一些,发现,反而不如这个程序!

原因是,bias【】更新计算对了,但写的地方不对导致学习成绩下降成绩,这是一个很隐蔽的错误,接下来,我会讲到,很久才发现bug,很崩溃,一度不想用bias【】!

今天先到这里!

相关文章:

cnn突破一(先搞定三层反馈神经网络bpnet,c#实现)

惦记cnn很久了&#xff0c;一直搞机器视觉&#xff0c;走不出来&#xff0c;现在megauging已经实现&#xff0c;说明书也写了不少&#xff0c;该突破的突破了&#xff0c;该改进的也改进了&#xff0c;一个心病治好了&#xff0c;有空把人工智能在机器视觉上的延伸&#xff0c;…...

如何创建一个docker,给它命名,且下次重新打开它

1.创建一个新的docker并同时命名 docker run -it --name one ubuntu:18.04 /bin/bash 这时候我们已经创建了一个docker,并且命名为"one" 2.关闭当前docker exit 3.这时docker已经终止了&#xff0c;我们需要使用它要重新启动 docker start one 4.现在可以重新打…...

【D3.js in Action 3 精译_025】3.4 让 D3 数据适应屏幕(中)—— 线性比例尺的用法

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…...

Python的多线程与多进程:并发编程基础与实战

随着计算机硬件的不断发展,现代计算机通常配备多核处理器,使得在程序中同时处理多个任务成为可能。并发编程是提升程序性能、充分利用多核处理器能力的重要技术之一。在Python中,并发编程的实现主要包括多线程、多进程以及异步编程(如asyncio)。然而,由于Python的全局解释…...

HarmonyOS Next应用开发——响应式布局之媒体查询

响应式布局之媒体查询 媒体查询作为响应式设计的核心&#xff0c;在移动设备上应用十分广泛。媒体查询可根据不同设备类型或同设备不同状态修改应用的样式&#xff0c;常用于多屏幕的应用适配。媒体查询常用于下面两种场景&#xff1a; 针对设备和应用的属性信息&#xff08;…...

240 搜索二维矩阵 II

解题思路&#xff1a; \qquad 解这道题最重要的是如何利用从左到右、从上到下为升序的性质&#xff0c;快速找到目标元素。 \qquad 如果从左上角开始查找&#xff0c;如果当前matrix[i][[j] < target&#xff0c;可以向右、向下扩展元素都是升序&#xff0c;但选择哪个方向…...

jenkins微服务

如果vim进去某个文件里&#xff0c;可以按键盘的向下键查阅其它部分 记得每天备份虚拟机的项目 一.在linux安装jenkins 1.上传文件 我们采用安装包的方式安装。 先用SShclient在/usr/local/下创建jenkins文件夹&#xff0c;然后向其中导入两个包 2.安装jenkins 再在控制…...

【Kotlin基于selenium实现自动化测试】初识selenium以及搭建项目基本骨架(1)

导读大纲 1.1 Java: Selenium 首选语言1.2 配置一个强大的开发环境 1.1 Java: Selenium 首选语言 Java 是开发人员和测试人员进行自动化 Web 测试的首选 Java 和 Selenium 之间的协同作用受到各种因素的驱动,从而提高它们的有效性 为什么Java经常被认为是Selenium的首选语言 广…...

汽车追尾为什么是后车的责任?

简单点说&#xff1a;因为人后面没有长眼睛。 结论 在汽车追尾事故中&#xff0c;通常情况下后车被认为是责任方的原因在于交通法规对驾驶安全标准的约定和实践中的责任识别原则。虽然追尾事故常见地被归责于后车&#xff0c;但具体判断并不是绝对的&#xff0c;仍需综合多种…...

[运维]4.bookinfo无法部署的问题

为了拉取镜像&#xff0c;搭建了阿里云镜像仓库&#xff0c;教程见&#xff1a;K8S中基于NFS-Subdir-External-Provisioner存储组件实现的StorageClass-CSDN博客 但是bookinfo的ratings和productpage无法运行&#xff0c;部署后显示crashLoopBackOff [rootmaster ~]# kubectl…...

ACT调试pycharm报错

在运行ACT 代码时&#xff0c;根据官方readme使用命令行需要在wandb选择的时候输入3 但是&#xff0c;使用pycharm运行的时候会报错 wandb.errors.UsageError: api_key not configured (no-tty). call wandb.login(key[your_api_key]) 网上搜索都是说要注册什么key&#xf…...

记一次控件提升后,运行却不显示的Bug

.h文件 #ifndef VOLUMETOOLBTN_H #define VOLUMETOOLBTN_H#include <QToolButton> #include <memory>class VolumeToolBtn : public QToolButton { Q_OBJECTpublic:explicit VolumeToolBtn(QWidget *parent nullptr);~VolumeToolBtn() override;void initUi(); p…...

关于深度学习torch的环境配置问题

已经下好了torch在虚拟环境中&#xff0c;结果在ipynb文件中无法运行 后来在终端直接用python语句编译 发现没有问题 在编辑测试py文件 发现runcode有问题 原来是插件默认base环境 具体操作参考VS Code插件Code Runner使用python虚拟环境_coderunner怎么在虚拟环境中使用-CSD…...

Linux工具的使用——yum和vim的理解和使用

目录 linux工具的使用1.linux软件包管理器yum1.1yum的背景了解关于yum的拓展 1.2yum的使用 2.Linux编辑器-vim使用2.1vim的基本概念2.2vim的基本操作2.3命令模式命令集2.3.1关于光标的命令&#xff1a;2.3.2关于复制粘贴的命令2.3.3关于删除的命令2.3.4关于文本编辑的命令 2.4插…...

websockets库使用(基于Python)

主要参考资料&#xff1a; 【Python】websockets库的介绍及用法: https://blog.csdn.net/qq_53871375/article/details/135920231 python模块websockets&#xff0c;浏览器与服务器之间的双向通信: https://blog.csdn.net/randy521520/article/details/134752051 目录 websocke…...

Electron 主进程与渲染进程、预加载preload.js

在 Electron 中&#xff0c;主要控制两类进程&#xff1a; 主进程 、 渲染进程 。 Electron 应⽤的结构如下图&#xff1a; 如果需要更深入的了解electron进程&#xff0c;可以访问官网 流程模型 文档。 主进程 每个 Electron 应用都有一个单一的主进程&#xff0c;作为应用…...

鸿蒙harmonyos next纯flutter开发环境搭建

公司app是用纯flutter开发的&#xff0c;目前支持android和iOS&#xff0c;后续估计也会支持鸿蒙harmonyos。目前谷歌flutter并没有支持咱们国产手机操作系统鸿蒙harmonyos&#xff0c;于是乎国内有个叫OpenHarmony-SIG的组织&#xff0c;去做了鸿蒙harmonyos适配flutter开发的…...

【学习资源】人在环路的机器学习

说明&#xff1a;本文图片和内容来源 Human-in-the-Loop Machine Learning Human-in-the-Loop Machine Learning Active learning and annotation for human-centered AI by Robert (Munro) Monarch, June 2021 介绍Human-in-the-Loop的目标&#xff0c;学习过程&#xff0c…...

计算机毕业设计 基于Python的热门微博数据可视化分析系统的设计与实现 Python+Django+Vue 可视化大屏 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

031集——文本文件按空格分行——C#学习笔记

如下图&#xff0c;读取每行文本&#xff0c;每行文本再按空格分开读取一个字符串&#xff0c;输出到另一个文本&#xff1a; CAD环境下&#xff0c;代码如下&#xff1a; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; using System; using Sys…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...