機械学習で二次方程式の解 1

```math
a(x-α)(x-β)=0
```
a = 1 で固定し
解α,βを正の整数0～100までの組み合わせ
(0,0)
(0,1)
...
(100,99)
(100,100)
101×101=10201通りを学習させてみました。
ニューラルネットワークはとりあえずこうしてみました。
出力は恒等関数です。
図のxの使い方がややおかしいとは思いますが感じは伝わっていると思います。
![二次方程式.png](https://qiita-image-store.s3.amazonaws.com/0/207542/49af06a1-d0fe-2faf-d631-c950ba383c5e.png)

学習率は1で何もしてません。
当然、駄目でした。
![a=1.png](https://qiita-image-store.s3.amazonaws.com/0/207542/c3be81ec-d1b5-0651-6cbd-c6dbfd85e428.png)



ちゃんと書くのがめんどうなので
反響があったらまじめに書きます。

```csharp
        double[,] w0 = 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}};

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

        private void core()
        {
            for (double alpha = 0; alpha <= 100; alpha++)
            {
                for (double beta = 0; beta <= 100; beta++)
                {
                    //
                    double a = 1;
                    double b = -(alpha + beta);
                    double c = alpha * beta;
                    double d = b * b - 4 * a * c;

                    //forward
                    double h0_0_in = a * w0[0, 0] + b * w0[1, 0] + c * w0[2, 0] + w0[3, 0];
                    double h0_1_in = a * w0[0, 1] + b * w0[1, 1] + c * w0[2, 1] + w0[3, 1];
                    double h0_2_in = a * w0[0, 2] + b * w0[1, 2] + c * w0[2, 2] + w0[3, 2];

                    double h0_0_out = s(h0_0_in);
                    double h0_1_out = s(h0_1_in);
                    double h0_2_out = s(h0_2_in);

                    double o_0_in = h0_0_out * w1[0, 0] + h0_1_out * w1[1, 0] + h0_2_out * w1[2, 0] + w1[3, 0];
                    double o_1_in = h0_0_out * w1[0, 1] + h0_1_out * w1[1, 1] + h0_2_out * w1[2, 1] + w1[3, 1];

                    double o_0_out = o_0_in;
                    double o_1_out = o_1_in;

                    double[] mE = new double[] { o_0_out - alpha, o_1_out - beta };

                    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(),
                            o_0_in.ToString(), o_0_out.ToString(),
                            o_1_in.ToString(), o_1_out.ToString(),
                            mE[0].ToString(), mE[1].ToString()
                            );
                        Refresh();
                    }));

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

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

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

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

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

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

            Invoke(new dldl(delegate
            {
                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;
            Thread th = new Thread(core);
            th.Start();
        }
```