public static Array <Real> Min(this Array <Real> a, int axis, bool keepDims = false, Array <Real> result = null)
        {
            if (axis < 0)
            {
                axis = a.Shape.Length + axis;
            }
            result = result ?? NN.Zeros <Real>(GetAggregatorResultShape(a, axis, keepDims));

            bool firstTime = true;

            foreach (var row in a.UnsafeRows(axis, keepDims))
            {
                if (firstTime)
                {
                    result._  = row;
                    firstTime = false;
                }
                else
                {
                    NN.Apply(result, row, (x, y) => Math.Min(x, y), result: result);
                }
            }

            return(result);
        }
Beispiel #2
0
        public Tsne(Array <float> X_, int dims, float perplexity)
        {
            X_.AssertOfDim(2);
            int n = X_.Shape[0];

            X = T.Shared(X_, "X");
            Y = T.Shared(NN.Random.Uniform(-1f, 1f, n, dims), "Y");

            YMomentum = T.Shared(NN.Zeros(n, dims), "YMomentum");
            dYLast    = T.Shared(NN.Zeros(n, dims), "dYLast");

            // ones everywhere, zero on the diag
            mask = T.Shared(NN.Ones(n, n) - NN.Eye(n), "mask");

            // Compute pairwise affinities
            var sum_Y = T.Sum(Y * Y, 1, keepDims: true);

            var num = 1 / (1 - T.DimShuffle((2 * T.Dot(Y, Y, transposeY: true) + sum_Y), 1, 0) + sum_Y);

            // set the diag to zero
            num *= mask;

            var Q = num / T.Sum(num);
            //Q = T.Max(Q, 1e-12f);

            var P_ = x2p(X_, 1e-5f, perplexity);

            P_ = P_ * 4f; // early exaggeration
            P_ = NN.Apply(P_, x => Math.Max(x, 1e-12f));
            P  = T.Shared(P_, "P");

            KL_Loss = T.Sum(P * T.Log(P / Q));

            dY   = T.Function(output: T.Grad(KL_Loss, Y));
            Loss = T.Function(output: KL_Loss);

            var updates = MomentumUpdate(Y, YMomentum, dYLast, T.Grad(KL_Loss, Y), 500);

            Train = T.Function(updates);
        }
Beispiel #3
0
        public void CompareElementWisePerformance()
        {
            Trace.Listeners.Add(new ConsoleTraceListener());

            Func <float, float, float> f = (x, y) => x + y;
            var clock = new Stopwatch();

#if DEBUG
            Trace.WriteLine($"Testing on DEBUG");
#else
            Trace.WriteLine($"Testing on RELEASE");
#endif
            Trace.WriteLine($"Testing on {Blas.NThreads} threads");

            for (int i = 0; i < 300; ++i)
            {
                int n = i + 1;
                var a = NN.Random.Uniform(-1f, 1f, n, n);
                var b = NN.Random.Uniform(-1f, 1f, n, n);
                var r = NN.Zeros(n, n);

                var size = a.Size;
                // estimating loop count for this size
                NN.MIN_SIZE_FOR_PARELLELISM = size * 2;
                var loopCount = 0;
                clock.Restart();

                while (clock.ElapsedMilliseconds < 1000)
                {
                    NN.Apply(a, b, f, result: r);
                    ++loopCount;
                }
                Trace.WriteLine($"doing {loopCount} loops for size {size}");

                // profiling Normal
                clock.Restart();
                for (int _ = 0; _ < loopCount; _++)
                {
                    NN.Apply(a, b, f, result: r);
                }
                var time = clock.ElapsedMilliseconds;
                var avg  = (double)time / loopCount;

                // profiling Parrellized
                NN.MIN_SIZE_FOR_PARELLELISM = 0;
                clock.Restart();
                for (int _ = 0; _ < loopCount; _++)
                {
                    NN.Apply(a, b, f, result: r);
                }
                var timePar = clock.ElapsedMilliseconds;
                var avgPar  = (double)timePar / loopCount;

                clock.Restart();
                for (int _ = 0; _ < loopCount; _++)
                {
                    a.Add(b, result: r);
                }
                var timeAdd = clock.ElapsedMilliseconds;
                var avgAdd  = (double)timeAdd / loopCount;

                clock.Restart();
                for (int _ = 0; _ < loopCount; _++)
                {
                    Blas.vadd(size, a.Values, 0, b.Values, 0, r.Values, 0);
                }
                var timeBlas = clock.ElapsedMilliseconds;
                var avgBlas  = (double)timeBlas / loopCount;

                var message = $"On size {size}, avg time: {avg:F4}ms \t with parallelism {avgPar:F4}ms \t with Add {avgAdd:F4}ms \t with Blas {avgBlas:F4}ms.";
                Trace.WriteLine(message);
            }

            throw new Exception("see output for profiler results");
        }