def predict_sequence(self, X, A, pi, inference='smoothing'):
        obsll = self.predict_proba(X)
        T, S = obsll.shape
        alpha = np.zeros((T, S))
        alpha[0, :] = pi
        for t in range(1, T):
            alpha[t, :] = np.dot(alpha[t-1, :], A)
            for s in range(S):
                alpha[t, s] *= obsll[t, s]
            alpha[t, :] = alpha[t, :]/sum(alpha[t, :])
        if inference == 'filtering':
            return alpha
        else:
            beta = np.zeros((T, S))
            gamma = np.zeros((T, S))
            beta[T-1, :] = np.ones(S)
            for t in range(T-2, -1, -1):
                for i in range(S):
                    for j in range(S):
                        beta[t, i] += A[i, j]*obsll[t+1, j]*beta[t+1, j]
                beta[t, :] = beta[t, :]/sum(beta[t, :])
            for t in range(T):
                gamma[t, :] = alpha[t, :]*beta[t, :]
                gamma[t, :] = gamma[t, :]/sum(gamma[t, :])
            return gamma