C# でゼロから Deep Learning を実装する挑戦を少しずつ進めている。 まだ第 4 章だけど。 今回は勾配を実装してみた。
using MathNet.Numerics.LinearAlgebra; using System; using System.Linq; namespace NumericGradientSample { class Program { static void Main(string[] args) { Func<Vector<double>, double> function2 = x => x[0] * x[0] + x[1] * x[1]; Console.WriteLine("(x0, x1) = (3.0, 4.0) のとき"); Console.WriteLine( NumericalGradient( function2, Vector<double>.Build.DenseOfArray(new[] { 3.0, 4.0 }))); Console.WriteLine("(x0, x1) = (0.0, 2.0) のとき"); Console.WriteLine( NumericalGradient( function2, Vector<double>.Build.DenseOfArray(new[] { 0.0, 2.0 }))); Console.WriteLine("(x0, x1) = (3.0, 0.0) のとき"); Console.WriteLine( NumericalGradient( function2, Vector<double>.Build.DenseOfArray(new[] { 3.0, 0.0 }))); Console.ReadLine(); } static Vector<double> NumericalGradient(Func<Vector<double>, double> f, Vector<double> x) { var h = 0.0001; var grad = Vector<double>.Build.Dense(x.Count); foreach (var idx in Enumerable.Range(0, x.Count)) { var tmpVal = x[idx]; // f(x+h) の計算 x[idx] = tmpVal + h; var fxh1 = f(x); // f(x-h) の計算 x[idx] = tmpVal - h; var fxh2 = f(x); grad[idx] = (fxh1 - fxh2) / (2 * h); // 値を元に戻す x[idx] = tmpVal; } return grad; } } }
実行結果がこちら。