機械学習で二次方程式の解 4【層を増やしてどうなるか】

![二次方程式５×５.png](https://qiita-image-store.s3.amazonaws.com/0/207542/28f24b4f-e7b4-319c-e811-e404e12eb153.png)
線を106本引くのが苦痛だったので省略させていただきます。

冬は寒くてやる気が起きないもので、布団に入っている時間が長すぎて更新が遅れてしまいました。
なので、おさらいをさせて頂きます。

```math
a(x-α)(x-β)=0
```

a = 1 で固定し
解α,βを正の整数0～100までの組み合わせ
(0,0)
(0,1)
...
(0,99)
(0,100)
(1,0)
(1,1)
...
(100,99)
(100,100)
101×101=10201通り
を出力・学習するように

```math
ax^2+bx+c=0\\
　\\
a=1\\
b=-(α+β)\\
c=αβ\\
```
係数a,b,c
a=1,b=0,c=0　(0,0)
a=1,b=-1,c=0　(0,1)
...
a=1,b=-99,c=0　(0,99)
a=1,b=-100,c=0　(0,100)
a=1,b=-1,c=0　(1,0)
a=1,b=-2,c=1　(1,1)
...
a=1,b=-199,c=9900　(100,99)
a=1,b=-200,c=10000　(100,100)
を入力させてみました。
学習率は1で何もしてません。
出力は恒等関数で入力をそのまま出力させています。

最終的な重みはこうなりました。

|   |w[0]|w[1]|w[2]|w[3]|w[4]|w[5]|
|---|---|---|---|---|---|---|
|[0,0]|0.441930898801797|0.469590514077478|0.469590514077478|0.469590514077478|0.469590514077478|4.51380711840005|
|[0,1]|0.443547685860287|0.470383041353623|0.470383041353623|0.470383041353623|0.470383041353623|3.05704100337193|
|[0,2]|0.450653084374292|0.473889759484426|0.473889759484426|0.473889759484426|0.473889759484426||
|[0,3]|0.487101135272675|0.492018054843344|0.492018054843344|0.492018054843344|0.492018054843344||
||||||||
|[1,0]|0.599222684470502|0.445981685833605|0.445981685833605|0.445981685833605|0.445981685833605|4.51024540772987|
|[1,1]|0.596102727640753|0.446971359524566|0.446971359524566|0.446971359524566|0.446971359524566|3.05294463073917|
|[1,2]|0.582596514136166|0.451346252377226|0.451346252377226|0.451346252377226|0.451346252377226||
|[1,3]|0.513322331310806|0.47531861146909|0.47531861146909|0.47531861146909|0.47531861146909||
||||||||
|[2,0]|0.499999268892448|0.304971657954352|0.304971657954352|0.304971657954352|0.304971657954352|4.4984007149069|
|[2,1]|0.499999262120468|0.308508804805227|0.308508804805227|0.308508804805227|0.308508804805227|3.03885524565442|
|[2,2]|0.499999121283456|0.324531446240591|0.324531446240591|0.324531446240591|0.324531446240591||
|[2,3]|0.49999082281352|0.409685459874327|0.409685459874327|0.409685459874327|0.409685459874327||
||||||||
|[3,0]|0.441930898801797|-0.575856621237778|-0.575856621237778|-0.575856621237778|-0.575856621237778|4.4491601671519|
|[3,1]|0.443547685860287|-0.553578175959809|-0.553578175959809|-0.553578175959809|-0.553578175959809|2.97034604531204|
|[3,2]|0.450653084374292|-0.449290489120273|-0.449290489120273|-0.449290489120273|-0.449290489120273||
|[3,3]|0.487101135272675|0.109319059631224|0.109319059631224|0.109319059631224|0.109319059631224||
||||||||
|[4,0]||-5.17187275931402|-5.17187275931402|-5.17187275931402|-5.17187275931402|99.901140332925|
|[4,1]||-5.1770660169597|-5.1770660169597|-5.1770660169597|-5.1770660169597|99.9335273220302|
|[4,2]||-5.19439167279984|-5.19439167279984|-5.19439167279984|-5.19439167279984||
|[4,3]||-5.27018799485631|-5.27018799485631|-5.27018799485631|-5.27018799485631||

どうも、学習はしていなくその時の教師信号が
α=w[5][4,0]
β=w[5][4,1]
となってしまうだけの結果です。

そういえば、私の数学の先生に相談したところ
最終層にバイアスがある意味がわからないと助言を頂いておりました。

ちなみに前回までの誤差逆伝播で


```csharp
w0[0, 0] = w0[0, 0] - (a * s(-h0_0_out) * (1 - s(-h0_0_out)) * ((w1[0, 0] * -mE[0]) + (w1[0, 1] * -mE[1])));
```
と計算してしてました。正しくは


```csharp
w0[0, 0] = w0[0, 0] - (a * h0_0_out * (1 - h0_0_out) * ((w1[0, 0] * -mE[0]) + (w1[0, 1] * -mE[1])));
```

こうするべきでした。
シグモイド関数に入れてみたり、マイナスつけたりgdgdでした。

また、余談ですが、「ですます」調に揃えなきゃいけないものでしょうか？
書いてて「でした」と言いたいところを「ですます」で表現するのに困っており「ます」。

次回
最後の層のバイアスを消す


```csharp
        /*
        double[,] w0 = new double[,]{   //h0,h1,h2
                                        { 0.5,0.5,0.5}, //a
                                        { 0.5,0.5,0.5}, //b
                                        { 0.5,0.5,0.5}, //c
                                        { 0.5,0.5,0.5}};//B

        double[,] w1 = new double[,]{
                                        { 0.5,0.5},
                                        { 0.5,0.5},
                                        { 0.5,0.5},
                                        { 0.5,0.5}};
        */

        string path = @"D:\開発\AI\" + DateTime.Now.ToString("yyyyMMdd") + ".csv";

        int layer = 5;
        int cell = 4;//今回はどの層も活性化関数がシグモイド関数で数も同じなので1変数で記述

        double[][,] w = new double[6][,] {
            new double[,]{
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5}},
            new double[,]{
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5}},
            new double[,]{
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5}},
            new double[,]{
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5}},
            new double[,]{
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5},
                { 0.5,0.5,0.5,0.5}},
            new double[,]{
                { 0.5,0.5},
                { 0.5,0.5},
                { 0.5,0.5},
                { 0.5,0.5},
                { 0.5,0.5}},
        }; 

        Stopwatch sw = new Stopwatch();

        private void nnw()
        {            
            using (StreamWriter sw = new StreamWriter(path, true, Encoding.Unicode))
            {//列見出し
                sw.Write(
                    "a,b,c,D,α,β," +

                    "w[0][0_0]:a-h0_0,w[0][0_1]:a-h0_1,w[0][0_2]:a-h0_2,w[0][0_3]:a-h0_3," +
                    "w[0][1_0]:b-h0_0,w[0][1_1]:b-h0_1,w[0][1_2]:b-h0_2,w[0][1_3]:b-h0_3," +
                    "w[0][2_0]:c-h0_0,w[0][2_1]:c-h0_1,w[0][2_2]:c-h0_2,w[0][2_3]:c-h0_3," +
                    "w[0][3_0]:B-h0_0,w[0][3_1]:B-h0_1,w[0][3_2]:B-h0_2,w[0][3_3]:B-h0_3," +

                    "h0_0:net,h0_0:out,h0_1:net,h0_1:out,h0_2:net,h0_2:out,h0_3:net,h0_3:out," +

                    "w[1][0_0]:h0_0-h1_0,w[1][0_1]:h0_0-h1_1,w[1][0_2]:h0_0-h1_2,w[1][0_3]:h0_0-h1_3," +
                    "w[1][1_0]:h0_1-h1_0,w[1][1_1]:h0_1-h1_1,w[1][1_2]:h0_1-h1_2,w[1][1_3]:h0_1-h1_3," +
                    "w[1][2_0]:h0_2-h1_0,w[1][2_1]:h0_2-h1_1,w[1][2_2]:h0_2-h1_2,w[1][2_3]:h0_2-h1_3," +
                    "w[1][3_0]:h0_3-h1_0,w[1][3_1]:h0_3-h1_1,w[1][3_2]:h0_3-h1_2,w[1][3_3]:h0_3-h1_3," +
                    "w[1][4_0]:B-h1_0,w[1][4_1]:B-h1_1,w[1][4_2]:B-h1_2,w[1][4_3]:B-h1_3," +

                    "h1_0:net,h1_0:out,h1_1:net,h1_1:out,h1_2:net,h1_2:out,h1_3:net,h1_3:out," +

                    "w[2][0_0]:h1_0-h2_0,w[2][0_1]:h1_0-h2_1,w[2][0_2]:h1_0-h2_2,w[2][0_3]:h1_0-h2_3," +
                    "w[2][1_0]:h1_1-h2_0,w[2][1_1]:h1_1-h2_1,w[2][1_2]:h1_1-h2_2,w[2][1_3]:h1_1-h2_3," +
                    "w[2][2_0]:h1_2-h2_0,w[2][2_1]:h1_2-h2_1,w[2][2_2]:h1_2-h2_2,w[2][2_3]:h1_2-h2_3," +
                    "w[2][3_0]:h1_3-h2_0,w[2][3_1]:h1_3-h2_1,w[2][3_2]:h1_3-h2_2,w[2][3_3]:h1_3-h2_3," +
                    "w[2][4_0]:B-h2_0,w[2][4_1]:B-h2_1,w[2][4_2]:B-h2_2,w[2][4_3]:B-h2_3," +

                    "h2_0:net,h2_0:out,h2_1:net,h2_1:out,h2_2:net,h2_2:out,h2_3:net,h2_3:out," +

                    "w[3][0_0]:h2_0-h3_0,w[3][0_1]:h2_0-h3_1,w[3][0_2]:h2_0-h3_2,w[3][0_3]:h2_0-h3_3," +
                    "w[3][1_0]:h2_1-h3_0,w[3][1_1]:h2_1-h3_1,w[3][1_2]:h2_1-h3_2,w[3][1_3]:h2_1-h3_3," +
                    "w[3][2_0]:h2_2-h3_0,w[3][2_1]:h2_2-h3_1,w[3][2_2]:h2_2-h3_2,w[3][2_3]:h2_2-h3_3," +
                    "w[3][3_0]:h2_3-h3_0,w[3][3_1]:h2_3-h3_1,w[3][3_2]:h2_3-h3_2,w[3][3_3]:h2_3-h3_3," +
                    "w[3][4_0]:B-h3_0,w[3][4_1]:B-h3_1,w[3][4_2]:B-h3_2,w[3][4_3]:B-h3_3," +

                    "h3_0:net,h3_0:out,h3_1:net,h3_1:out,h3_2:net,h3_2:out,h3_3:net,h3_3:out," +

                    "w[4][0_0]:h3_0-h4_0,w[4][0_1]:h3_0-h4_1,w[4][0_2]:h3_0-h4_2,w[4][0_3]:h3_0-h4_3," +
                    "w[4][1_0]:h3_1-h4_0,w[4][1_1]:h3_1-h4_1,w[4][1_2]:h3_1-h4_2,w[4][1_3]:h3_1-h4_3," +
                    "w[4][2_0]:h3_2-h4_0,w[4][2_1]:h3_2-h4_1,w[4][2_2]:h3_2-h4_2,w[4][2_3]:h3_2-h4_3," +
                    "w[4][3_0]:h3_3-h4_0,w[4][3_1]:h3_3-h4_1,w[4][3_2]:h3_3-h4_2,w[4][3_3]:h3_3-h4_3," +
                    "w[4][4_0]:B-h4_0,w[4][4_1]:B-h4_1,w[4][4_2]:B-h4_2,w[4][4_3]:B-h4_3," +

                    "h4_0:net,h4_0:out,h4_1:net,h4_1:out,h4_2:net,h4_2:out,h4_3:net,h4_3:out," +

                    "w[5][0_0]:h4_0-Yα,w[5][0_1]:h4_0-Yβ," +
                    "w[5][1_0]:h4_1-Yα,w[5][1_1]:h4_1-Yβ," +
                    "w[5][2_0]:h4_2-Yα,w[5][2_1]:h4_2-Yβ," +
                    "w[5][3_0]:h4_3-Yα,w[5][3_1]:h4_3-Yβ," +
                    "w[5][4_0]:B-Yα,w[5][4_1]:B-Yβ," +

                    "Y0_net,Y0_out,ΔE0," +
                    "Y1_net,Y1_out,ΔE1" +

                    Environment.NewLine);
            }

            for (double alpha = 0; alpha <= 100; alpha++)
            {
                for (double beta = 0; beta <= 100; beta++)
                {
                    Invoke(new dldl(delegate
                    {
                        label1.Text = alpha.ToString() + "," + beta.ToString();
                        label2.Text = sw.Elapsed.ToString();
                    }));

                    //
                    double a = 1;
                    double b = -(alpha + beta);
                    double c = alpha * beta;
                    double d = b * b - 4 * a * c;

                    //forward                                       
                    double[][] h_net = new double[layer][];
                    double[][] h_out = new double[layer][];
                    
                    h_net[0] = new double[cell];
                    h_out[0] = new double[cell];
                    for (int cl = 0; cl < cell; cl++)
                    {
                        h_net[0][cl] = a * w[0][0, cl] + b * w[0][1, cl] + c * w[0][2, cl] + w[0][3, cl];
                        h_out[0][cl] = s(h_net[0][cl]);
                    }

                    for (int ly = 1; ly < layer; ly++)
                    {
                        h_net[ly] = new double[cell];
                        h_out[ly] = new double[cell];
                        for (int cl = 0; cl < cell; cl++)
                        {
                            h_net[ly][cl] = h_out[ly - 1][0] * w[ly][0, cl] + h_out[ly - 1][1] * w[ly][1, cl] + h_out[ly - 1][2] * w[ly][2, cl] + h_out[ly - 1][3] * w[ly][3, cl] + w[ly][4, cl];
                            h_out[ly][cl] = s(h_net[ly][cl]);
                        }
                    }

                    double Y0_net = h_out[layer - 1][0] * w[layer][0, 0] + h_out[layer - 1][1] * w[layer][1, 0] + h_out[layer - 1][2] * w[layer][2, 0] + h_out[layer - 1][3] * w[layer][3, 0] + w[layer][4, 0];
                    double Y0_out = Y0_net;
                    double Y1_net = h_out[layer - 1][1] * w[layer][0, 1] + h_out[layer - 1][1] * w[layer][1, 1] + h_out[layer - 1][2] * w[layer][2, 1] + h_out[layer - 1][3] * w[layer][3, 1] + w[layer][4, 1];
                    double Y1_out = Y1_net;

                    //double[] mE = new double[] { alpha - OUT0_out, beta - OUT1_out };
                    double[] deltaE = new double[] { Y0_out - alpha, Y1_out - beta };//計算省略のため二乗誤差微分後の値

                    //記録
                    using (StreamWriter sw = new StreamWriter(path, true, Encoding.Unicode))
                    {
                        sw.Write(
                            a.ToString() + "," + b.ToString() + "," + c.ToString() + "," + d.ToString() + "," +
                            alpha.ToString() + "," + beta.ToString() + "," +

                            w[0][0, 0].ToString() + "," + w[0][0, 1].ToString() + "," + w[0][0, 2].ToString() + "," + w[0][0, 3].ToString() + "," +
                            w[0][1, 0].ToString() + "," + w[0][1, 1].ToString() + "," + w[0][1, 2].ToString() + "," + w[0][1, 3].ToString() + "," +
                            w[0][2, 0].ToString() + "," + w[0][2, 1].ToString() + "," + w[0][2, 2].ToString() + "," + w[0][2, 3].ToString() + "," +
                            w[0][3, 0].ToString() + "," + w[0][3, 1].ToString() + "," + w[0][3, 2].ToString() + "," + w[0][3, 3].ToString() + "," +

                            h_net[0][0].ToString() + "," + h_out[0][0].ToString() + "," +
                            h_net[0][1].ToString() + "," + h_out[0][1].ToString() + "," +
                            h_net[0][2].ToString() + "," + h_out[0][2].ToString() + "," +
                            h_net[0][3].ToString() + "," + h_out[0][3].ToString() + "," +

                            w[1][0, 0].ToString() + "," + w[1][0, 1].ToString() + "," + w[1][0, 2].ToString() + "," + w[1][0, 3].ToString() + "," +
                            w[1][1, 0].ToString() + "," + w[1][1, 1].ToString() + "," + w[1][1, 2].ToString() + "," + w[1][1, 3].ToString() + "," +
                            w[1][2, 0].ToString() + "," + w[1][2, 1].ToString() + "," + w[1][2, 2].ToString() + "," + w[1][2, 3].ToString() + "," +
                            w[1][3, 0].ToString() + "," + w[1][3, 1].ToString() + "," + w[1][3, 2].ToString() + "," + w[1][3, 3].ToString() + "," +
                            w[1][4, 0].ToString() + "," + w[1][4, 1].ToString() + "," + w[1][4, 2].ToString() + "," + w[1][4, 3].ToString() + "," +

                            h_net[1][0].ToString() + "," + h_out[1][0].ToString() + "," +
                            h_net[1][1].ToString() + "," + h_out[1][1].ToString() + "," +
                            h_net[1][2].ToString() + "," + h_out[1][2].ToString() + "," +
                            h_net[1][3].ToString() + "," + h_out[1][3].ToString() + "," +

                            w[2][0, 0].ToString() + "," + w[2][0, 1].ToString() + "," + w[2][0, 2].ToString() + "," + w[2][0, 3].ToString() + "," +
                            w[2][1, 0].ToString() + "," + w[2][1, 1].ToString() + "," + w[2][1, 2].ToString() + "," + w[2][1, 3].ToString() + "," +
                            w[2][2, 0].ToString() + "," + w[2][2, 1].ToString() + "," + w[2][2, 2].ToString() + "," + w[2][2, 3].ToString() + "," +
                            w[2][3, 0].ToString() + "," + w[2][3, 1].ToString() + "," + w[2][3, 2].ToString() + "," + w[2][3, 3].ToString() + "," +
                            w[2][4, 0].ToString() + "," + w[2][4, 1].ToString() + "," + w[2][4, 2].ToString() + "," + w[2][4, 3].ToString() + "," +

                            h_net[2][0].ToString() + "," + h_out[2][0].ToString() + "," +
                            h_net[2][1].ToString() + "," + h_out[2][1].ToString() + "," +
                            h_net[2][2].ToString() + "," + h_out[2][2].ToString() + "," +
                            h_net[2][3].ToString() + "," + h_out[2][3].ToString() + "," +

                            w[3][0, 0].ToString() + "," + w[3][0, 1].ToString() + "," + w[3][0, 2].ToString() + "," + w[3][0, 3].ToString() + "," +
                            w[3][1, 0].ToString() + "," + w[3][1, 1].ToString() + "," + w[3][1, 2].ToString() + "," + w[3][1, 3].ToString() + "," +
                            w[3][2, 0].ToString() + "," + w[3][2, 1].ToString() + "," + w[3][2, 2].ToString() + "," + w[3][2, 3].ToString() + "," +
                            w[3][3, 0].ToString() + "," + w[3][3, 1].ToString() + "," + w[3][3, 2].ToString() + "," + w[3][3, 3].ToString() + "," +
                            w[3][4, 0].ToString() + "," + w[3][4, 1].ToString() + "," + w[3][4, 2].ToString() + "," + w[3][4, 3].ToString() + "," +

                            h_net[3][0].ToString() + "," + h_out[3][0].ToString() + "," +
                            h_net[3][1].ToString() + "," + h_out[3][1].ToString() + "," +
                            h_net[3][2].ToString() + "," + h_out[3][2].ToString() + "," +
                            h_net[3][3].ToString() + "," + h_out[3][3].ToString() + "," +

                            w[4][0, 0].ToString() + "," + w[4][0, 1].ToString() + "," + w[4][0, 2].ToString() + "," + w[4][0, 3].ToString() + "," +
                            w[4][1, 0].ToString() + "," + w[4][1, 1].ToString() + "," + w[4][1, 2].ToString() + "," + w[4][1, 3].ToString() + "," +
                            w[4][2, 0].ToString() + "," + w[4][2, 1].ToString() + "," + w[4][2, 2].ToString() + "," + w[4][2, 3].ToString() + "," +
                            w[4][3, 0].ToString() + "," + w[4][3, 1].ToString() + "," + w[4][3, 2].ToString() + "," + w[4][3, 3].ToString() + "," +
                            w[4][4, 0].ToString() + "," + w[4][4, 1].ToString() + "," + w[4][4, 2].ToString() + "," + w[4][4, 3].ToString() + "," +

                            h_net[4][0].ToString() + "," + h_out[4][0].ToString() + "," +
                            h_net[4][1].ToString() + "," + h_out[4][1].ToString() + "," +
                            h_net[4][2].ToString() + "," + h_out[4][2].ToString() + "," +
                            h_net[4][3].ToString() + "," + h_out[4][3].ToString() + "," +

                            w[5][0, 0].ToString() + "," + w[5][0, 1].ToString() + "," +
                            w[5][1, 0].ToString() + "," + w[5][1, 1].ToString() + "," +
                            w[5][2, 0].ToString() + "," + w[5][2, 1].ToString() + "," +
                            w[5][3, 0].ToString() + "," + w[5][3, 1].ToString() + "," +
                            w[5][4, 0].ToString() + "," + w[5][4, 1].ToString() + "," +

                            Y0_net.ToString() + "," + Y0_out.ToString() + "," + deltaE[0].ToString() + "," +
                            Y1_net.ToString() + "," + Y1_out.ToString() + "," + deltaE[1].ToString() +

                            Environment.NewLine);
                    }

                    //backward
                    //δE/δNET
                    double[,] dE_dN = new double[layer, cell + 1];
                    for (int cl = 0; cl < cell; cl++)
                    {
                        dE_dN[layer - 1, cl] = h_out[layer - 1][cl] * (1 - h_out[layer - 1][cl]) * (w[layer][cl, 0] * deltaE[0] + w[layer][cl, 1] * deltaE[1]);
                    }
                    dE_dN[layer - 1, cell] = w[layer][cell, 0] * deltaE[0] + w[layer][cell, 1] * deltaE[1];

                    for (int ly = layer - 2; ly > -1; ly--)
                    {
                        for (int cl = 0; cl < cell; cl++)
                        {
                            dE_dN[ly, cl] = h_out[ly][cl] * (1 - h_out[ly][cl]) * (w[ly + 1][cl, 0] * dE_dN[ly + 1, 0] +
                                                                                   w[ly + 1][cl, 1] * dE_dN[ly + 1, 1] +
                                                                                   w[ly + 1][cl, 2] * dE_dN[ly + 1, 2] +
                                                                                   w[ly + 1][cl, 3] * dE_dN[ly + 1, 3] );
                        }
                        dE_dN[ly, cell] = w[ly + 1][cell, 0] * dE_dN[ly + 1, 0] +
                                          w[ly + 1][cell, 1] * dE_dN[ly + 1, 1] +
                                          w[ly + 1][cell, 2] * dE_dN[ly + 1, 2] +
                                          w[ly + 1][cell, 3] * dE_dN[ly + 1, 3];
                    }

                    //w-((δE/δNET)(δNET/δw))
                    for (int n = 0; n < cell; n++)
                    {
                        w[0][0, n] = w[0][0, n] - (a * dE_dN[0, n]);
                        w[0][1, n] = w[0][1, n] - (b * dE_dN[0, n]);
                        w[0][2, n] = w[0][2, n] - (c * dE_dN[0, n]);
                        w[0][3, n] = w[0][3, n] -      dE_dN[0, n];
                    }
                    for (int ly = 1; ly < layer; ly++)
                    {
                        for (int cl = 0; cl < cell; cl++)
                        {
                            for (int n = 0; n < cell; n++)
                            {
                                w[ly][cl, n] = w[ly][cl, n] - (h_out[cl][n] * dE_dN[cl, n]);
                            }
                        }

                        for (int n = 0; n < cell; n++)
                        {
                            w[ly][cell, n] = w[ly][cell, n] - (h_out[cell][n] * dE_dN[cell, n]);
                        }
                    }
                    for (int n = 0; n < 2; n++)
                    {
                        w[layer][0, n] = w[layer][0, n] - (h_out[layer - 1][0] * deltaE[n]);
                        w[layer][1, n] = w[layer][1, n] - (h_out[layer - 1][1] * deltaE[n]);
                        w[layer][2, n] = w[layer][2, n] - (h_out[layer - 1][2] * deltaE[n]);
                        w[layer][3, n] = w[layer][3, n] - (h_out[layer - 1][3] * deltaE[n]);
                        w[layer][4, n] = w[layer][4, n] -                        deltaE[n];
                    }

                    /*/////////////////////////////////////////メモ/////////////////////////////////////////
                    //(δE / δnetYα)  (δE / δoutYα)(δoutYα / δnetYα)
                    double dE_dnetY0 = deltaE[0];
                    //(δE / δnetYβ)  (δE / δoutYβ)(δoutYβ / δnetYβ)
                    double dE_dnetY1 = deltaE[1];
                    //(δE / δnetH40)   (δE / δoutY)(δoutY / δnetH40)
                    double dE_dnetH40 = h4_0_out * (1 - h4_0_out) * ((w[5][0, 0] * deltaE[0]) + (w[5][0, 1] * deltaE[1]));
                    //(δE / δnetH30)   (δE / δoutY)(δoutY / δnetH30)
                    double dE_dnetH30 = h3_0_out * (1 - h3_0_out) * (w[4][0, 0] * dE_dnetH40 + w[4][0, 1] * dE_dnetH41 + w[4][0, 2] * dE_dnetH42 + w[4][0, 3] * dE_dnetH43);

                    w[5][0, 0] = w[5][0, 0] - (h_out[4][0] * deltaE[0]);
                    w[5][0, 1] = w[5][0, 1] - (h_out[4][0] * deltaE[1]);

                    w[4][0, 0] = w[4][0, 0] - (h_out[3][0] * h_out[4][0] * (1 - h_out[4][0]) * (w[5][0, 0] * 1 * deltaE[0] +
                                                                                                w[5][0, 1] * 1 * deltaE[1]));

                    w[3][0, 0] = w[3][0, 0] - (h_out[2][0] * h_out[3][0] * (1 - h_out[3][0]) * (w[4][0, 0] * (δE / δnet40) +
                                                                                                w[4][0, 1] * (δE / δnet41) +
                                                                                                w[4][0, 2] * (δE / δnet42) +
                                                                                                w[4][0, 3] * (δE / δnet43) ));

                    w[0][0, 0] = w[0][0, 0] - (a * h0_0_out * (1 - h0_0_out) * (w[1][0, 0] * (h1_0_out * (1 - h1_0_out) * (w[2][0, 0] * (δE / δnet30) + w[2][0, 1] * (δE / δnet31) + w[2][0, 2] * (δE / δnet32) + w[2][0, 3] * (δE / δnet33))) +
                                                                                w[1][0, 1] * (h1_1_out * (1 - h1_1_out) * (w[2][1, 0] * (δE / δnet30) + w[2][1, 1] * (δE / δnet31) + w[2][1, 2] * (δE / δnet32) + w[2][1, 3] * (δE / δnet33))) +
                                                                                w[1][0, 2] * (h1_2_out * (1 - h1_2_out) * (w[2][2, 0] * (δE / δnet30) + w[2][2, 1] * (δE / δnet31) + w[2][2, 2] * (δE / δnet32) + w[2][2, 3] * (δE / δnet33))) +
                                                                                w[1][0, 3] * (h1_3_out * (1 - h1_3_out) * (w[2][3, 0] * (δE / δnet30) + w[2][3, 1] * (δE / δnet31) + w[2][3, 2] * (δE / δnet32) + w[2][3, 3] * (δE / δnet33))) ));

                    w[1][3, 1] = w[1][3, 1] - (h0_3_out * h1_1_out * (1 - h1_1_out) * (w[2][1, 0] * (δE / δnet20) +
                                                                                       w[2][1, 1] * (δE / δnet21) +
                                                                                       w[2][1, 2] * (δE / δnet22) +
                                                                                       w[2][1, 3] * (δE / δnet23) ));
                    /////////////////////////////////////////メモ/////////////////////////////////////////*/

                    /*
                    Invoke(new dldl(delegate
                    {
                        dataGridView1.Rows.Add(
                            a.ToString(), b.ToString(), c.ToString(), d.ToString(),
                            alpha.ToString(), beta.ToString(),
                            w0[0, 0].ToString(), w0[0, 1].ToString(), w0[0, 2].ToString(),
                            w0[1, 0].ToString(), w0[1, 1].ToString(), w0[1, 2].ToString(),
                            w0[2, 0].ToString(), w0[2, 1].ToString(), w0[2, 2].ToString(),
                            w0[3, 0].ToString(), w0[3, 1].ToString(), w0[3, 2].ToString(),
                            h0_0_in.ToString(), h0_0_out.ToString(),
                            h0_1_in.ToString(), h0_1_out.ToString(),
                            h0_2_in.ToString(), h0_2_out.ToString(),
                            w1[0, 0].ToString(), w1[0, 1].ToString(),
                            w1[1, 0].ToString(), w1[1, 1].ToString(),
                            w1[2, 0].ToString(), w1[2, 1].ToString(),
                            w1[3, 0].ToString(), w1[3, 1].ToString(),
                            OUT0_in.ToString(), OUT0_out.ToString(),
                            OUT1_in.ToString(), OUT1_out.ToString(),
                            mE[0].ToString(), mE[1].ToString()
                            );
                        Refresh();
                    }));

                    //backward
                    w0[0, 0] = w0[0, 0] - (a * s(-h0_0_out) * (1 - s(-h0_0_out)) * ((w1[0, 0] * -mE[0]) + (w1[0, 1] * -mE[1])));
                    w0[0, 1] = w0[0, 1] - (a * s(-h0_1_out) * (1 - s(-h0_1_out)) * ((w1[1, 0] * -mE[0]) + (w1[1, 1] * -mE[1])));
                    w0[0, 2] = w0[0, 2] - (a * s(-h0_2_out) * (1 - s(-h0_2_out)) * ((w1[2, 0] * -mE[0]) + (w1[2, 1] * -mE[1])));

                    w0[1, 0] = w0[1, 0] - (b * s(-h0_0_out) * (1 - s(-h0_0_out)) * ((w1[0, 0] * -mE[0]) + (w1[0, 1] * -mE[1])));
                    w0[1, 1] = w0[1, 1] - (b * s(-h0_1_out) * (1 - s(-h0_1_out)) * ((w1[1, 0] * -mE[0]) + (w1[0, 1] * -mE[1])));
                    w0[1, 2] = w0[1, 2] - (b * s(-h0_2_out) * (1 - s(-h0_2_out)) * ((w1[2, 0] * -mE[0]) + (w1[0, 1] * -mE[1])));

                    w0[2, 0] = w0[2, 0] - (c * s(-h0_0_out) * (1 - s(-h0_0_out)) * ((w1[0, 0] * -mE[0]) + (w1[0, 1] * -mE[1])));
                    w0[2, 1] = w0[2, 1] - (c * s(-h0_1_out) * (1 - s(-h0_1_out)) * ((w1[1, 0] * -mE[0]) + (w1[1, 1] * -mE[1])));
                    w0[2, 2] = w0[2, 2] - (c * s(-h0_2_out) * (1 - s(-h0_2_out)) * ((w1[2, 0] * -mE[0]) + (w1[2, 1] * -mE[1])));

                    w0[3, 0] = w0[3, 0] - (    s(-h0_0_out) * (1 - s(-h0_0_out)) * ((w1[0, 0] * -mE[0]) + (w1[0, 1] * -mE[1])));
                    w0[3, 1] = w0[3, 1] - (    s(-h0_1_out) * (1 - s(-h0_1_out)) * ((w1[1, 0] * -mE[0]) + (w1[1, 1] * -mE[1])));
                    w0[3, 2] = w0[3, 2] - (    s(-h0_2_out) * (1 - s(-h0_2_out)) * ((w1[2, 0] * -mE[0]) + (w1[2, 1] * -mE[1])));


                    w1[0, 0] = w1[0, 0] - (h0_0_out * -mE[0]);
                    w1[1, 0] = w1[1, 0] - (h0_1_out * -mE[0]);
                    w1[2, 0] = w1[2, 0] - (h0_2_out * -mE[0]);
                    w1[3, 0] = w1[3, 0] - (-mE[0]);

                    w1[0, 1] = w1[0, 1] - (h0_0_out * -mE[1]);
                    w1[1, 1] = w1[1, 1] - (h0_1_out * -mE[1]);
                    w1[2, 1] = w1[2, 1] - (h0_2_out * -mE[1]);
                    w1[3, 1] = w1[3, 1] - (-mE[1]);
                    */
                }
            }

            //記録
            using (StreamWriter sw = new StreamWriter(path, true, Encoding.Unicode))
            {
                sw.Write(
                    ",,,," +
                    ",," +

                    w[0][0, 0].ToString() + "," + w[0][0, 1].ToString() + "," + w[0][0, 2].ToString() + "," + w[0][0, 3].ToString() + "," +
                    w[0][1, 0].ToString() + "," + w[0][1, 1].ToString() + "," + w[0][1, 2].ToString() + "," + w[0][1, 3].ToString() + "," +
                    w[0][2, 0].ToString() + "," + w[0][2, 1].ToString() + "," + w[0][2, 2].ToString() + "," + w[0][2, 3].ToString() + "," +
                    w[0][3, 0].ToString() + "," + w[0][3, 1].ToString() + "," + w[0][3, 2].ToString() + "," + w[0][3, 3].ToString() + "," +

                    ",," +
                    ",," +
                    ",," +
                    ",," +

                    w[1][0, 0].ToString() + "," + w[1][0, 1].ToString() + "," + w[1][0, 2].ToString() + "," + w[1][0, 3].ToString() + "," +
                    w[1][1, 0].ToString() + "," + w[1][1, 1].ToString() + "," + w[1][1, 2].ToString() + "," + w[1][1, 3].ToString() + "," +
                    w[1][2, 0].ToString() + "," + w[1][2, 1].ToString() + "," + w[1][2, 2].ToString() + "," + w[1][2, 3].ToString() + "," +
                    w[1][3, 0].ToString() + "," + w[1][3, 1].ToString() + "," + w[1][3, 2].ToString() + "," + w[1][3, 3].ToString() + "," +
                    w[1][4, 0].ToString() + "," + w[1][4, 1].ToString() + "," + w[1][4, 2].ToString() + "," + w[1][4, 3].ToString() + "," +

                    ",," +
                    ",," +
                    ",," +
                    ",," +

                    w[2][0, 0].ToString() + "," + w[2][0, 1].ToString() + "," + w[2][0, 2].ToString() + "," + w[2][0, 3].ToString() + "," +
                    w[2][1, 0].ToString() + "," + w[2][1, 1].ToString() + "," + w[2][1, 2].ToString() + "," + w[2][1, 3].ToString() + "," +
                    w[2][2, 0].ToString() + "," + w[2][2, 1].ToString() + "," + w[2][2, 2].ToString() + "," + w[2][2, 3].ToString() + "," +
                    w[2][3, 0].ToString() + "," + w[2][3, 1].ToString() + "," + w[2][3, 2].ToString() + "," + w[2][3, 3].ToString() + "," +
                    w[2][4, 0].ToString() + "," + w[2][4, 1].ToString() + "," + w[2][4, 2].ToString() + "," + w[2][4, 3].ToString() + "," +

                    ",," +
                    ",," +
                    ",," +
                    ",," +

                    w[3][0, 0].ToString() + "," + w[3][0, 1].ToString() + "," + w[3][0, 2].ToString() + "," + w[3][0, 3].ToString() + "," +
                    w[3][1, 0].ToString() + "," + w[3][1, 1].ToString() + "," + w[3][1, 2].ToString() + "," + w[3][1, 3].ToString() + "," +
                    w[3][2, 0].ToString() + "," + w[3][2, 1].ToString() + "," + w[3][2, 2].ToString() + "," + w[3][2, 3].ToString() + "," +
                    w[3][3, 0].ToString() + "," + w[3][3, 1].ToString() + "," + w[3][3, 2].ToString() + "," + w[3][3, 3].ToString() + "," +
                    w[3][4, 0].ToString() + "," + w[3][4, 1].ToString() + "," + w[3][4, 2].ToString() + "," + w[3][4, 3].ToString() + "," +

                    ",," +
                    ",," +
                    ",," +
                    ",," +

                    w[4][0, 0].ToString() + "," + w[4][0, 1].ToString() + "," + w[4][0, 2].ToString() + "," + w[4][0, 3].ToString() + "," +
                    w[4][1, 0].ToString() + "," + w[4][1, 1].ToString() + "," + w[4][1, 2].ToString() + "," + w[4][1, 3].ToString() + "," +
                    w[4][2, 0].ToString() + "," + w[4][2, 1].ToString() + "," + w[4][2, 2].ToString() + "," + w[4][2, 3].ToString() + "," +
                    w[4][3, 0].ToString() + "," + w[4][3, 1].ToString() + "," + w[4][3, 2].ToString() + "," + w[4][3, 3].ToString() + "," +
                    w[4][4, 0].ToString() + "," + w[4][4, 1].ToString() + "," + w[4][4, 2].ToString() + "," + w[4][4, 3].ToString() + "," +

                    ",," +
                    ",," +
                    ",," +
                    ",," +

                    w[5][0, 0].ToString() + "," + w[5][0, 1].ToString() + "," +
                    w[5][1, 0].ToString() + "," + w[5][1, 1].ToString() + "," +
                    w[5][2, 0].ToString() + "," + w[5][2, 1].ToString() + "," +
                    w[5][3, 0].ToString() + "," + w[5][3, 1].ToString() + "," +
                    w[5][4, 0].ToString() + "," + w[5][4, 1].ToString() + "," +

                    ",,," +
                    ",," +

                    Environment.NewLine);
            }

            //読取専用
            File.SetAttributes(path, FileAttributes.ReadOnly);

            Invoke(new dldl(delegate
            {
                sw.Stop();
                label2.Text = sw.Elapsed.ToString();
                button1.Enabled = true;
            }));
        }

        private double s(double x)
        {
            return 1.0/(1.0 + Math.Exp(-x));
        }

        private delegate void dldl();

        private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            //列ヘッダーかどうか調べる
            if (e.ColumnIndex < 0 && e.RowIndex >= 0)
            {
                //セルを描画する
                e.Paint(e.ClipBounds, DataGridViewPaintParts.All);

                //行番号を描画する範囲を決定する
                //e.AdvancedBorderStyleやe.CellStyle.Paddingは無視しています
                Rectangle indexRect = e.CellBounds;
                indexRect.Inflate(-2, -2);
                //行番号を描画する
                TextRenderer.DrawText(e.Graphics,
                    (e.RowIndex + 1).ToString(),
                    e.CellStyle.Font,
                    indexRect,
                    e.CellStyle.ForeColor,
                    TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
                //描画が完了したことを知らせる
                e.Handled = true;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            sw.Start();
            Thread th = new Thread(nnw);
            th.Start();
        }
```