/// Sigmoid関数 public static AutoDiff Sigmoid(AutoDiff x) { var z = new AutoDiff(1 / (1 + Math.Exp(-x.Val)), 1); z.AddInput(0, x, (1 - z.Val) * z.Val); return(z); }
/// 絶対値関数 public static AutoDiff Abs(AutoDiff x) { var z = new AutoDiff(Math.Abs(x.Val), 1); z.AddInput(0, x, x.Val < 0 ? -1 : 1); return(z); }
/// Rectified Linear Unit /// <param name="x"></param> /// <returns></returns> public static AutoDiff ReLU(AutoDiff x) { var z = new AutoDiff(Math.Max(0, x.Val), 1); z.AddInput(0, x, x.Val > 0 ? 1 : 0); return(z); }
/// Exp関数 public static AutoDiff Exp(AutoDiff x) { var z = new AutoDiff(Math.Exp(x.Val), 1); z.AddInput(0, x, z.Val); return(z); }
/// Cos関数 public static AutoDiff Cos(AutoDiff x) { var z = new AutoDiff(Math.Cos(x.Val), 1); z.AddInput(0, x, -Math.Sin(x.Val)); return(z); }
/// Sqrt関数 public static AutoDiff Sqrt(AutoDiff x) { var z = new AutoDiff(Math.Sqrt(x.Val), 1); z.AddInput(0, x, 0.5 / z.Val); return(z); }
/// -単項演算子のオーバーロード public static AutoDiff operator -(AutoDiff x) { var z = new AutoDiff(-x.Val, 1); z.AddInput(0, x, -1); return(z); }
/// Tanh関数 public static AutoDiff Tanh(AutoDiff x) { var z = new AutoDiff(Math.Tanh(x.Val), 1); z.AddInput(0, x, 1 - z.Val * z.Val); return(z); }
/// 累乗関数 x^y public static AutoDiff Pow(AutoDiff x, AutoDiff y) { var z = new AutoDiff(Math.Pow(x.Val, y.Val), 2); z.AddInput(0, x, y.Val * Math.Pow(x.Val, y.Val - 1)); z.AddInput(1, y, z.Val * Math.Log(x.Val)); return(z); }
/// *演算子のオーバーロード public static AutoDiff operator *(AutoDiff x, AutoDiff y) { var z = new AutoDiff(x.Val * y.Val, 2); z.AddInput(0, x, y.Val); z.AddInput(1, y, x.Val); return(z); }
/// Tan関数 public static AutoDiff Tan(AutoDiff x) { var z = new AutoDiff(Math.Tan(x.Val), 1); double cos = Math.Cos(x.Val); z.AddInput(0, x, 1 / (cos * cos)); return(z); }
/// Log関数 public static AutoDiff Log(AutoDiff x, double a) { const double delta = 1e-13; var z = new AutoDiff(Math.Log(x.Val + delta, a), 1); z.AddInput(0, x, 1 / ((x.Val + delta) * Math.Log(a))); return(z); }
/// /演算子のオーバーロード public static AutoDiff operator /(AutoDiff x, AutoDiff y) { var z = new AutoDiff(x.Val / y.Val, 2); z.AddInput(0, x, 1 / y.Val); z.AddInput(1, y, -x.Val / (y.Val * y.Val)); return(z); }
/// -演算子のオーバーロード public static AutoDiff operator -(AutoDiff x, AutoDiff y) { var z = new AutoDiff(x.Val - y.Val, 2); z.AddInput(0, x, 1); z.AddInput(1, y, -1); return(z); }
/// 合計関数 public static AutoDiff Sum(AutoDiff[] x) { var z = new AutoDiff(0, x.Length); for (int i = 0; i < x.Length; i++) { z.Val += x[i].Val; z.AddInput(i, x[i], 1); } return(z); }
/// 平均関数 public static AutoDiff Average(AutoDiff[] x) { var z = new AutoDiff(0, x.Length); for (int i = 0; i < x.Length; i++) { z.Val += x[i].Val; z.AddInput(i, x[i], 1.0 / x.Length); } z.Val /= x.Length; return(z); }
/// 内積関数 public static AutoDiff InnerProd(AutoDiff[] x, AutoDiff[] y) { var N = Math.Min(x.Length, y.Length); var z = new AutoDiff(0, 2 * N); for (int i = 0; i < N; i++) { z.Val += x[i].Val * y[i].Val; z.AddInput(i, x[i], y[i].Val); z.AddInput(i + N, y[i], x[i].Val); } return(z); }
/// Max関数 public static AutoDiff Max(AutoDiff x, AutoDiff y) { return(x.Val > y.Val ? +x : +y); }
/// 入力変数と対応する偏微分値を追加する public void AddInput(int index, AutoDiff input, double diff) { this.Inputs[index] = input; this.Differentials[index] = diff; }
/// Min関数 public static AutoDiff Min(AutoDiff x, AutoDiff y) { return(x.Val < y.Val ? +x : +y); }