簡體   English   中英

神經網絡[OCR]

[英]Neural network [ocr]

我來尋找有關我現在正在編寫的程序的一般提示。

目標是:使用神經網絡程序識別3個字母[D,O,M](如果我輸入的不是3個字母,則顯示“什么也沒有識別”)。

這是我到目前為止的內容:

我的單個神經元的課程

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

圖層的類:

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

現在,我選擇了算法:

我有一個尺寸為200x200的圖片框,您可以在其中畫一個字母(或從jpg文件中讀取一個字母)。

然后,將其轉換為我的第一個數組(獲取整個圖片)和第二個數組(剪切周圍的無關背景),如下所示:

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

            }
        }

然后像這樣將其轉換為我的最終12x8數組(我知道我可以將其縮短很多,但是希望每個步驟都處於不同的循環中,這樣我就可以更容易地發現出了什么問題[如果有的話]):

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

結果是一個0x和1的12x8(我可以在代碼中更改它以便從某些表單控件獲取它)數組,其中1形成繪制的字母的大致形狀。

現在我的問題是:這是正確的算法嗎? 是我的職責

1/(1+Math.Exp(x))

好用在這里? 拓撲應該是什么? 2或3層,如果是3層,則隱藏層中有多少個神經元? 我有96個輸入(finalnet數組的每個字段),所以我也應該在第一層接受96個神經元嗎? 我是否應該在最后一層中包含3個神經元或4個神經元(考慮到“未識別”的情況),還是沒有必要?

謝謝您的幫助。

編輯:哦,我忘了補充,我要使用反向傳播算法來訓練我的網絡。

  1. 使用反向傳播方法,您可能至少需要4層才能獲得准確的結果。 1個輸入,2個中間層和一個輸出層。

  2. 12 * 8矩陣太小(可能會導致數據丟失,從而導致完全失敗)-嘗試嘗試16 *16。如果要減小尺寸,則必須剝去黑色像素的外層進一步。

  3. 考慮使用您的參考字符來訓練網絡。

  4. 請記住,您必須再次將輸出反饋回輸入層,並對其進行多次迭代。

前一段時間,我創建了一個神經網絡來識別數字0-9 (python,對不起),因此根據我的(簡短)經驗,可以確定3層,而96/50/3拓撲可能會做得很好。 至於輸出層,則由您選擇; 您可以在輸入圖像不是D,O或M的情況下反向傳播全0,或使用第四個輸出神經元表示未識別出該字母。 我認為第一種選擇是最好的選擇,因為它更簡單(培訓時間更短,調試網絡的問題更少...),您只需要應用一個閾值即可將圖像分類為“無法識別”。
我也使用了sigmoid作為激活函數,雖然我沒有嘗試其他方法,但它確實有效:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM