极简单cnn编程测试

我们前面已经推导了极简的cnn数学流程,这里编程测试一下,从极简bpnet改过来,c#版本!

我们用九宫格"X",来训练1万次,然后测试,看看效果:

测个:工

然后,全1

测个,0做的x,不错,识别到了!有意思!

我们再测试一个:0(1做的圈)

再测:x

效果还不错!

完整代码如下:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace 识别x第二版//及其简单的bpnet

{

public partial class Form1 : Form

{

//九宫格x,即

//1 0 1

//0 1 0

//1 0 1

double 常数a = 0.02;

float a1 = 1;

float a2 = 0;

float a3 = 1;

float a4 = 0;

float a5 = 1;

float a6 = 0;

float a7 = 1;

float a8 = 0;

float a9 = 1;

public double sigmoid(double x)

{

return 1 / (1.0 + Math.Exp(-x));

}

public double dsigmoid(double x)

{

return x * (1 - x);

}

public Form1()

{

InitializeComponent();

for (int xx = 0; xx < 2; xx++)

wcnnxx = new double4;

for (int xx = 0; xx < 2; xx++)

wcnn的偏差xx = new double4;

a00= a1;

a01= a2;

a02= a3;

a03= a4;

a04= a5;

a05= a6;

a06= a7;

a07= a8;

a08 = a9;

}

double\[\] a0 = new double9;

double\[\] aI = new double4;

double aII = 0;

double\[\] z1 = new double4;

double z2 = 0;

double\[\]\[\] wcnn = new double2\[\];// wcnn0第一层卷积核, wcnn1第二层卷积核

double\[\]\[\] wcnn的偏差 = new double2\[\];

double o = 0;

public void forward()

{

//1,第一层卷积

z10 = a00 * wcnn00 + a01 * wcnn01 + a03* wcnn02 + a04* wcnn03;//1,2,4,5

z11 = a01 * wcnn00 + a02 * wcnn01 + a04 * wcnn02 + a05 * wcnn03;//2,3,5,6

z12 = a03 * wcnn00 + a04 * wcnn01 + a06 * wcnn02 + a07 * wcnn03;//4,5,7,8

z13 = a04 * wcnn00 + a05 * wcnn01 + a07 * wcnn02 + a08 * wcnn03;//5,6,8,9

//2, z1->aI,第二层输入

aI0 = sigmoid(z10);

aI1 = sigmoid(z11);

aI2 = sigmoid(z12);

aI3 = sigmoid(z13);

//3,第三层

z2 = aI0 * wcnn10 + aI1 * wcnn11 + aI2* wcnn12 + aI3 * wcnn13 ;

aII = sigmoid(z2);

o = aII;

//4

double 偏差 = (1 - o) * (1 - o) * 1 / 2.0;

}

double E偏差zII = 0;

public void back()

{

//1,计算偏差,e/a2的偏导,a/z2偏导

E偏差zII = -(1 - o) * dsigmoid(o);//delta

//2,计算w【1】的偏导,第二层卷积核

wcnn的偏差10 = E偏差zII * aI0;//e偏差z2*zII偏导w2【11】

wcnn的偏差11 = E偏差zII * aI1;//e偏差z2*zII偏导w2【12】

wcnn的偏差12 = E偏差zII * aI2;//e偏差z2*zII偏导w2【21】

wcnn的偏差13 = E偏差zII * aI3;//e偏差z2*zII偏导w2【22】

//e对z1的偏导=e对a1的偏导*a1对z1的偏导

double delta11 = E偏差zII * wcnn10*dsigmoid(aI0);

double delta12 = E偏差zII * wcnn11*dsigmoid(aI1);

double delta21 = E偏差zII * wcnn12*dsigmoid(aI2);

double delta22 = E偏差zII * wcnn13 * dsigmoid(aI3);

//3,计算w【0】的偏导,第一层卷积核

wcnn的偏差00 = delta11*a00 + delta12*a01 + delta21*a03 + delta22*a04;//w1的偏差

wcnn的偏差01 = delta11*a01 + delta12*a02 + delta21*a04 + delta22*a05;//w2的偏差

wcnn的偏差02 = delta11*a03 + delta12*a04 + delta21*a06 + delta22*a07;//w3的偏差

wcnn的偏差03 = delta11*a04 + delta12*a05 + delta21*a07 + delta22*a08;//w4的偏差

//更新

//w1,第二层的一个卷积核

for (int i = 0; i < 4; i++)

{

wcnn1i = wcnn1i - 常数a * wcnn的偏差1i;

}

//w0,第一层的一个卷积核

for (int i = 0; i < 4; i++)

{

wcnn0i = wcnn0i - 常数a * wcnn的偏差0i;

}

}

private void button1_Click(object sender, EventArgs e)//训练

{

for (int i = 0; i < 10000; i++)

{

forward();

back();

}

double last偏差 = (1 - o) * (1 - o) * 1 / 2.0;

textBox10.Text = last偏差.ToString();

button1.Enabled = false;

MessageBox.Show("请换图测试!");

}

Random ran = new Random();

public double randomNormalDistribution()

{

double u = 0.0, v = 0.0, w = 0.0, c = 0.0;

do

{

//获得两个(-1,1)的独立随机变量

u = ran.NextDouble() * 2 - 1.0;

v = ran.NextDouble() * 2 - 1.0;

w = u * u + v * v;

} while (w == 0.0 || w >= 1.0);

//这里就是 Box-Muller转换

c = Math.Sqrt((-2 * Math.Log(w)) / w);

//返回2个标准正态分布的随机数,封装进一个数组返回

//当然,因为这个函数运行较快,也可以扔掉一个

//return u\*c,v\*c;

//double u1 = ran.NextDouble();

//double u2 = ran.NextDouble();

//double z = Math.Sqrt(-2 * Math.Log(u1)) * Math.Sin(2 * Math.PI * u2);

//return z;

return u * c;

}

private void button2init_Click(object sender, EventArgs e)

{

a1 =(float)Convert.ToDouble(textBox1.Text);

a2 = (float)Convert.ToDouble(textBox2.Text);

a3 = (float)Convert.ToDouble(textBox3.Text);

a4 = (float)Convert.ToDouble(textBox4.Text);

a5 = (float)Convert.ToDouble(textBox5.Text);

a6 = (float)Convert.ToDouble(textBox6.Text);

a7 = (float)Convert.ToDouble(textBox7.Text);

a8 = (float)Convert.ToDouble(textBox8.Text);

a9 = (float)Convert.ToDouble(textBox9.Text);

a00 = a1;

a01 = a2;

a02 = a3;

a03 = a4;

a04 = a5;

a05 = a6;

a06 = a7;

a07 = a8;

a08 = a9;

// layer.mapi.bias = randomNormalDistribution() / Math.Sqrt(9 / 2f);

for (int xx = 0; xx < 4; xx++)

{

wcnn的偏差0xx = randomNormalDistribution() / Math.Sqrt(9 / 2f);

wcnn的偏差1xx = randomNormalDistribution() / Math.Sqrt(4 / 2f);

}

button2init.Enabled = false;

}

private void button2Test_Click(object sender, EventArgs e)

{

a1 = (float)Convert.ToDouble(textBox1.Text);

a2 = (float)Convert.ToDouble(textBox2.Text);

a3 = (float)Convert.ToDouble(textBox3.Text);

a4 = (float)Convert.ToDouble(textBox4.Text);

a5 = (float)Convert.ToDouble(textBox5.Text);

a6 = (float)Convert.ToDouble(textBox6.Text);

a7 = (float)Convert.ToDouble(textBox7.Text);

a8 = (float)Convert.ToDouble(textBox8.Text);

a9 = (float)Convert.ToDouble(textBox9.Text);

a00 = a1;

a01 = a2;

a02 = a3;

a03 = a4;

a04 = a5;

a05 = a6;

a06 = a7;

a07 = a8;

a08 = a9;

forward();

double last偏差 = (1 - o) * (1 - o) * 1 / 2.0;

MessageBox.Show(last偏差.ToString());

}

}

}

相关推荐
冬奇Lab15 小时前
Workflow 系列(03):状态管理——持久化、幂等性与版本绑定
人工智能·工作流引擎
冬奇Lab15 小时前
每日一个开源项目(第146篇):openpilot - 开源自动驾驶辅助系统,曾在 Consumer Reports 评测中超过特斯拉 Autopilot
人工智能·开源·自动驾驶
吴佳浩17 小时前
AI 工程师知识地图:模型格式、框架、部署工具一次讲明白
人工智能·aigc·ai编程
IT_陈寒17 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
码农胖大海17 小时前
AI额度不够用的解决方案
人工智能
后端小肥肠18 小时前
小红书虚拟商品怎么做?我先用 Skill 跑通了壁纸品类
人工智能·aigc·agent
feiyu_gao18 小时前
从零搭建个人 AI 工作台:一个管理者的 3 个月实验
人工智能·aigc·团队管理
程序员cxuan19 小时前
一句话,让你用上 GPT-5.6
人工智能·后端·程序员
机器之心19 小时前
AI圈刚开始谈Loop Engineering,两位95后博士已经盯上了人类闭环数据
人工智能·openai