def loglikelihood(data, model):
    lpr = log_multivariate_normal_density_diag(data['lmfcc'], model['means'],
                                               model['covars'])
    log_st_prob = np.log(model['startprob'])
    log_transmat = np.log(model['transmat'])
    alpha_matrix = forward(lpr, log_st_prob, log_transmat)
    return lpr, logsumexp(alpha_matrix[-1])
def forward_algorithm():
    wordHMMs = {}
    isolated = get_isolated(prondict)
    plot_p_color_mesh(example['logalpha'], 'example alpha matrix')

    # verify implementation
    wordHMMs['o'] = concatHMMs(phoneHMMsAll, isolated['o'])
    log_st_prob = np.log(wordHMMs['o']['startprob'])
    log_transmat = np.log(wordHMMs['o']['transmat'])
    alpha_matrix = forward(example['obsloglik'], log_st_prob, log_transmat)
    plot_p_color_mesh(alpha_matrix, "hmms all output example alpha matrix")

    # 44 data labels
    keys_list = [x for x in isolated.keys()]
    scores_models_all = np.zeros((len(data), len(isolated)))
    scores_models_onespkr = np.zeros_like(scores_models_all)

    for j in range(len(keys_list)):
        key = keys_list[j]
        hmms = concatHMMs(phoneHMMsAll, isolated[key])
        log_st_prob = np.log(hmms['startprob'])
        log_transmat = np.log(hmms['transmat'])
        for i in range(len(data)):
            lpr_test = log_multivariate_normal_density_diag(
                data[i]['lmfcc'], hmms['means'], hmms['covars'])
            alpha = forward(lpr_test, log_st_prob, log_transmat)
            scores_models_all[i, j] = logsumexp(alpha[len(alpha) - 1])

        hmms = concatHMMs(phoneHMMsOne, isolated[key])
        log_st_prob = np.log(hmms['startprob'])
        log_transmat = np.log(hmms['transmat'])
        for i in range(len(data)):
            lpr_test = log_multivariate_normal_density_diag(
                data[i]['lmfcc'], hmms['means'], hmms['covars'])
            alpha = forward(lpr_test, log_st_prob, log_transmat)
            scores_models_onespkr[i, j] = logsumexp(alpha[len(alpha) - 1])

    predict_all = np.argmax(scores_models_all, axis=1)
    predict_one = np.argmax(scores_models_onespkr, axis=1)

    label_all = [keys_list[x] for x in predict_all]
    label_one = [keys_list[x] for x in predict_one]

    true_label = [data[x]['digit'] for x in range(len(data))]
    print(true_label)
    print(label_all)
    print(label_one)
Пример #3
0
def get_loglik(feature, hmm):
    trans_mat = hmm['transmat'][:-1, :-1]
    pi_vec = hmm['startprob'][:-1]
    means = hmm['means']
    covars = hmm['covars']
    obsloglik = log_multivariate_normal_density_diag(feature, means, covars)
    log_alpha = forward(obsloglik, np.log(pi_vec), np.log(trans_mat))
    ret = logsumexp(log_alpha[-1])
    return ret
Пример #4
0
def statePosteriors(log_alpha, log_beta):
    """State posterior (gamma) probabilities in log domain.

    Args:
        log_alpha: NxM array of log forward (alpha) probabilities
        log_beta: NxM array of log backward (beta) probabilities
    where N is the number of frames, and M the number of states

    Output:
        log_gamma: NxM array of gamma probabilities for each of the M states in the model
    """
    log_gamma = log_alpha + log_beta - lab2_tools.logsumexp(log_alpha[-1,:])
    return log_gamma
Пример #5
0
def backward(log_emlik, log_startprob, log_transmat):
    """Backward (beta) probabilities in log domain.

    Args:
        log_emlik: NxM array of emission log likelihoods, N frames, M states
        log_startprob: log probability to start in state i
        log_transmat: transition log probability from state i to j

    Output:
        backward_prob: NxM array of backward log probabilities for each of the M states in the model
    """
    log_beta = np.zeros(log_emlik.shape)  # since beta_N = 1 => log_beta_N = 0
    for n in reversed(range(log_emlik.shape[0] - 1)): # time dimension
        for i in range(log_emlik.shape[1]): # loop over states
            log_beta[n, i] = logsumexp(log_transmat[i,:] + log_emlik[n + 1, :] + log_beta[n + 1,:])
    return log_beta
