cnn突破三

cnn,是卷积核神经网络,前面讲的没有卷积核,所以这里,我们在前面三层bpnet网络的基础上,增加卷积核试一试!

所有的启发来自,28*28变14*14的那个常用的高斯卷积核,我们前面的网络实际是:28*28->3*3卷积后,隔行隔列抠图(相当于池化)->14*14->128->10

下面,我们就是仿照上面,我们不再使用高斯核,而是让他自己产生四个卷积核(看看是什么鬼!):

即14*14->4*10*10->4*5*5->80->10,结论是:

改成14*14*4-10*10*4-5*5*4-80-10,学习6万次,均分大于90,小于95,我们先看结果:

我们训练学习了12万次,达到95分,用鼠标画了个2,识别出来了,得分99,不错,说明四个卷积核有了,我们把mnist原图的2,用学到的卷积核处理后的四个图像也有了,太神奇!

下面是c#实现源码,请对比前面三层bpnet网络看:

先初始化了四个卷积核:

double[,] w1cnn = new double[25, 4]; double[,] w12cnn = new double[100, 80];

double[,] w2cnn = new double[80, 10];

//for cnn202409181004

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

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

{

w1cnn[i, j] = ran.Next(-100, 100) / 100f;

}

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

for (int j = 0; j < 80; j++)

{

w12cnn[i, j] = ran.Next(-100, 100) / 100f;

}

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

for (int j = 0; j < 10; j++)

{

w2cnn[i, j] = ran.Next(-100, 100) / 100f;

}

然后,你对比前头的三层网络:forward()函数中增加如下:

forward第一步:14*14的图像用5*5的四个卷积核操作,变成4*10*10

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

for (int j = 0; j < 10; j++)//

{

int l = (i) * 10 + j;

for (int m = 0; m < 5; m++)

for (int n = 0; n < 5; n++)

{

int k = (i + m) * 14 + j + n;

hIcnntemp[l] += xI[k] * w1cnn[m * 5 + n, 0];

hIcnntemp1[l] += xI[k] * w1cnn[m * 5 + n, 1];

hIcnntemp2[l] += xI[k] * w1cnn[m * 5 + n, 2];

hIcnntemp3[l] += xI[k] * w1cnn[m * 5 + n, 3];

}

}

//forward第二步,10*10-》5*5

jilumn.Clear();//forward执行一次,就是换一张图片

jilumn1na.Clear();

jilumn2na.Clear(); jilumn3na.Clear();

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

for (int j = 0; j < 5; j++)//

{

int l = (i) * 5 + j;

double tempb = 0;

Point tempPt = new Point();

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

for (int n = 0; n < 2; n++)//需要记住m,n和序号L,202409181018

{

int k = (i * 2 + m) * 10 + j * 2 + n;

//取最大值

if (hIcnntemp[k] > tempb)

{

tempb = hIcnntemp[k];

tempPt = new Point(n, m);//m是h,n是w,这个要小心用错

}

}

jilumn.Add(tempPt);//25个数据,就有25组m,n,序号一一对应

hIcnn[l] = tempb;//25个数据,通过这个关系,就能找到14*14matrix中去。202409181038

}

上面这段代码要重复三次,一共处理四副图像,即4@10*10-》4@5*5

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

for (int j = 0; j < 5; j++)//

{

int l = (i) * 5 + j;

double tempb = 0;

Point tempPt = new Point();

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

for (int n = 0; n < 2; n++)//需要记住m,n和序号L,202409181018

{

int k = (i * 2 + m) * 10 + j * 2 + n;

// tempb += B1[k] * Wb2c[m * 2 + n, l];//取均值?还是取最大值?

if (hIcnntemp1[k] > tempb)

{

tempb = hIcnntemp1[k];//如果是最大值,核就变得没有意义,back怎么办?202409170727

tempPt = new Point(n, m);//m是h,n是w,这个要小心用错

}

}

// C1[l] = (byte)(tempb/4f);

jilumn1na.Add(tempPt);//25个数据,就有25组m,n,序号一一对应

hIcnn1na[l] = tempb;//25个数据,通过这个关系,就能找到14*14matrix中去。202409181038

}

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

for (int j = 0; j < 5; j++)//

{

int l = (i) * 5 + j;

double tempb = 0;

Point tempPt = new Point();

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

for (int n = 0; n < 2; n++)//需要记住m,n和序号L,202409181018

{

int k = (i * 2 + m) * 10 + j * 2 + n;

// tempb += B1[k] * Wb2c[m * 2 + n, l];//取均值?还是取最大值?

if (hIcnntemp2[k] > tempb)

{

tempb = hIcnntemp2[k];//如果是最大值,核就变得没有意义,back怎么办?202409170727

tempPt = new Point(n, m);//m是h,n是w,这个要小心用错

}

}

// C1[l] = (byte)(tempb/4f);

jilumn2na.Add(tempPt);//25个数据,就有25组m,n,序号一一对应

hIcnn2na[l] = tempb;//25个数据,通过这个关系,就能找到14*14matrix中去。202409181038

}

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

