def fromJSON(self, jsonObj): """Initializes the prototype with a JSON dictionary.""" super(PrototypeHMM, self).fromJSON(jsonObj) self.N = jsonObj["N"] self.model = WeightedGaussianHMM(self.N, "diag", algorithm="map", params="mc") self.model.n_features = jsonObj["n_features"] self.model.transmat_ = normalize(jsonObj["transmat"], axis=1) self.model.startprob_ = normalize(jsonObj["startprob"], axis=0) self.model._means_ = np.asarray(jsonObj["means"]) self.model._covars_ = np.asarray(jsonObj["covars"])
def train(self, obs, obs_weights=None, max_N=15): """Estimates the prototype from a set of observations. Parameters ---------- max_N : int The maximum lenght of the HMM. """ if obs_weights is None: obs_weights = np.ones(len(obs)) else: obs_weights = np.asarray(obs_weights) # set the number of states if self.num_states >= 1.0: self.N = int(self.num_states) else: mean_length = np.mean([each_obs.shape[0] for each_obs in obs]) self.N = min(int(self.num_states * mean_length), max_N) # transition prob: left-to-right self.transmat = np.zeros((self.N, self.N)) for i in range(self.N): self.transmat[i, i] = self.self_transprob if i + 1 < self.N: self.transmat[i, i + 1] = self.next_transprob for j in range(i + 2, self.N): self.transmat[i, j] = self.skip_transprob self.transmat = normalize(self.transmat, axis=1) # state prior prob: left-most only self.startprob = np.zeros(self.N) self.startprob[0] = 1.0 self.model = WeightedGaussianHMM(self.N, "diag", self.startprob, self.transmat, algorithm="map", params="mc") self.num_obs = len(obs) return self.model.fit(obs, obs_weights=obs_weights)
class PrototypeHMM(_Prototype): """HMM-based prototype. This class uses HMM as the underlying model. The similarity is defined in term of the log likelihood. Parameters ---------- num_states : float Number of hidden states. If num_states < 1, the number of states is set proportionally to the average length of the observations. For example, if num_states = 0.5, the number of states will be set to 0.5 * average length of the observations. self_transprob : float Probability of staying in the same state. next_transprob : float Probability of moving to the adjacent state. skip_transprob : float Probability of moving to any other non-adjacent states. Attributes ---------- N : int Number of hidden states in the model. """ def __init__(self, label, num_states=0.5, self_transprob=0.8, next_transprob=0.2, skip_transprob=1e-6): _Prototype.__init__(self, label) self.num_states = num_states self.self_transprob = self_transprob self.next_transprob = next_transprob self.skip_transprob = skip_transprob def train(self, obs, obs_weights=None, max_N=15): """Estimates the prototype from a set of observations. Parameters ---------- max_N : int The maximum lenght of the HMM. """ if obs_weights is None: obs_weights = np.ones(len(obs)) else: obs_weights = np.asarray(obs_weights) # set the number of states if self.num_states >= 1.0: self.N = int(self.num_states) else: mean_length = np.mean([each_obs.shape[0] for each_obs in obs]) self.N = min(int(self.num_states * mean_length), max_N) # transition prob: left-to-right self.transmat = np.zeros((self.N, self.N)) for i in range(self.N): self.transmat[i, i] = self.self_transprob if i + 1 < self.N: self.transmat[i, i + 1] = self.next_transprob for j in range(i + 2, self.N): self.transmat[i, j] = self.skip_transprob self.transmat = normalize(self.transmat, axis=1) # state prior prob: left-most only self.startprob = np.zeros(self.N) self.startprob[0] = 1.0 self.model = WeightedGaussianHMM(self.N, "diag", self.startprob, self.transmat, algorithm="map", params="mc") self.num_obs = len(obs) return self.model.fit(obs, obs_weights=obs_weights) def score(self, obs, last_state_only=True): """Calculates the score of an observation. Returns ------- score : float If last_state_only=False, the score is defined as the log likelihood of the observation under the model. Otherwise, the score is defined as the log likelihood at the last state only. """ obs = np.asarray(obs) framelogprob = self.model._compute_log_likelihood(obs) if last_state_only: _, fwdlattice = self.model._do_forward_pass(framelogprob) return fwdlattice[-1, -1] else: logprob, _ = self.model._do_forward_pass(framelogprob) return logprob def toJSON(self): """Returns a JSON dictionary representing the prototype.""" info = super(PrototypeHMM, self).toJSON() info["n_components"] = int(self.model.n_components) info["n_features"] = int(self.model.n_features) info["transmat"] = self.model.transmat_.astype(np.float16).tolist() info["startprob"] = self.model.startprob_.astype(np.float16).tolist() info["means"] = self.model._means_.astype(np.float16).tolist() info["covars"] = self.model._covars_.astype(np.float16).tolist() info["N"] = self.N return info def fromJSON(self, jsonObj): """Initializes the prototype with a JSON dictionary.""" super(PrototypeHMM, self).fromJSON(jsonObj) self.N = jsonObj["N"] self.model = WeightedGaussianHMM(self.N, "diag", algorithm="map", params="mc") self.model.n_features = jsonObj["n_features"] self.model.transmat_ = normalize(jsonObj["transmat"], axis=1) self.model.startprob_ = normalize(jsonObj["startprob"], axis=0) self.model._means_ = np.asarray(jsonObj["means"]) self.model._covars_ = np.asarray(jsonObj["covars"])