NumSharp でパーセプトロン

以前、「ゼロから作るDeep Learning」を読みながら、C# でゼロから Deep Learning を実装する試みをやっていた。

当時、行列の計算には Math.NET Numerics を使っていたけど、API が NumPy と違い過ぎて、途中で頓挫してしまった…。

numerics.mathdotnet.com

NumPy の C# 移植版と言える NumSharp というものがある。機能は NumPy にだいぶ追いついてそう。NumPy と同じように書けるようにする方針なのも好ましい。

github.com

NumSharp で再挑戦すれば、今度は完走できるかも。まずは、パーセプトロンからやり直してみた。

using NumSharp;

Console.WriteLine("AND");
Console.WriteLine("x1\tx2\ty");
Console.WriteLine($"0\t0\t{AND(0, 0)}");
Console.WriteLine($"1\t0\t{AND(1, 0)}");
Console.WriteLine($"0\t1\t{AND(0, 1)}");
Console.WriteLine($"1\t1\t{AND(1, 1)}");

Console.WriteLine("OR");
Console.WriteLine("x1\tx2\ty");
Console.WriteLine($"0\t0\t{OR(0, 0)}");
Console.WriteLine($"1\t0\t{OR(1, 0)}");
Console.WriteLine($"0\t1\t{OR(0, 1)}");
Console.WriteLine($"1\t1\t{OR(1, 1)}");

Console.WriteLine("NAND");
Console.WriteLine("x1\tx2\ty");
Console.WriteLine($"0\t0\t{NAND(0, 0)}");
Console.WriteLine($"1\t0\t{NAND(1, 0)}");
Console.WriteLine($"0\t1\t{NAND(0, 1)}");
Console.WriteLine($"1\t1\t{NAND(1, 1)}");

Console.WriteLine("XOR");
Console.WriteLine("x1\tx2\ty");
Console.WriteLine($"0\t0\t{XOR(0, 0)}");
Console.WriteLine($"1\t0\t{XOR(1, 0)}");
Console.WriteLine($"0\t1\t{XOR(0, 1)}");
Console.WriteLine($"1\t1\t{XOR(1, 1)}");

Console.ReadLine();

static int AND(int x1, int x2)
{
    var x = np.array<double>(x1, x2);
    var w = np.array(0.5, 0.5);
    var b = -0.7;
    var tmp = np.sum(w * x, typeof(double)) + b;
    if ((double)tmp <= 0)
        return 0;
    else
        return 1;
}

static int NAND(int x1, int x2)
{
    var x = np.array<double>(x1, x2);
    var w = np.array(-0.5, -0.5);
    var b = 0.7;
    var tmp = np.sum(w * x, typeof(double)) + b;
    if ((double)tmp <= 0)
        return 0;
    else
        return 1;
}

static int OR(int x1, int x2)
{
    var x = np.array<double>(x1, x2);
    var w = np.array(0.5, 0.5);
    var b = -0.2;
    var tmp = np.sum(w * x, typeof(double)) + b;
    if ((double)tmp <= 0)
        return 0;
    else
        return 1;
}

static int XOR(int x1, int x2)
{
    var s1 = NAND(x1, x2);
    var s2 = OR(x1, x2);
    var y = AND(s1, s2);
    return y;
}

.NET 6 で実行。

NumPy とは微妙に書き味が違ったけど、Math.NET Numerics と比べたら誤差だな。AND・OR・NAND・XOR がちゃんと動いたのでヨシ!