for (int j = 0; j < 5; j++)//

{

int l = (i) * 5 + j;

double tempb = 0;

Point tempPt = new Point();

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

for (int n = 0; n < 2; n++)//需要记住m,n和序号L,202409181018

{

int k = (i * 2 + m) * 10 + j * 2 + n;

// tempb += B1[k] * Wb2c[m * 2 + n, l];//取均值?还是取最大值?

if (hIcnntemp3[k] > tempb)

{

tempb = hIcnntemp3[k];//如果是最大值,核就变得没有意义,back怎么办?202409170727

tempPt = new Point(n, m);//m是h,n是w,这个要小心用错

}

}

// C1[l] = (byte)(tempb/4f);

jilumn3na.Add(tempPt);//25个数据,就有25组m,n,序号一一对应

hIcnn3na[l] = tempb;//25个数据,通过这个关系,就能找到14*14matrix中去。202409181038

}

第三步关于forward,把处理后的图像合并起来,4@5*5=100

hocnnhebing = new double[100];

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

{

hocnnhebing[i] = hocnn[i] = sigmoid(hIcnn[i]);

hocnnhebing[i+25] = hocnn1na[i] = sigmoid(hIcnn1na[i]);

hocnnhebing[i + 50] = sigmoid(hIcnn2na[i]);

hocnnhebing[i + 75] = sigmoid(hIcnn3na[i]);

}

forward第四步,全连接:

//下面开始全连接202409181044

hI2 = new double[80];//

for (int i = 0; i < 100; i++)//

for (int j = 0; j < 80; j++)//

hI2[j] += (hocnnhebing[i]) * w12cnn[i, j];//

//通过激活函数对隐藏层进行计算

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

hO2[i] = sigmoid(hI2[i]);

yicnn = new double[10];

//通过w2计算隐藏层-输出层

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

for (int j = 0; j < 10; j++)

yicnn[j] += hO2[i] * w2cnn[i, j];

//通过激活函数求yo

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

yOcnn[i] = sigmoid(yicnn[i]);

上面就完成了forward()函数。下面再看backward()函数

for (int i = 0; i < 80; i++)//

for (int j = 0; j < 10; j++)//10

{

double delta = (yOcnn[j] - d[j]) * dsigmoid(yOcnn[j]) * hO2[i];

w2cnn[i, j] -= delta * learnRate;

}

double[] W3 = new double[80];//

for (int j = 0; j < 80; j++)//

for (int k = 0; k < 10; k++)//10

W3[j] += (yOcnn[k] - d[k]) * dsigmoid(yOcnn[k]) * w2cnn[j, k];

for (int i = 0; i <100; i++)//

for (int j = 0; j < 80; j++)//

{

double delta = dsigmoid(hO2[j]) * (hocnnhebing[i]) * W3[j];//这里要的是系数

w12cnn[i, j] -= delta * learnRate;

}

//对比三层bpnet,上面比较好理解,下面是对四个卷积核的backward:

//backward中第一个卷积核5*5的处理:

double[] deltacnn = new double[25];//每一个deltacnn,都对应25个14*14中的数据元素,以及一个5*5的卷积核

for (int i = 0; i < 25; i++)//25

for (int j = 0; j < 80; j++)//

{

deltacnn[i] = dsigmoid(hO2[j]) * W3[j] * w12cnn[i, j] * dsigmoid(hocnnhebing[i]);

}//全连接还是好处理202409200708

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

{

Point temppt=求二维(i, jilumn[i].Y, jilumn[i].X);

for (int k = 0; k < 5; k++)

for (int z = 0; z < 5; z++)

{

int newIndex = (temppt.Y + k) * 14 + (temppt.X + z);

double delta = xI[newIndex] * deltacnn[i];//一共25个

w1cnn[k * 5 + z, 0] -= delta * learnRate;//只用一个卷积核,核forward就对应上了202409181430

}

}

//第二个卷积核202409191112

double[] deltacnn1 = new double[25];//每一个deltacnn,都对应25个14*14中的数据元素,以及一个5*5的卷积核

for (int i = 25; i < 50; i++)//25

for (int j = 0; j < 80; j++)//

{

deltacnn1[i - 25] = dsigmoid(hO2[j]) * W3[j] * w12cnn[i, j] * dsigmoid(hocnnhebing[i]);

}

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

