Пример #1
0
    def build_poe(self, b_frames, tau_frames, win_mats, sdw=None):
        """
            Computes natural parameters for a Gaussian product-of-experts model.
            The natural parameters (b-value vector and precision matrix) are returned.
            The returned precision matrix is stored as a BandMat.
                Mathematically the b-value vector is given as:
            b = \sum_d \transpose{W_d} \tilde{b}_d
                and the precision matrix is given as:
            P = \sum_d \transpose{W_d} \text{diag}(\tilde{tau}_d) W_d
                where $W_d$ is the window matrix for window $d$ as specified by an element
             of `win_mats`, $\tilde{b}_d$ is the sequence over time of b-value
                parameters for window $d$ as given by a column of `b_frames`, and
                $\tilde{\tau}_d$ is the sequence over time of precision parameters for
                window $d$ as given by a column of `tau_frames`.
        """
        if sdw is None:
            sdw = max([win_mat.l + win_mat.u for win_mat in win_mats])
        num_windows = len(win_mats)
        frames = len(b_frames)
        assert np.shape(b_frames) == (frames, num_windows)
        assert np.shape(tau_frames) == (frames, num_windows)
        assert all([win_mat.l + win_mat.u <= sdw for win_mat in win_mats])

        b = np.zeros((frames, ))
        prec = bm.zeros(sdw, sdw, frames)

        for win_index, win_mat in enumerate(win_mats):
            bm.dot_mv_plus_equals(win_mat.T, b_frames[:, win_index], target=b)
            bm.dot_mm_plus_equals(win_mat.T,
                                  win_mat,
                                  target_bm=prec,
                                  diag=float64(tau_frames[:, win_index]))

        return b, prec
Пример #2
0
def unit_variance_mlpg_matrix(windows, T):
    """Compute MLPG matrix assuming input is normalized to have unit-variances.

    Let :math:`\mu` is the input mean sequence (``num_windows*T x static_dim``),
    :math:`W` is a window matrix ``(T x num_windows*T)``, assuming input is
    normalized to have unit-variances, MLPG can be written as follows:

    .. math::

        y = R \mu

    where

    .. math::

        R = (W^{T} W)^{-1} W^{T}

    Here we call :math:`R` as the MLPG matrix.

    Args:
        windows: (list): List of windows.
        T (int): Number of frames.

    Returns:
        numpy.ndarray: MLPG matrix (``T x nun_windows*T``).

    See also:
        :func:`nnmnkwii.autograd.UnitVarianceMLPG`,
        :func:`nnmnkwii.paramgen.mlpg`.

    Examples:
        >>> from nnmnkwii import paramgen as G
        >>> import numpy as np
        >>> windows = [
        ...         (0, 0, np.array([1.0])),
        ...         (1, 1, np.array([-0.5, 0.0, 0.5])),
        ...         (1, 1, np.array([1.0, -2.0, 1.0])),
        ...     ]
        >>> G.unit_variance_mlpg_matrix(windows, 3)
        array([[  2.73835927e-01,   1.95121944e-01,   9.20177400e-02,
                  9.75609720e-02,  -9.09090936e-02,  -9.75609720e-02,
                 -3.52549881e-01,  -2.43902430e-02,   1.10864742e-02],
               [  1.95121944e-01,   3.41463417e-01,   1.95121944e-01,
                  1.70731708e-01,  -5.55111512e-17,  -1.70731708e-01,
                 -4.87804860e-02,  -2.92682916e-01,  -4.87804860e-02],
               [  9.20177400e-02,   1.95121944e-01,   2.73835927e-01,
                  9.75609720e-02,   9.09090936e-02,  -9.75609720e-02,
                  1.10864742e-02,  -2.43902430e-02,  -3.52549881e-01]], dtype=float32)
    """
    win_mats = build_win_mats(windows, T)
    sdw = np.max([win_mat.l + win_mat.u for win_mat in win_mats])

    P = bm.zeros(sdw, sdw, T)
    for win_index, win_mat in enumerate(win_mats):
        bm.dot_mm_plus_equals(win_mat.T, win_mat, target_bm=P)
    chol_bm = bla.cholesky(P, lower=True)
    Pinv = cholesky_inv_banded(chol_bm.full(), width=chol_bm.l + chol_bm.u + 1)

    cocatenated_window = full_window_mat(win_mats, T)
    return Pinv.dot(cocatenated_window.T).astype(np.float32)
