数値微分を実装してみた

C# でゼロから Deep Learning を実装する挑戦の続き。 今回は第 4 章の数値微分を実装してみた。

using System;

namespace NumericalDifferentiationSample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 微分
            Func<double, double> function1 =
                x => 0.01 * Math.Pow(x, 2) + 0.1 * x;
            Console.WriteLine("y = 0.01x^2 + 0.1x");
            Console.WriteLine($"x = 5,  y = {NumericalDiff(function1, 5)}");
            Console.WriteLine($"x = 10, y = {NumericalDiff(function1, 10)}");
            Console.WriteLine();

            // 偏微分
            Func<double, double, double> function2 =
                (x0, x1) => Math.Pow(x0, 2) + Math.Pow(x1, 2);
            Console.WriteLine("f(x0, x1) = x0^2 + x1^2");
            Console.WriteLine("x0 = 3.0, x1 = 4.0 のとき");

            Func<double, double> functionTemp1
                = (x0) => function2(x0, 4);
            Console.WriteLine($"x0 に対する偏微分 : {NumericalDiff(functionTemp1, 3)}");

            Func<double, double> functionTemp2
                = (x1) => function2(3, x1);
            Console.WriteLine($"x1 に対する偏微分 : {NumericalDiff(functionTemp2, 4)}");

            Console.ReadLine();
        }

        static double NumericalDiff(Func<double, double> f, double x)
        {
            var h = 1e-4;   // 0.0001
            return (f(x + h) - f(x - h)) / (2 * h);
        }
    }
}

実行結果は次の通り。 偏微分の結果に誤差が出てしまっている。

余談だけど、『ゼロからつくる Deep Learning』に書いてある微分の説明は非常に分かりやすいと思った。 自分が学生の頃使った教科書も、これぐらい分かりやすく書いてあればな。