Did you mean the
self.gmm.inference() function looks like? It basically code that is only using pure numpy

class GMM:
def __init__(self, ncomp, initial_mus, initial_covs, initial_priors):

    self.ncomp = ncomp
    self.mus = np.asarray(initial_mus)
    self.covs = np.asarray(initial_covs)
    self.priors = np.asarray(initial_priors)

def inference(self, datas): # E-step
    unnormalized_probs = []
    if type(datas) == torch.Tensor:
        datas = datas.cpu().numpy()

    for i in range(self.ncomp):
        mu, cov, prior = self.mus[i, :], self.covs[i, :, :], self.priors[i]
        # multivariate_normal.pdf is a function from Scipy to calculate
        # multivariate normal distribution because our data is 3 dimension
       unnormalized_prob = prior * multivariate_normal.pdf(datas, mean=mu, cov=cov, allow_singular=True)

        unnormalized_probs.append(np.expand_dims(unnormalized_prob, -1))

    preds = np.concatenate(unnormalized_probs, axis=1)
    log_likelihood = np.sum(preds, axis=1)
    log_likelihood = np.sum(np.log(log_likelihood))
    preds = preds / np.sum(preds, axis=1, keepdims=True)

    return np.asarray(preds), log_likelihood


I also try to follow the tutorial of making forward and backward pass manually, but I’m confused, in my case which part I should save into the ctx.save_for_backward function and how can I make the backward function.