def train_models(model, x, y): """ Train a Gaussian HMM for each class in the input matrix. For this, a default of 7 states is used. Hence the size of startprob and transmat. As this is a Left-Right HMM, the start probability is 100% for state 1, and 0 for all others. Args: model: HMM class object x: input image feature vector y: labels for images Return: Trained Model """ classes = len(np.unique(y)) if classes < 1: raise ValueError("Need at least 1 class to train HMMs with.") startprob = np.array([1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) transmat = np.array([[0.8, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.8, 0.2, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.8, 0.2, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.8, 0.2, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.8, 0.2, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.2], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1]]) for image_class in range(classes): # Partition the training data into arrays for each class # Then train a Hidden Markov Model for each covar = "diag" if model.diag else "full" hmm = GaussianHMM(model.states, covar, n_iter=20, tol=0.00001, random_state=np.random.RandomState()) hmm.startprob_ = startprob hmm.transmat_ = transmat # Loop iterator corresponds to label of data hmm.label = image_class features = functions.get_labelled_train_data(x, y, image_class) # Fit the HMM for that label old_block_num = features.shape[1] features_size = features.shape[2] length = features.shape[0] # Need to flatten out the first 2 dimensions of feature vector # and pass an array of length into the HMM # old_block_num = number of observation blocks for a single image. lengths = [] for i in range(length): lengths.append(old_block_num) feat = features.reshape((length * old_block_num, features_size)) hmm.fit(feat, lengths=lengths) # Train the model for 1 class. model.hmms.append(hmm) return model