「ゼロから作る 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 そのままとはいかないな。