Пример #6
0
def forward(log_emlik, log_startprob, log_transmat):
    """Forward (alpha) probabilities in log domain.

    Args:
        log_emlik: NxM array of emission log likelihoods, N frames, M states
        log_startprob: log probability to start in state i
        log_transmat: log transition probability from state i to j

    Output:
        forward_prob: NxM array of forward log probabilities for each of the M states in the model
    """

    # follow the appendix in the question pdf
    log_alpha = np.zeros(log_emlik.shape)
    log_alpha[0][:] = log_startprob.T + log_emlik[0]

    for n in range(1,len(log_alpha)): # time dimension
        for i in range(log_alpha.shape[1]): # loop over states
            log_alpha[n, i] = logsumexp(log_alpha[n - 1] + log_transmat[:,i]) + log_emlik[n,i]
    return log_alpha
Пример #7
0
def retrain(feature, model, num_iters=20, threshold=1):

    # extract params
    means = model['means']
    covars = model['covars']
    transmat = model['transmat'][:-1, :-1]
    startprob = model['startprob'][:-1]
    log_pi = np.log(startprob)
    log_trans = np.log(transmat)

    # calculate the emission
    obsloglik = log_multivariate_normal_density_diag(feature, means, covars)

    # EM algorithm
    loglik_old = -np.inf
    for iter_ in range(num_iters):
        # E-step
        log_alpha = forward(obsloglik, log_pi, log_trans)
        log_beta = backward(obsloglik, log_pi, log_trans)
        log_gamma = statePosteriors(log_alpha, log_beta)

        # M-step
        means, covars = updateMeanAndVar(feature, log_gamma)
        # update
        obsloglik = log_multivariate_normal_density_diag(
            feature, means, covars)

        loglik = logsumexp(log_alpha[-1])
        print("Iter {}: The log likelihood in EM:".format(iter_), loglik)

        # check if terminate EM
        if (loglik - loglik_old) < threshold or np.isnan(loglik):
            print("Terminating the EM")
            break
        else:
            loglik_old = loglik
Пример #8
0
def backward(log_emlik, log_startprob, log_transmat):
    """Backward (beta) probabilities in log domain.

    Args:
        log_emlik: NxM array of emission log likelihoods, N frames, M states
        log_startprob: log probability to start in state i
        log_transmat: transition log probability from state i to j

    Output:
        backward_prob: NxM array of backward log probabilities for each of the M states in the model
    """

    N, M = log_emlik.shape

    # Create zeroed beta return matrix.
    log_beta = np.zeros((N, M))

    #For all other n, populate beta with regular formula result.
    #Start at N-2 &, in increments of -1, finish at 0.
    for n in range(N - 2, -1, -1):
        for j in range(M):
            log_beta[n][j] = lab2_tools.logsumexp(log_beta[n + 1, :] + log_emlik[n + 1, :] + log_transmat[j, :-1])

    return log_beta
Пример #9
0
def forward(log_emlik, log_startprob, log_transmat):
    """Forward (alpha) probabilities in log domain.

    Args:
        log_emlik: NxM array of emission log likelihoods, N frames, M states
        log_startprob: log probability to start in state i
        log_transmat: log transition probability from state i to j

    Output:
        forward_prob: NxM array of forward log probabilities for each of the M states in the model
    """

    N, M = log_emlik.shape

    # Create alpha return matrix, populate with n=0 formula result.
    forward_prob = np.zeros((N, M))

    forward_prob[0, :] = log_startprob[:-1] + log_emlik[0, :]

    for n in range(1, N):
        for j in range(M):
            forward_prob[n, j] = lab2_tools.logsumexp(forward_prob[n-1, :] + log_transmat[:-1, j]) + log_emlik[n, j]

    return forward_prob
Пример #10
0
    for d in isolated.keys():
        wordHMMs[d] = concatHMMs(phoneHMMs, isolated[d])

    # get the observation sequence
    feature = data[10]['lmfcc']

    # First part
    # calculate the emissions
    digit = '4'
    means = wordHMMs[digit]['means']
    covars = wordHMMs[digit]['covars']
    obsloglik = log_multivariate_normal_density_diag(feature, means, covars)

    # calculate the log likelihood
    trans_mat = wordHMMs[digit]['transmat'][:-1, :-1]
    pi_vec = wordHMMs[digit]['startprob'][:-1]
    # log space
    log_pi = np.log(pi_vec)
    log_trans = np.log(trans_mat)

    log_alpha = forward(obsloglik, log_pi, log_trans)
    log_seq_likelihood = logsumexp(log_alpha[-1])
    print("The log likelihood of the digit {}:".format(digit),
          log_seq_likelihood)
    # =========================================================================
    for d in wordHMMs.keys():
        print("========================================================")
        print("Retrain HMM of digit '{}' with data[10]['lmfcc']".format(d))
        retrain(feature, wordHMMs[d])
        print("========================================================")