Пример #3
0
def _get_banded_test_mat(win_mats, T):
    import bandmat as bm

    sdw = max([win_mat.l + win_mat.u for win_mat in win_mats])
    P = bm.zeros(sdw, sdw, T)
    for win_index, win_mat in enumerate(win_mats):
        bm.dot_mm_plus_equals(win_mat.T, win_mat, target_bm=P)
    return P
Пример #4
0
    def test_zeros(self, its=50):
        for it in range(its):
            size = random.choice([0, 1, randint(0, 10), randint(0, 100)])
            l = random.choice([0, 1, randint(0, 10)])
            u = random.choice([0, 1, randint(0, 10)])

            mat_bm = bm.zeros(l, u, size)
            assert mat_bm.l == l
            assert mat_bm.u == u
            assert_allequal(mat_bm.full(), np.zeros((size, size)))
Пример #5
0
    def test_zeros(self, its=50):
        for it in range(its):
            size = random.choice([0, 1, randint(0, 10), randint(0, 100)])
            l = random.choice([0, 1, randint(0, 10)])
            u = random.choice([0, 1, randint(0, 10)])

            mat_bm = bm.zeros(l, u, size)
            assert mat_bm.l == l
            assert mat_bm.u == u
            assert_allequal(mat_bm.full(), np.zeros((size, size)))
Пример #6
0
    def build_wuw(self, frame_number, tau_frames, win_mats, sdw=None):
        if sdw is None:
            sdw = max([ win_mat.l + win_mat.u for win_mat in win_mats ])

        prec = bm.zeros(sdw, sdw, frame_number)

        for win_index, win_mat in enumerate(win_mats):
            bm.dot_mm_plus_equals(win_mat.T, win_mat, target_bm=prec,
                                  diag=float64(tau_frames[:, win_index]))

        return prec
Пример #7
0
    def build_wu(self, frame_number, tau_frames, win_mats, sdw=None):
        if sdw is None:
            sdw = max([ win_mat.l + win_mat.u for win_mat in win_mats ])

        wu_list = []

        for win_index, win_mat in enumerate(win_mats):
            temp_wu =  bm.zeros(sdw, sdw, frame_number)
            bm.dot_mm_plus_equals(win_mat.T, win_mats[0], target_bm=temp_wu,
                                  diag=float64(tau_frames[:, win_index]))
            wu_list.append(temp_wu.full())

        return  wu_list
Пример #8
0
    def build_wuw(self, frame_number, tau_frames, win_mats, sdw=None):
        if sdw is None:
            sdw = max([win_mat.l + win_mat.u for win_mat in win_mats])

        prec = bm.zeros(sdw, sdw, frame_number)

        for win_index, win_mat in enumerate(win_mats):
            bm.dot_mm_plus_equals(win_mat.T,
                                  win_mat,
                                  target_bm=prec,
                                  diag=float64(tau_frames[:, win_index]))

        return prec
Пример #9
0
    def build_wu(self, frame_number, tau_frames, win_mats, sdw=None):
        if sdw is None:
            sdw = max([win_mat.l + win_mat.u for win_mat in win_mats])

        wu_list = []

        for win_index, win_mat in enumerate(win_mats):
            temp_wu = bm.zeros(sdw, sdw, frame_number)
            bm.dot_mm_plus_equals(win_mat.T,
                                  win_mats[0],
                                  target_bm=temp_wu,
                                  diag=float64(tau_frames[:, win_index]))
            wu_list.append(temp_wu.full())

        return wu_list
