机器视觉匹配中使用bpnet匹配,二
使用leaky relu和leaky relu的斜率代替f(x)=1/(1+exp(-x))及f(x)的导数f(x)(1-f(x))确实是一个好办法。
我们机器视觉中bpnet匹配,是x[n]-hi/ho-yi/yo这样结构,即n-80-1三层bpnet最简单网络。
输入n,使用canny轮廓,不行,最后匹配用canny轮廓对应原图的灰度就ok,要不,整个截图在全图中bpnet匹配,至少3分钟(这还是不旋转的情况下)!这样处理大大减少了匹配基数!
80是隐层神经元,最后输出1个结果,还是很简单的bpnet了,本来估计效率很高,没想到最快也得30秒。当然隐层神经元我试过40,60,最后还是80好!
+-45度匹配我使用3度间隔,2度间隔,1度间隔,最后用2度间隔,1度间隔太慢,3度准确度下降,而我轮廓形状匹配粗匹配中5度间隔在这里作废!
好我们先研究一下bpnet公式,看怎么替代,其实挺简单:
public double dsigmoid(double x)
{
return x * (1 - x);
}
public double dNDrelu(double x)
{
return x > 0 ? 1f : 0.01f;
}
public double sigmoid(double x)
return 1 / (1f + Math.Exp(-x));
public double NDrelu(double x)
{
return x > 0 ? x : 0.01f * x;//=max(0.1x,x)
}
forward()中:原来代码:
for (int i = 0; i < 80; i++) hOroi[i] = sigmoid(hIroi[i] );
yOroi[0] = sigmoid(yiroi[0]);
改完代码:
for (int i = 0; i < 80; i++) hOroi[i] = NDrelu(hIroi[i] );
yOroi[0] = NDrelu(yiroi[0]);
back()中:原来代码:
double[] deltax = new double[1];
deltax[0] = (yOroi[0] - d[0]) * dsigmoid(yOroi[0]);
double delta = dsigmoid(hOroi[j]) * W2[j];
改完代码:
deltax[0] = (yOroi[0] - d[0]) * dNDrelu(yOroi[0]);
double delta = dNDrelu(hOroi[j]) * W2[j];
就这么简单,换个函数就可以了!
好,编译没错误,运行!
我滴个天!还想训练5000次,第三次就挂了!数字大的异常了!
这是什么鬼?
最后想了想,坑总是要踩的!
我研究后发现:
for (int j = 0; j < 80; j++)//80
for (int i = 0; i < lunkc; i++)//轮廓点数
{
hI固定roi[j] += xxxroi[i] * w1固定roi[i, j];
}
进入ndrelu()的 hI固定roi[j]太大!好有办法,找出roi[j]中最大,都除以这个值,不就ok了嘛!
立马执行!改代码:
for (int j = 0; j < 80; j++)//80
{
for (int i = 0; i < lunkc; i++)///轮廓点数
{
hI固定roi[j] += xxxroi[i] * w1固定roi[i, j];
}
if (hI固定roi[j]>linshimax)
{
linshimax = hI固定roi[j];
}
}
for (int i = 0; i < 80; i++) hO固定roi[i] = NDrelu(hI固定roi[i] / linshimax);//临时最大
哎,学习训练3,4,5次有效果,好训练5000次,back()函数中未改,我考虑后觉得没影响。
你想,back中斜率只取1或0.01,只有大于零或小于零起作用,除以 linshimax显然没影响。
训练完成后,这个最大值 linshimax要保留,在匹配中要用,因为这是你学习的成果。
我想的周到吧!
最后发现训练效果出奇的好,但是匹配结果中,没有一个正确的!
怎么回事,不知道啊!
想起这个除以最大,是很好的归一化,有地方用过,不错的,否则绝不会想到!
最后我发现,估计是误差函数反向传播时与dndrelu()有问题,我也没仔细研究!
既然这样不行,我sigmoid搭配tanhx输出一起用过,是正确的,那么肯定ndrelu()搭配tanhx也是可以的,或者sigmo函数,好,我就改成
ndrelu隐层用,输出层用sigmoid,发现训练的也很好,匹配结果中没正确的!
这个肯定没问题,那么问题一定在linshimax上。
但我仍然不知道linshimax错在哪?上网查:
relu需要和softmax函数搭配使用!这就是结论!
而且只有一个输出的,不用relu和softmax!
这冤枉路走的,我去!
然而,当你到达彼岸时,以上犯的错,皆有功德,当你想通大神的想法,并实现时,你发现你犯的错,他们都犯过,而且你很遗憾,你没有深究下去,他们都是从错误中领悟的!
因为意识是相同的,你的直觉,他也会有,你犯错他也会,这或许是圣经!