Пример #11
0
    axs[0].set_title("Computed \"o\" forward probability, from one speaker")
    axs[0].pcolormesh(forward_probability.T)
    axs[1].set_title("Computed \"o\" forward probability, from multiple speakers")
    axs[1].pcolormesh(forward_probability_all.T)
    plt.show()
    

    scores = np.zeros((44, 11))
    for i in range(len(data)):
        data_sample = data[i]['lmfcc']

        j = 0
        for key, HMM in wordHMMs.items():
            log_lik = lab2_tools.log_multivariate_normal_density_diag(data_sample, HMM["means"], HMM["covars"])
            forward_probability2 = forward(log_lik, np.log(HMM["startprob"]), np.log(HMM["transmat"]))
            scores[i, j] = lab2_tools.logsumexp(forward_probability2[-1])
            j += 1

    scores_all = np.zeros((44, 11))
    for i in range(len(data)):
        data_sample = data[i]['lmfcc']

        j = 0
        for key, HMM in wordHMMs_all.items():
            log_lik = lab2_tools.log_multivariate_normal_density_diag(data_sample, HMM["means"], HMM["covars"])
            forward_probability2 = forward(log_lik, np.log(HMM["startprob"]), np.log(HMM["transmat"]))
            scores_all[i, j] = lab2_tools.logsumexp(forward_probability2[-1])
            j += 1

    #  plotting forward functions, comparing all speakers to one:
    fig, axs = plt.subplots(2)
Пример #12
0
    example = np.load('data/lab2_example.npz')['example'].item()
    phoneHMMs = np.load('data/lab2_models_onespkr.npz')['phoneHMMs'].item()

    # Build hmm
    wordHMMs = {}
    wordHMMs['o'] = concatHMMs(phoneHMMs, isolated['o'])

    trans_mat = wordHMMs['o']['transmat'][:-1, :-1]
    pi_vec = wordHMMs['o']['startprob'][:-1]
    log_startprob = np.log(pi_vec)
    log_transmat = np.log(trans_mat)
    log_emlik = example['obsloglik']
    # =====================================================
    log_beta = backward(log_emlik, log_startprob, log_transmat)
    log_alpha = forward(log_emlik, log_startprob, log_transmat)

    # caculate the log gamma
    log_gamma = statePosteriors(log_alpha, log_beta)

    # print(np.allclose(example['loggamma'], log_gamma))

    # check if sum to one in linear / sum to zero in log domain
    ntime_steps = log_gamma.shape[0]
    zeros = np.zeros((ntime_steps))
    # print(np.allclose(logsumexp(log_gamma, axis=1), zeros))
    # ====================================================================
    # See notes, just do the normalization to get the state posterior of GMM
    logZ = logsumexp(log_emlik,
                     axis=1)  # the normalization factor in log space
    log_gamma_gmm = log_emlik - logZ[:, np.newaxis]
Пример #13
0
from lab2_proto import backward
from lab2_tools import logsumexp

if __name__ == "__main__":
    # load data
    data = np.load('data/lab2_data.npz')['data']
    example = np.load('data/lab2_example.npz')['example'].item()
    phoneHMMs = np.load('data/lab2_models_onespkr.npz')['phoneHMMs'].item()

    # Build hmm
    wordHMMs = {}
    wordHMMs['o'] = concatHMMs(phoneHMMs, isolated['o'])

    trans_mat = wordHMMs['o']['transmat'][:-1, :-1]
    pi_vec = wordHMMs['o']['startprob'][:-1]
    log_startprob = np.log(pi_vec)
    log_transmat = np.log(trans_mat)
    log_emlik = example['obsloglik']
    # =====================================================
    log_beta = backward(log_emlik, log_startprob, log_transmat)

    # check the result of log_beta
    print("Is beta close?:", np.allclose(log_beta, example['logbeta']))

    # calculate the log prob
    # seq_likelihood = sum_{i}(\alpha_0(i) * \beta_0(i))
    log_alpha_0 = log_startprob.T + log_emlik[0]
    log_beta_0 = log_beta[0, :]
    log_seq_like = logsumexp(log_alpha_0 + log_beta_0)
    print(log_seq_like)
    print(example['loglik'])