Пример #10
0
def gen_pos_def_BandMat(size, depth=None, contrib_rank=2, transposed=None):
    """Generates a random positive definite BandMat."""
    assert contrib_rank >= 0
    if depth is None:
        depth = random.choice([0, 1, randint(0, 10)])
    if transposed is None:
        transposed = rand_bool()
    mat_bm = bm.zeros(depth, depth, size)
    for _ in range(contrib_rank):
        diff = randint(0, depth + 1)
        chol_bm = gen_BandMat(size, l=depth - diff, u=diff)
        bm.dot_mm_plus_equals(chol_bm, chol_bm.T, mat_bm)
    if transposed:
        mat_bm = mat_bm.T
    randomize_extra_entries_bm(mat_bm)
    return mat_bm
Пример #11
0
def gen_pos_def_BandMat(size, depth=None, contrib_rank=2, transposed=None):
    """Generates a random positive definite BandMat."""
    assert contrib_rank >= 0
    if depth is None:
        depth = random.choice([0, 1, randint(0, 10)])
    if transposed is None:
        transposed = rand_bool()
    mat_bm = bm.zeros(depth, depth, size)
    for _ in range(contrib_rank):
        diff = randint(0, depth + 1)
        chol_bm = gen_BandMat(size, l=depth - diff, u=diff)
        bm.dot_mm_plus_equals(chol_bm, chol_bm.T, mat_bm)
    if transposed:
        mat_bm = mat_bm.T
    randomize_extra_entries_bm(mat_bm)
    return mat_bm
Пример #12
0
    def build_poe(self, b_frames, tau_frames, win_mats, sdw=None):
        if sdw is None:
            sdw = max([win_mat.l + win_mat.u for win_mat in win_mats])
        num_windows = len(win_mats)
        frames = len(b_frames)
        assert np.shape(b_frames) == (frames, num_windows)
        assert np.shape(tau_frames) == (frames, num_windows)
        assert all([win_mat.l + win_mat.u <= sdw for win_mat in win_mats])

        b = np.zeros((frames,))
        prec = bm.zeros(sdw, sdw, frames)

        for win_index, win_mat in enumerate(win_mats):
            bm.dot_mv_plus_equals(win_mat.T, b_frames[:, win_index], target=b)
            bm.dot_mm_plus_equals(win_mat.T, win_mat, target_bm=prec, diag=float64(tau_frames[:, win_index]))
        return b, prec
Пример #13
0
    def test_sum_overlapping_m(self, its=50):
        for it in range(its):
            num_contribs = random.choice([0, 1, randint(10), randint(100)])
            step = random.choice([1, randint(2), randint(10)])
            width = max(step, 1) + random.choice([0, 1, randint(10)])
            depth = width - 1
            assert depth >= 0
            overlap = width - step
            mat_size = num_contribs * step + overlap

            contribs = randn(num_contribs, width, width)
            target_bm = gen_BandMat(mat_size, l=depth, u=depth)
            target_bm_orig = target_bm.copy()

            mat_bm = bmo.sum_overlapping_m(contribs, step=step)
            assert mat_bm.size == mat_size
            assert mat_bm.l == mat_bm.u == depth

            # check target-based version adds to target_bm correctly
            bmo.sum_overlapping_m(contribs, step=step, target_bm=target_bm)
            assert_allclose(*cc(target_bm, target_bm_orig + mat_bm))

            if num_contribs == 0:
                # check action for no contributions
                assert_allequal(mat_bm.full(), np.zeros((overlap, overlap)))
            elif num_contribs == 1:
                # check action for a single contribution
                assert_allequal(mat_bm.full(), contribs[0])
            else:
                # check action under splitting list of contributions in two
                split_pos = randint(num_contribs + 1)
                mat_bm_again = bm.zeros(depth, depth, mat_size)
                bmo.sum_overlapping_m(
                    contribs[:split_pos],
                    step=step,
                    target_bm=mat_bm_again.sub_matrix_view(
                        0, split_pos * step + overlap
                    )
                )
                bmo.sum_overlapping_m(
                    contribs[split_pos:],
                    step=step,
                    target_bm=mat_bm_again.sub_matrix_view(
                        split_pos * step, mat_size
                    )
                )
                assert_allclose(*cc(mat_bm, mat_bm_again))
Пример #14
0
    def build_poe(self, b_frames, tau_frames, win_mats, sdw=None):