{

Point temppt = 求二维(i, jilumn1na[i].Y, jilumn1na[i].X);

for (int k = 0; k < 5; k++)

for (int z = 0; z < 5; z++)

{

int newIndex = (temppt.Y + k) * 14 + (temppt.X + z);

double delta = xI[newIndex] * deltacnn1[i];//一共25个

w1cnn[k * 5 + z, 1] -= delta * learnRate;//只用一个卷积核,核forward就对应上了202409181430

}

}

//第三个卷积核202409191112

double[] deltacnn2 = new double[25];//每一个deltacnn,都对应25个14*14中的数据元素,以及一个5*5的卷积核

for (int i = 50; i < 75; i++)//25

for (int j = 0; j < 80; j++)//

{

deltacnn2[i - 50] = dsigmoid(hO2[j]) * W3[j] * w12cnn[i, j] * dsigmoid(hocnnhebing[i]);

}

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

{

Point temppt = 求二维(i, jilumn2na[i].Y, jilumn2na[i].X);

for (int k = 0; k < 5; k++)

for (int z = 0; z < 5; z++)

{

int newIndex = (temppt.Y + k) * 14 + (temppt.X + z);

double delta = xI[newIndex] * deltacnn2[i];//一共25个

w1cnn[k * 5 + z, 2] -= delta * learnRate;//只用一个卷积核,核forward就对应上了202409181430

}

}

//第四个卷积核202409191112

double[] deltacnn3 = new double[25];//每一个deltacnn,都对应25个14*14中的数据元素,以及一个5*5的卷积核

for (int i = 75; i < 100; i++)//25

for (int j = 0; j <80; j++)//

{

deltacnn3[i - 75] = dsigmoid(hO2[j]) * W3[j] * w12cnn[i, j] * dsigmoid(hocnnhebing[i]);

}

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

{

Point temppt = 求二维(i, jilumn3na[i].Y, jilumn3na[i].X);

for (int k = 0; k < 5; k++)

for (int z = 0; z < 5; z++)

{

int newIndex = (temppt.Y + k) * 14 + (temppt.X + z);

double delta = xI[newIndex] * deltacnn3[i];//一共25个

w1cnn[k * 5 + z, 3] -= delta * learnRate;//只用一个卷积核,核forward就对应上了202409181430

}

}

以上就处理完了。哦,还有一个函数:

public Point 求二维(int index, int mm, int nn)

{

Point rePt = new Point();

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

for (int j = 0; j < 5; j++)

{

int n = i * 5 + j;

if (index == n)

{

int h = i * 2 + mm;

int w = j * 2 + nn;

rePt.X = w;

rePt.Y = h;

i = 5;

j = 5;//end 2 for loop;

}

}

return rePt;

}

或许,我这个cnn与你想的高大上的不同,但刨根问底,就是一回事!

也就是,你自学懂了,想怎么实现就怎么实现!

这几个核,在训练达到95分后,竟然自己生成了,太神奇!

想一想我们在图像处理里,用了那么多的卷积核,重来没有说是让计算机自己生成的,震惊到了吧!虽然这几个核,不那么好看,但的的确确,是计算机自己学习到的!

这是什么,这就是人工智能,这就是有学习能力的机器,太厉害了!所以人能做到的高斯核,机器在不断改进和进化中,一定会生成,更震惊的,他可能生成的卷积核,你都没见过,但他确实效果好,所以,他得到的结果,还有可能超过你!

本程序中,我们只生成了4个卷积核,那么使用8个卷积核,是不是效果更好?留作思考。

本节到此结束。

相关推荐
普密斯科技13 分钟前
手机外观边框缺陷视觉检测智慧方案
人工智能·计算机视觉·智能手机·自动化·视觉检测·集成测试
四口鲸鱼爱吃盐26 分钟前
Pytorch | 利用AI-FGTM针对CIFAR10上的ResNet分类器进行对抗攻击
人工智能·pytorch·python
lishanlu13627 分钟前
Pytorch分布式训练
人工智能·ddp·pytorch并行训练
日出等日落40 分钟前
从零开始使用MaxKB打造本地大语言模型智能问答系统与远程交互
人工智能·语言模型·自然语言处理
三木吧1 小时前
开发微信小程序的过程与心得
人工智能·微信小程序·小程序
whaosoft-1431 小时前
w~视觉~3D~合集5
人工智能
猫头虎1 小时前
新纪天工 开物焕彩:重大科技成就发布会参会感
人工智能·开源·aigc·开放原子·开源软件·gpu算力·agi
正在走向自律2 小时前
京东物流营销 Agent:智能驱动,物流新篇(13/30)
人工智能·ai agent·ai智能体·京东物流agent
远洋录3 小时前
React性能优化实战:从理论到落地的最佳实践
前端·人工智能·react
KD3353 小时前
Marscode AI辅助编程
人工智能