我们第一层用卷积核,前面已经成功,现在我们用两层卷积核:
结构如下,是不是很想lenet-1,其实我们24年就实现了sigmoid版本的:
cnn突破九(我们的五层卷积核bpnet网络就是lenet-1)-CSDN博客
28*28*4-》24*24*4-》12*12*4-》8*8*16-》4*4*16-》80-》10
我们28*28到24*24使用4个卷积核。
12*12到8*8使用16个卷积核。
还是那句话,权重参数w就是卷积核,卷积核就是权重w!
我们现在要全部改成relu版本!
那时我们是sigmoid实现,平均分93分,就打住了!
这次改的过程中才发现一个错误!
这里边我们的公式如下:
我们令B=(yo[k]-d[k])*ds(yo[k])*w2【m,k】*ds(h2o[m])*w12【j,m】*ds(hocnn[j])
=B*
*
*
=B*w1cnn[25]*ds(hxo[])*x[i]
= (yo[k]-d[k])*ds(yo[k])*w2【m,k】*ds(h2o[m])*w12【j,m】*ds(hocnn[j])*w1cnn[25]*ds(hxo[])*x[i]
其实公式是没有问题的,问题出在程序中,第一次卷积中,forward方向少了sigmoid!
back方向上,却做了sigmoid求导!
奇怪了,这么大的问题,为什么还能得分93?
也就是说反向更新搞错,也没影响?这个问题还是值得研究一下的!
但是再往上走,可能性变为0.训练12万次也不行,当时也不知道,就认了!
当初这个在我期望中,就放下了!
直到这一次才发现!
代码中关键在forward中这个地方遗忘了:(特别用遗忘二字标出来)
for (int i = 0; i < 144; i++)
{//NDrelu
hI遗忘[i] = NDrelu(hIcnnna[i] );
hI遗忘1[i] = NDrelu(hIcnn1na[i] );
hI遗忘2[i] = NDrelu(hIcnn2na[i] );
hI遗忘3[i] = NDrelu(hIcnn3na[i] );
}
而back代码中有呼应如下:
double[] deltacnnX = new double[16];//每一个deltacnnx,都对应25个28*28中的数据元素,以及一个5*5的卷积核
for (int i = 0; i < 16; i++)//16
for (int j = 0; j < 25; j++)//25
{
deltacnnX[i] = deltacnn[i] * w1cnn[j, 0];
}//全连接还是好处理202409200708
for (int i = 0; i < 16; i++)
{//jilumnna
Point temppt = 求二维(i, jilumnna[i].Y, jilumnna[i].X);
for (int k = 0; k < 5; k++)
for (int z = 0; z < 5; z++)
{
int newIndex = (temppt.Y + k) * 28+ (temppt.X + z);
int biasIndex=(temppt.Y / 2 + k) * 12 + temppt.X / 2 + z;
double delta = deltacnnX[i] * dNDrelu(hI遗忘[biasIndex]) * learnRate;//一共25个
// double delta = xI[newIndex] * deltacnnX[i] * dsigmoid(hIcnnna[(temppt.Y / 2 + k) * 12 + temppt.X / 2 + z]);//一共25个
w576cnn[k * 5 + z, 0] -= xI[newIndex] * delta ;//只用一个卷积核,核forward就对应上了202409181430
}
}
前四个卷积核,后16个卷积核,一共20个。
20个卷积核cnn更改ok(类似lenet-1),平均96分,最好97.667
而遗憾的是老版本20个卷积核程序改挂了!使用sigmoid函数!
三个cnn版本,sigmoid版本应该可以改成功!
难度大的都搞定,sigmoid应该问题不大!
有机会试一下真正lecun的lenet-1:
28*28*3(rgb)-》3*24*24-》3*12*12-》16*8*8-》16*4*4-》80-》10
刚好我有彩色相机,不必10个输出,1个就好,在机器视觉中试一试,也不需要什么数据集!