Esempio n. 1
0
        /// <summary>
        /// Given (symbolic) log-domain potentials, construct the graph for forward inference in a chain CRF.
        /// </summary>
        /// <param name="obs_potentials">(n_steps, n_classes) Axes correspond to time and the value of the discrete label variable
        /// This is the energy assigned to a configuration (so higher energy = lower probability).</param>
        /// <param name="chain_potentials">(n_classes, n_classes, n_classes) Axes correspond to left label state, right label state, and the global label.
        /// Corresponds to the energy of a given pair of labels adjacent to one another (higher energy = lower probability).</param>
        /// <param name="viterbi">Perform MAP inference with the Viterbi algorithm rather than marginalizing the step-specific
        /// label variables, Instead, use the single most likely configuration.</param>
        /// <returns>(1-dimensional) The energy assigned for a given global label.
        /// This can be turned into a log probability by subtracting logsumexp(energy).</returns>
        public static Tensor <float> Forward(Tensor <float> obs_potentials, Tensor <float> chain_potentials, bool viterbi = false)
        {
            Func <Tensor <float>, Tensor <float>, Tensor <float> > inner_function = (obs, prior_result /*, chain_potentials*/) =>
            {
                prior_result = prior_result.DimShuffle(0, 'x', 1);
                obs          = obs.DimShuffle('x', 0, 'x');
                if (viterbi)
                {
                    return(T.Max((-prior_result - obs - chain_potentials), axis: 0));
                }
                else
                {
                    return(LogSumExp(-prior_result - obs - chain_potentials, axis: 0));
                }
            };

            Debug.Assert(obs_potentials.NDim == 2);
            Debug.Assert(chain_potentials.NDim == 3);
            var initial = (obs_potentials[0].DimShuffle(0, 'x') * T.OnesLike(chain_potentials[0]));
            var scanned = T.Scan(
                fn: inner_function,
                outputsInfo: initial,
                sequences: new[] { obs_potentials[XSlicer.From(1)] }
                //non_sequences: chain_potentials
                );

            if (viterbi)
            {
                return(-(T.Max(scanned[-1], axis: 0)));
            }
            else
            {
                return(-LogSumExp(scanned[-1], axis: 0));
            }
        }
Esempio n. 2
0
        public void TestShapeOfSlice()
        {
            var v = T.Shared(0.2f * NN.Random.Uniform(-1.0f, 1.0f, 13).As <float>(), "v");

            AssertArray.WriteTheSame(new[] { 3 }, v[XSlicer.Range(5, 8)].Shape);
            AssertArray.WriteTheSame(new[] { 3 }, v[XSlicer.Range(8, 5, -1)].Shape);
            AssertArray.WriteTheSame(new[] { 4 }, v[XSlicer.Range(3, 11, 2)].Shape);

            var M = T.Shared(0.2f * NN.Random.Uniform(-1.0f, 1.0f, 8, 22).As <float>(), "M");

            AssertArray.WriteTheSame(new[] { 5, 17 }, M[XSlicer.Range(6, 1, -1), XSlicer.From(5)].Shape);
        }
Esempio n. 3
0
        public void TestRecursive()
        {
            // http://deeplearning.net/software/theano/tutorial/loop.html
            // define tensor variables
            var X       = T.Vector <float>("X");
            var W       = T.Matrix <float>("W");
            var b_sym   = T.Matrix <float>("b_sym");
            var U       = T.Matrix <float>("U");
            var Y       = T.Matrix <float>("Y");
            var V       = T.Matrix <float>("V");
            var P       = T.Matrix <float>("P");
            var results = T.Scan((yy, pp, xx_tm1) => T.Tanh(T.Dot(xx_tm1, W) + T.Dot(yy, U) + T.Dot(pp, V)),
                                 sequences: new[] { Y, P[XSlicer.Step(-1)] },
                                 outputsInfo: X);
            var compute_seq = T.Function(inputs: new[] { X, W, Y, U, P, V }, output: results);
            // test values
            var x = NN.Zeros <float>(2);

            x.Item[1] = 1;
            var w = NN.Ones <float>(2, 2);
            var y = NN.Ones <float>(5, 2);

            y.Item[0] = -3;
            var u = NN.Ones <float>(2, 2);
            var p = NN.Ones <float>(5, 2);

            p.Item[0] = 3;
            var v      = NN.Ones <float>(2, 2);
            var result = compute_seq(new[] { x, w, y, u, p, v }); // Array<float>[5] => theano returns Array<float>[5][1]
            // comparison with numpy
            var x_res = NN.Zeros <float>(5, 2);

            x_res[0] = NN.Tanh(x.Dot(w) + y[0].Dot(u) + p[4].Dot(v));
            for (int i = 1; i < 5; i++)
            {
                x_res[i] = NN.Tanh(x_res[i - 1].Dot(w) + y[i].Dot(u) + p[4 - i].Dot(v));
            }

            AssertArray.AreAlmostEqual(x_res, result);
        }