NumSharp で損失関数

「ゼロから作る Deep Learning」を読んで、C# でゼロから作ってみる続き。MNIST データセットを使ったニューラルネットの実装は、配布されているパラメーターのファイルが Pickle 形式だったのでスキップ。損失関数に進むことにした。

NumSharp を使って、2乗和誤差と交差エントロピー誤差、2つの損失関数を実装してみた。

using NumSharp;

{
    // 正解を 2 とする
    var t = new double[] { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };

    // 例1: 「2」の確率が最も高い場合 (0.6)
    var y = new double[] { 0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0 };
    Console.WriteLine(mean_squared_error(np.array(y), np.array(t)).ToString());

    // 例2: 「7」の確率が最も高い場合 (0.6)
    y = new double[] { 0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0 };
    Console.WriteLine(mean_squared_error(np.array(y), np.array(t)).ToString());
}

{
    var t = new double[] { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
    var y = new double[] { 0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0 };
    Console.WriteLine(cross_entropy_error(np.array(y), np.array(t)).ToString());

    y = new double[] { 0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0 };
    Console.WriteLine(cross_entropy_error(np.array(y), np.array(t)).ToString());
}

Console.ReadLine();

// 2乗和誤差
static NDArray mean_squared_error(NDArray y, NDArray t)
{
    return 0.5 * np.sum((y - t) * (y - t), NPTypeCode.Double);
}

// 交差エントロピー誤差
static NDArray cross_entropy_error(NDArray y, NDArray t)
{
    var delta = 1e-7;
    return (-1) * np.sum(t * np.log(y + delta), NPTypeCode.Double);
}

.NET 6 で実行。

(y - t)^2 みたいに書きたかったけど、NDArray は ^ 演算子オーバーロードしていなかったので、同じ値を掛けて代用。なかなか NumPy そのままとはいかないな。