C# 神经网络[ocr]
我是来寻找关于我现在写的程序的一般提示的 目标是: 使用神经网络程序识别3个字母[D,O,M],或者显示如果我输入的不是这3个字母,就不会识别任何字母 以下是我目前掌握的情况: 我的单神经元课程C# 神经网络[ocr],c#,neural-network,C#,Neural Network,我是来寻找关于我现在写的程序的一般提示的 目标是: 使用神经网络程序识别3个字母[D,O,M],或者显示如果我输入的不是这3个字母,就不会识别任何字母 以下是我目前掌握的情况: 我的单神经元课程 public class neuron { double[] weights; public neuron() { weights = null; } public neuron(int size) { weights =
public class neuron
{
double[] weights;
public neuron()
{
weights = null;
}
public neuron(int size)
{
weights = new double[size + 1];
Random r = new Random();
for (int i = 0; i <= size; i++)
{
weights[i] = r.NextDouble() / 5 - 0.1;
}
}
public double output(double[] wej)
{
double s = 0.0;
for (int i = 0; i < weights.Length; i++) s += weights[i] * wej[i];
s = 1 / (1 + Math.Exp(s));
return s;
}
}
这里用的好吗?
拓扑应该是什么?2或3层,如果3层,隐藏层中有多少神经元?我在finalnet数组的每个区域都有96个输入,所以我应该在第一层也取96个神经元吗?我应该在最后一层有3个神经元还是4个神经元来考虑未识别的情况,还是没有必要
谢谢你的帮助
编辑:哦,我忘了添加,我要用反向传播算法训练我的网络。不久前,我创建了一个python,对不起,根据我的短期经验,3层是可以的,96/50/3拓扑可能会做得很好。至于输出层,这是您的选择;当输入图像不是D、O或M时,可以反向传播所有0,也可以使用第四个输出神经元指示字母未被识别。我认为第一个选项是最好的,因为它更简单,训练时间更短,调试网络的问题更少…,您只需要应用一个阈值,将图像分类为“未识别”。
我还使用了sigmoid作为激活功能,我没有尝试其他功能,但它起了作用:
您可能至少需要4层才能使用反向传播方法获得准确的结果。1个输入层、2个中间层和一个输出层
12*8矩阵太小,可能会导致数据丢失,从而导致完全失败-尝试一些16*16的东西。如果你想缩小尺寸,那么你必须进一步剥离黑色像素的外层
考虑用你的参考人物训练网络
请记住,您必须再次将输出反馈到输入层,并对其进行多次迭代
嗯,在我的讲座中,没有明确说明使用双极函数还是单极函数更好,所以我在网上搜索了一下,我仍然不确定。3输出神经元似乎更容易是的,但阈值让我困惑,所以让我们假设我所有的神经元都返回接近0的值,比如0,1;0,2;0,15假设它什么也没认出来是安全的吗?@NagashTDN是的,没错1。你能解释一下为什么我需要4层吗?2.我从7x5矩阵开始,然后发现12x8是首选尺寸,如果我不想得到超精确的结果,这是我在uni实验室的一个程序。16x16是指采用AxA矩阵比采用AxB矩阵好还是采用更大的矩阵好?3.我有一套培训图片,由5个不同的人编写,每个字母10个。4.我认为我的英语不够好,无法理解这一点,对不起:这也是为什么我会被否决,我尽了最大努力解释我的情况。中间隐藏层在学习样本时起着关键作用。因此,再增加一层将提高其学习能力。如果精度不是一个问题,您可以使用3层。然而,在工业强度规范中,人们使用动态可配置的网络来提高精度和更好的测试。根据我的经验,16X16是经过优化的。
public class layer
{
neuron[] tab;
public layer()
{
tab = null;
}
public layer(int numNeurons, int numInputs)
{
tab = new neuron[numNeurons];
for (int i = 0; i < numNeurons; i++)
{
tab[i] = new neuron(numInputs);
}
}
public double[] compute(double[] wejscia)
{
double[] output = new double[tab.Length + 1];
output[0] = 1;
for (int i = 1; i <= tab.Length; i++)
{
output[i] = tab[i - 1].output(wejscia);
}
return output;
}
}
public class network
{
layer[] layers = null;
public network(int numLayers, int numInputs, int[] npl)
{
layers = new layer[numLayers];
for (int i = 0; i < numLayers; i++)
{
layers[i] = new layer(npl[i], (i == 0) ? numInputs : (npl[i - 1]));
}
}
double[] compute(double[] inputs)
{
double[] output = layers[0].compute(inputs);
for (int i = 1; i < layers.Length; i++)
{
output = layers[i].compute(output);
}
return output;
}
}
Bitmap bmp2 = new Bitmap(this.pictureBox1.Image);
int[,] binaryfrom = new int[bmp2.Width, bmp2.Height];
int minrow=0, maxrow=0, mincol=0, maxcol=0;
for (int i = 0; i < bmp2.Height; i++)
{
for (int j = 0; j < bmp2.Width; j++)
{
if (bmp2.GetPixel(j, i).R == 0)
{
binaryfrom[i, j] = 1;
if (minrow == 0) minrow = i;
if (maxrow < i) maxrow = i;
if (mincol == 0) mincol = j;
else if (mincol > j) mincol = j;
if (maxcol < j) maxcol = j;
}
else
{
binaryfrom[i, j] = 0;
}
}
}
int[,] boundaries = new int[binaryfrom.GetLength(0)-minrow-(binaryfrom.GetLength(0)-(maxrow+1)),binaryfrom.GetLength(1)-mincol-(binaryfrom.GetLength(1)-(maxcol+1))];
for(int i = 0; i < boundaries.GetLength(0); i++)
{
for(int j = 0; j < boundaries.GetLength(1); j++)
{
boundaries[i, j] = binaryfrom[i + minrow, j + mincol];
}
}
int[,] finalnet = new int[12, 8];
int k = 1;
int l = 1;
for (int i = 0; i < finalnet.GetLength(0); i++)
{
for (int j = 0; j < finalnet.GetLength(1); j++)
{
finalnet[i, j] = 0;
}
}
while (k <= finalnet.GetLength(0))
{
while (l <= finalnet.GetLength(1))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * (k - 1); i < (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * k; i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * (l - 1); j < (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * l; j++)
{
if (boundaries[i, j] == 1) finalnet[k-1, l-1] = 1;
}
}
l++;
}
l = 1;
k++;
}
int a = boundaries.GetLength(0);
int b = finalnet.GetLength(1);
if((a%b) != 0){
k = 1;
while (k <= finalnet.GetLength(1))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * finalnet.GetLength(0); i < boundaries.GetLength(0); i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * (k - 1); j < (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * k; j++)
{
if (boundaries[i, j] == 1) finalnet[finalnet.GetLength(0) - 1, k - 1] = 1;
}
}
k++;
}
}
if (boundaries.GetLength(1) % finalnet.GetLength(1) != 0)
{
k = 1;
while (k <= finalnet.GetLength(0))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * (k - 1); i < (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * k; i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * finalnet.GetLength(1); j < boundaries.GetLength(1); j++)
{
if (boundaries[i, j] == 1) finalnet[k - 1, finalnet.GetLength(1) - 1] = 1;
}
}
k++;
}
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * finalnet.GetLength(0); i < boundaries.GetLength(0); i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * finalnet.GetLength(1); j < boundaries.GetLength(1); j++)
{
if (boundaries[i, j] == 1) finalnet[finalnet.GetLength(0) - 1, finalnet.GetLength(1) - 1] = 1;
}
}
}
1/(1+Math.Exp(x))