public NDArray <Type> Broadcast(params int[] args) { int sLength = Shape.Length; int nLength = args.Length; int mLength = Math.Max(sLength, nLength); int[] nshape = new int[mLength]; for (int k = mLength - 1, i = sLength - 1, j = nLength - 1; k >= 0; --k, --i, --j) { int idx0 = i < 0 ? 1 : Shape[i]; int idx1 = j < 0 ? 1 : args[j]; if (idx0 != idx1 && idx0 != 1 && idx1 != 1) { throw new ArgumentException($"Cannot broadcast {Shape.Glue("x")} with {args.Glue("x")}"); } nshape[k] = Math.Max(idx0, idx1); } int dim = NumDN.ShapeCapacity(nshape); var nd = new NDArray <Type>(nshape); var idxArr = new int[sLength]; for (int k = 0; k < dim; ++k) { nd.BcIndex2Array(k, Shape, idxArr); Array2Index(idxArr, out int j); nd.items[k] = items[j]; } return(nd); }
public override void Initialize(IOptimizer <Type> optimizer) { double lim = 1.0 / Math.Sqrt(Inputs); W = NumDN.Uniform <Type>(-lim, lim, Inputs, Outputs); w0 = NDArray <Type> .Zeros(1, Outputs); WOpt = optimizer.Clone(); w0Opt = optimizer.Clone(); }
public NDArray(Type[] nd, int[] shape) { int dim = NumDN.ShapeCapacity(shape); if (dim <= 0) { throw new ArgumentException(); } Shape = shape.ToArray(); items = nd.ToArray(); }
public NDArray(Type v, int[] shape) { int dim = NumDN.ShapeCapacity(shape); if (dim <= 0) { throw new ArgumentException(); } Shape = shape.ToArray(); items = Enumerable.Repeat(v, dim).ToArray(); }
public NDArray <Type> ReShape(params int[] args) { int oldDim = NumDN.ShapeCapacity(Shape); int newDim = NumDN.ShapeCapacity(args); if (oldDim != newDim) { throw new ArgumentException(); } var ndarr = new NDArray <Type>(this); ndarr.Shape = args.Length != 0 ? args.ToArray() : new int[] { 1 }; return(ndarr); }
public override NDArray <Type> Backward(NDArray <Type> accumGrad) { var Wtmp = new NDArray <Type>(W); if (trainable) { var gW = NDArray <Type> .Dot(layerInput.T, accumGrad); var gw0 = (new NDArray <Type>(accumGrad.Shape)) + NumDN.Sum(accumGrad); W = WOpt.Update(W, gW); w0 = w0Opt.Update(w0, gw0); } var accumGrad0 = NDArray <Type> .Dot(accumGrad, W.T); return(accumGrad0); }
public NDArray <Type> this[int i] { get { if (i >= Shape[0] || i < -1) { throw new ArgumentException(); } var dim0 = NumDN.ShapeCapacity(Shape); var dim1 = dim0 / Shape[0]; var nshape = Shape.Skip(1).ToArray(); var start = i * dim1; var nd = new NDArray <Type>(nshape); for (int j = 0, k = start; j < dim1; ++j, ++k) { nd.items[j] = items[k]; } return(nd); } set { var dim0 = NumDN.ShapeCapacity(Shape); var dim1 = NumDN.ShapeCapacity(value.Shape); if (dim0 / dim1 != Shape[0] || i >= Shape[0] || i < 0) { throw new ArgumentException(); } var start = i * dim1; for (int j = 0, k = start; j < dim1; ++j, ++k) { items[k] = value.items[j]; } } }
static NDArray <Type> ElementOps(NDArray <Type> nD0, NDArray <Type> nD1, Func <Type, Type, Type> func) { int sLength0 = nD0.Shape.Length; int sLength1 = nD1.Shape.Length; int mLength = Math.Max(sLength0, sLength1); int[] nshape = new int[mLength]; for (int k = mLength - 1, i = sLength0 - 1, j = sLength1 - 1; k >= 0; --k, --i, --j) { int idx0 = i < 0 ? 1 : nD0.Shape[i]; int idx1 = j < 0 ? 1 : nD1.Shape[j]; if (idx0 != idx1 && idx0 != 1 && idx1 != 1) { throw new ArgumentException($"Cannot broadcast {nD0.Shape.Glue("x")} with {nD1.Shape.Glue("x")}"); } nshape[k] = Math.Max(idx0, idx1); } int dim = NumDN.ShapeCapacity(nshape); var nd = new NDArray <Type>(nshape); var idxArr0 = new int[sLength0]; var idxArr1 = new int[sLength1]; for (int k = 0; k < dim; ++k) { nd.BcIndex2Array(k, nD0.Shape, idxArr0); nd.BcIndex2Array(k, nD1.Shape, idxArr1); nD0.Array2Index(idxArr0, out int i0); nD1.Array2Index(idxArr1, out int i1); nd.items[k] = func(nD0.items[i0], nD1.items[i1]); } return(nd); }
public NDArray <Type> Function(NDArray <Type> x) => NumDN.Sigmoid(x);
public NDArray <Type> Function(NDArray <Type> x) => NumDN.Tanh(x);
public static NDArray <Type> Dot(NDArray <Type> nD0, NDArray <Type> nD1) { if (nD0.Shape.Length == 1) { nD0 = nD0.ReShape(1, nD0.Shape[0]); } if (nD1.Shape.Length == 1) { nD1 = nD1.ReShape(nD1.Shape[0], 1); } int length0 = nD0.Shape.Length; int length1 = nD1.Shape.Length; int commonDim = nD0.Shape.Last(); if (commonDim != nD1.Shape[length1 - 2]) { throw new ArgumentException($"Cannot multiply {nD0.Shape.Glue("x")} and {nD1.Shape.Glue("x")}"); } int[] nshape = new int[length0 + length1 - 2]; int[] idxInfos = new int[length0 + length1 - 2]; for (int k = 0, k0 = 0; k < length0 + length1; ++k) { if (k == length0 - 1 || k == length0 + length1 - 2) { continue; } if (k < length0 - 1) { nshape[k] = nD0.Shape[idxInfos[k] = k]; } else { nshape[k0] = nD1.Shape[idxInfos[k0] = k - length0]; } ++k0; } int[] idxArr0 = new int[length0]; int[] idxArr1 = new int[length1]; int[] idxNArr = new int[nshape.Length]; int dim = NumDN.ShapeCapacity(nshape); var nd = new NDArray <Type>(nshape); for (int m = 0; m < dim; ++m) { Type sum = OpsT.Zero; nd.Index2Array(m, idxNArr); for (int k = 0; k < nshape.Length; ++k) { if (k < length0 - 1) { idxArr0[idxInfos[k]] = idxNArr[k]; } else { idxArr1[idxInfos[k]] = idxNArr[k]; } } for (int i = 0; i < commonDim; ++i) { idxArr0[length0 - 1] = idxArr1[length1 - 2] = i; nD0.Array2Index(idxArr0, out int idx0); nD1.Array2Index(idxArr1, out int idx1); sum = OpsT.Add(sum, OpsT.Mul(nD0.items[idx0], nD1.items[idx1])); } nd.items[m] = sum; } return(nd); }
public NDArray <Type> Gradient(NDArray <Type> x) => 1 - NumDN.Sq(NumDN.Tanh(x));
public NDArray <Type> Function(NDArray <Type> x) { var ex = NumDN.Exp(x - NumDN.Max(x)); return(ex / NumDN.Sum(ex)); }
public NDArray <Type> Loss(NDArray <Type> y, NDArray <Type> p) => 0.5 * NumDN.Sq(y - p);
public NDArray <Type> Gradient(NDArray <Type> x) => NumDN.Sigmoid(x) * (1 - NumDN.Sigmoid(x));
public NDArray <Type> Loss(NDArray <Type> y, NDArray <Type> p) { var p0 = NumDN.Clamp(p, 1e-7, 1 - 1e-7); return(-y *NumDN.Log(p0) - (1 - y) * NumDN.Log(1 - p0)); }
public NDArray <Type> Grad(NDArray <Type> y, NDArray <Type> p) { var p0 = NumDN.Clamp(p, 1e-7, 1 - 1e-7); return(-y / p0 + (1 - y) / (1 - p0)); }