0

I would like to implement the following regression function with theano scan as an expression to compute delta coefficients. However, I can't figure out how to pass the previous theta inputs into the current step.

delta coefficient

where delta is a delta coefficient at time t computed in terms of the corresponding static coefficients coeff to coeff. The value of theta is set using the configuration parameter DELTAWINDOW. The same formula is applied to the delta coefficients to obtain acceleration coefficients except that in this case the window size is set by ACCWINDOW. Since equation 5.16 relies on past and future speech parameter values, some modification is needed at the beginning and end of the speech. The default behaviour is to replicate the first or last vector as needed to fill the regression window.

The DELTAWINDOW I am using is 9, and the input is a matrix eg:

[[1,1,1,1,1,1,1,1,1],
[2,2,2,2,2,2,2,2,2],
[3,3,3,3,3,3,3,3,3],
[4,4,4,4,4,4,4,4,4]]    

The reference material can be found at this link

Community
  • 1
  • 1
tolma
  • 141
  • 1
  • 10

1 Answers1

1

An attempt at creating a theano expression for this.

import numpy as np
import theano
import theano.tensor as T


def delta_theta(theta, curr_delta, t, THETA, Y):
    """
    compute a delta theta component at delta time step t
    :param theta: current time step theta component
    :param curr_delta: current accumulated delta_t
    :param t: current delta_t to be computed
    :param THETA: window size
    :param Y: input sequence
    :return: delta theta component for time step t
    """
    # accumulator is shaped (1, no_features), transpose to perform column wise element operations
    temp = curr_delta.T
    d_theta = theta * (Y[:, THETA + t + theta] - Y[:, THETA + t - theta]) / (2 * theta * theta)
    temp += d_theta
    temp = temp.astype('float32')
    curr_delta = temp.T
    return curr_delta


def delta_t(t, THETA, Y):
    """
    compute delta at time step t
    :param t: time step
    :param THETA: window size
    :param Y: sequence in shape (number_of_features, time_step)
    :return: delta coefficient at time step t
    """
    theta = T.arange(1, THETA + 1, dtype='int32')
    results, _ = theano.scan(delta_theta, outputs_info=T.zeros_like(Y),
                             sequences=theta, non_sequences=[t, THETA, Y])
    # only interested in the final results, discard the intermediate values
    final_results = results[-1]
    return final_results


def delta_coeff(A, theta):
    """
    compute delta coefficients given a sequence.
    :param A: input sequence in shape (time_step, number_of_features)
    :param theta: window size
    :return: delta coefficients for the input sequence
    """
    # transpose and repeat
    X = A.T
    Y = T.concatenate([T.extra_ops.repeat(X[:, 0], theta).reshape((X.shape[0], theta)),
                       X, T.extra_ops.repeat(X[:, -1], theta).reshape((X.shape[0], theta))], axis=1)
    results, _ = theano.scan(delta_t, sequences=[T.arange(0, X.shape[1], dtype='int32')], non_sequences=[theta, Y])
    # transpose the results back to shape (time_step, number_of_features)
    return results[:, :, -1].reshape(A.shape)


def main():
    """
    test runner, computes delta for an array of sequences
    :return: None
    """
    A = T.tensor3('A', dtype='float32')
    theta = T.iscalar('theta')

    # compute delta coefficients for multiple sequences
    results, updates = theano.scan(delta_coeff, sequences=A, non_sequences=theta)
    compute_deltas = theano.function([A, theta], outputs=results, updates=updates)

    seqs = np.array([[[1, 2, 3, 4, 5],
                      [10, 12, 13, 14, 15],
                      [300, 1, 23, 56, 22]],
                     [[1, 1, 1, 1, 1],
                      [1, 1, 100, 1, 1],
                      [1, 1, 1, 1, 1]]], dtype='float32')
    res = compute_deltas(seqs, 1)
    print(res)

if __name__ == '__main__':
    main()

If there are any mistakes, please point them out, thank you!

tolma
  • 141
  • 1
  • 10