极简单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++)

wcnn[xx] = new double[4];

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

wcnn的偏差[xx] = new double[4];

a0[0]= a1;

a0[1]= a2;

a0[2]= a3;

a0[3]= a4;

a0[4]= a5;

a0[5]= a6;

a0[6]= a7;

a0[7]= a8;

a0[8] = a9;

}

double[] a0 = new double[9];

double[] aI = new double[4];

double aII = 0;

double[] z1 = new double[4];

double z2 = 0;

double[][] wcnn = new double[2][];// wcnn[0]第一层卷积核, wcnn[1]第二层卷积核

double[][] wcnn的偏差 = new double[2][];

double o = 0;

public void forward()

{

//1,第一层卷积

z1[0] = a0[0] * wcnn[0][0] + a0[1] * wcnn[0][1] + a0[3]* wcnn[0][2] + a0[4]* wcnn[0][3];//1,2,4,5

z1[1] = a0[1] * wcnn[0][0] + a0[2] * wcnn[0][1] + a0[4] * wcnn[0][2] + a0[5] * wcnn[0][3];//2,3,5,6

z1[2] = a0[3] * wcnn[0][0] + a0[4] * wcnn[0][1] + a0[6] * wcnn[0][2] + a0[7] * wcnn[0][3];//4,5,7,8

z1[3] = a0[4] * wcnn[0][0] + a0[5] * wcnn[0][1] + a0[7] * wcnn[0][2] + a0[8] * wcnn[0][3];//5,6,8,9

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

aI[0] = sigmoid(z1[0]);

aI[1] = sigmoid(z1[1]);

aI[2] = sigmoid(z1[2]);

aI[3] = sigmoid(z1[3]);

//3,第三层

z2 = aI[0] * wcnn[1][0] + aI[1] * wcnn[1][1] + aI[2]* wcnn[1][2] + aI[3] * wcnn[1][3] ;

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的偏差[1][0] = E偏差zII * aI[0];//e偏差z2*zII偏导w2【11】

wcnn的偏差[1][1] = E偏差zII * aI[1];//e偏差z2*zII偏导w2【12】

wcnn的偏差[1][2] = E偏差zII * aI[2];//e偏差z2*zII偏导w2【21】

wcnn的偏差[1][3] = E偏差zII * aI[3];//e偏差z2*zII偏导w2【22】

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

double delta11 = E偏差zII * wcnn[1][0]*dsigmoid(aI[0]);

double delta12 = E偏差zII * wcnn[1][1]*dsigmoid(aI[1]);

double delta21 = E偏差zII * wcnn[1][2]*dsigmoid(aI[2]);

double delta22 = E偏差zII * wcnn[1][3] * dsigmoid(aI[3]);

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

wcnn的偏差[0][0] = delta11*a0[0] + delta12*a0[1] + delta21*a0[3] + delta22*a0[4];//w1的偏差

wcnn的偏差[0][1] = delta11*a0[1] + delta12*a0[2] + delta21*a0[4] + delta22*a0[5];//w2的偏差

wcnn的偏差[0][2] = delta11*a0[3] + delta12*a0[4] + delta21*a0[6] + delta22*a0[7];//w3的偏差

wcnn的偏差[0][3] = delta11*a0[4] + delta12*a0[5] + delta21*a0[7] + delta22*a0[8];//w4的偏差

//更新

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

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

{

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

}

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

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

{

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

}

}

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);

a0[0] = a1;

a0[1] = a2;

a0[2] = a3;

a0[3] = a4;

a0[4] = a5;

a0[5] = a6;

a0[6] = a7;

a0[7] = a8;

a0[8] = a9;

// layer.map[i].bias = randomNormalDistribution() / Math.Sqrt(9 / 2f);

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

{

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

wcnn的偏差[1][xx] = 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);

a0[0] = a1;

a0[1] = a2;

a0[2] = a3;

a0[3] = a4;

a0[4] = a5;

a0[5] = a6;

a0[6] = a7;

a0[7] = a8;

a0[8] = a9;

forward();

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

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

}

}

}

相关推荐
冷yan~2 小时前
OpenAI Codex CLI 完全指南:AI 编程助手的终端革命
人工智能·ai·ai编程
菜鸟‍2 小时前
【论文学习】通过编辑习得分数函数实现扩散模型中的图像隐藏
人工智能·学习·机器学习
AKAMAI2 小时前
无服务器计算架构的优势
人工智能·云计算
阿星AI工作室2 小时前
gemini3手势互动圣诞树保姆级教程来了!附提示词
前端·人工智能
刘一说2 小时前
时空大数据与AI融合:重塑物理世界的智能中枢
大数据·人工智能·gis
月亮月亮要去太阳2 小时前
基于机器学习的糖尿病预测
人工智能·机器学习
Oflycomm2 小时前
LitePoint 2025:以 Wi-Fi 8 与光通信测试推动下一代无线创新
人工智能·wifi模块·wifi7模块
机器之心2 小时前
「豆包手机」为何能靠超级Agent火遍全网,我们听听AI学者们怎么说
人工智能·openai
monster000w2 小时前
大模型微调过程
人工智能·深度学习·算法·计算机视觉·信息与通信
机器之心2 小时前
一手实测 | 智谱AutoGLM重磅开源: AI手机的「安卓时刻」正式到来
人工智能·openai