#        tau_frames.astype('float64')

        if sdw is None:
            sdw = max([ win_mat.l + win_mat.u for win_mat in win_mats ])
        num_windows = len(win_mats)
        frames = len(b_frames)
        assert np.shape(b_frames) == (frames, num_windows)
        assert np.shape(tau_frames) == (frames, num_windows)
        assert all([ win_mat.l + win_mat.u <= sdw for win_mat in win_mats ])

        b = np.zeros((frames,))
        prec = bm.zeros(sdw, sdw, frames)

        for win_index, win_mat in enumerate(win_mats):
            bm.dot_mv_plus_equals(win_mat.T, b_frames[:, win_index], target=b)
            bm.dot_mm_plus_equals(win_mat.T, win_mat, target_bm=prec,
                                  diag=float64(tau_frames[:, win_index]))

        return b, prec
Пример #15
0
    def test_sum_overlapping_m(self, its=50):
        for it in range(its):
            num_contribs = random.choice([0, 1, randint(10), randint(100)])
            step = random.choice([1, randint(2), randint(10)])
            width = max(step, 1) + random.choice([0, 1, randint(10)])
            depth = width - 1
            assert depth >= 0
            overlap = width - step
            mat_size = num_contribs * step + overlap

            contribs = randn(num_contribs, width, width)
            target_bm = gen_BandMat(mat_size, l=depth, u=depth)
            target_bm_orig = target_bm.copy()

            mat_bm = bmo.sum_overlapping_m(contribs, step=step)
            assert mat_bm.size == mat_size
            assert mat_bm.l == mat_bm.u == depth

            # check target-based version adds to target_bm correctly
            bmo.sum_overlapping_m(contribs, step=step, target_bm=target_bm)
            assert_allclose(*cc(target_bm, target_bm_orig + mat_bm))

            if num_contribs == 0:
                # check action for no contributions
                assert_allequal(mat_bm.full(), np.zeros((overlap, overlap)))
            elif num_contribs == 1:
                # check action for a single contribution
                assert_allequal(mat_bm.full(), contribs[0])
            else:
                # check action under splitting list of contributions in two
                split_pos = randint(num_contribs + 1)
                mat_bm_again = bm.zeros(depth, depth, mat_size)
                bmo.sum_overlapping_m(contribs[:split_pos],
                                      step=step,
                                      target_bm=mat_bm_again.sub_matrix_view(
                                          0, split_pos * step + overlap))
                bmo.sum_overlapping_m(contribs[split_pos:],
                                      step=step,
                                      target_bm=mat_bm_again.sub_matrix_view(
                                          split_pos * step, mat_size))
                assert_allclose(*cc(mat_bm, mat_bm_again))
Пример #16
0
def build_poe(b_frames, tau_frames, win_mats, sdw=None):
    if sdw is None:

        sdw = max([win_mat.l + win_mat.u for win_mat in win_mats])

    num_windows = len(win_mats)

    frames = len(b_frames)

    b = numpy.zeros((frames, ))

    prec = bandmat.zeros(sdw, sdw, frames)

    for win_index, win_mat in enumerate(win_mats):

        bandmat.dot_mv_plus_equals(win_mat.T, b_frames[:, win_index], target=b)

        bandmat.dot_mm_plus_equals(win_mat.T,
                                   win_mat,
                                   target_bm=prec,
                                   diag=tau_frames[:, win_index])

    return b, prec
Пример #17
0
def build_poe(b_frames, tau_frames, win_mats, sdw=None):
    r"""Computes natural parameters for a Gaussian product-of-experts model.

    The natural parameters (b-value vector and precision matrix) are returned.
    The returned precision matrix is stored as a BandMat.
    Mathematically the b-value vector is given as:

        b = \sum_d \transpose{W_d} \tilde{b}_d

    and the precision matrix is given as:

        P = \sum_d \transpose{W_d} \text{diag}(\tilde{tau}_d) W_d

    where $W_d$ is the window matrix for window $d$ as specified by an element
    of `win_mats`, $\tilde{b}_d$ is the sequence over time of b-value
    parameters for window $d$ as given by a column of `b_frames`, and
    $\tilde{\tau}_d$ is the sequence over time of precision parameters for
    window $d$ as given by a column of `tau_frames`.
    """
    if sdw is None:
        sdw = max([ win_mat.l + win_mat.u for win_mat in win_mats ])
    num_windows = len(win_mats)
    frames = len(b_frames)
    assert np.shape(b_frames) == (frames, num_windows)
    assert np.shape(tau_frames) == (frames, num_windows)
    assert all([ win_mat.l + win_mat.u <= sdw for win_mat in win_mats ])

    b = np.zeros((frames,))
    prec = bm.zeros(sdw, sdw, frames)

    for win_index, win_mat in enumerate(win_mats):
        bm.dot_mv_plus_equals(win_mat.T, b_frames[:, win_index], target=b)
        bm.dot_mm_plus_equals(win_mat.T, win_mat, target_bm=prec,
                              diag=tau_frames[:, win_index])

    return b, prec
Пример #18
0
def mlpg_grad(mean_frames, variance_frames, windows, grad_output):
    """MLPG gradient computation

    Parameters are same as :func:`nnmnkwii.paramgen.mlpg` except for
    ``grad_output``. See the function docmenent for what the parameters mean.

    Let :math:`d` is the index of static features, :math:`l` is the index
    of windows, gradients :math:`g_{d,l}` can be computed by:

    .. math::

        g_{d,l} = (\sum_{l} W_{l}^{T}P_{d,l}W_{l})^{-1} W_{l}^{T}P_{d,l}

    where :math:`W_{l}` is a banded window matrix and :math:`P_{d,l}` is a
    diagonal precision matrix.

    Assuming the variances are diagonals, MLPG can be performed in
    dimention-by-dimention efficiently.

    Let :math:`o_{d}` be ``T`` dimentional back-propagated gradients, the
    resulting gradients :math:`g'_{l,d}` to be propagated are
    computed as follows:

    .. math::

        g'_{d,l} = o_{d}^{T} g_{d,l}


    Args:
        mean_frames (numpy.ndarray): Means.
        variance_frames (numpy.ndarray): Variances.
        windows (list): Windows.
        grad_output: Backpropagated output gradient, shape (``T x static_dim``)

    Returns:
        numpy.ndarray: Gradients to be back propagated, shape: (``T x D``)

    See also:
        :func:`nnmnkwii.autograd.mlpg`, :class:`nnmnkwii.autograd.MLPG`
    """
    T, D = mean_frames.shape
    win_mats = build_win_mats(windows, T)
    static_dim = D // len(windows)

    max_win_width = np.max([max(win_mat.l, win_mat.u) for win_mat in win_mats])

    grads = np.zeros((T, D), dtype=np.float32)
    for d in range(static_dim):
        sdw = max([win_mat.l + win_mat.u for win_mat in win_mats])

        # R: \sum_{l} W_{l}^{T}P_{d,l}W_{l}
        R = bm.zeros(sdw, sdw, T)  # overwritten in the loop

        # dtype = np.float64 for bandmat
        precisions = np.zeros((len(windows), T), dtype=np.float64)

        for win_idx, win_mat in enumerate(win_mats):
            precisions[win_idx] = 1 / \
                variance_frames[:, win_idx * static_dim + d]

            # use zero precisions at edge frames for dynamic features
            if win_idx != 0:
                precisions[win_idx, :max_win_width] = 0
                precisions[win_idx, -max_win_width:] = 0

            bm.dot_mm_plus_equals(win_mat.T,
                                  win_mat,
                                  target_bm=R,
                                  diag=precisions[win_idx])

        for win_idx, win_mat in enumerate(win_mats):
            # r: W_{l}^{T}P_{d,l}
            r = bm.dot_mm(win_mat.T, bm.diag(precisions[win_idx]))

            # grad_{d, l} = R^{-1r}
            grad = solve_banded((R.l, R.u), R.data, r.full())
            assert grad.shape == (T, T)

            # Finally we get grad for a particular dimension
            grads[:, win_idx * static_dim + d] = grad_output[:, d].T.dot(grad)

    return grads