def test7(): """ This test builds an Hmm with dummy models which always give a score of 1, but with a somewhat unusual topology in which there are 6 actual states chained together with 2 virtual inputs and 3 virtual outputs. The point is to make sure we can handle this asymetric case correctly. This is the same as test6 except that now we'll use the network adaptation interface instead. """ import pprint num_states = 6 dimension = 2 # GmmMgr setup models = [] for i in xrange(num_states): dm = DummyModel(dimension, 1.0) models.append(dm) mm = GmmMgr(models) # Hmm setup T0: i1 i2 1 2 3 4 5 6 o1 o2 o3 FROM: trans = array(((0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), # i1 (0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), # i2 (0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), # 1 (0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), # 2 (0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0), # 3 (0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.4, 0.0, 0.1, 0.0, 0.0), # 4 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.4, 0.0, 0.1, 0.0), # 5 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5), # 6 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), # o1 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), # o2 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))) # o3 hmm0 = Hmm(num_states, log_domain=True) models = range(num_states) hmm0.build_model(mm, models, 2, 3, trans) print hmm0.to_string(True) num_passes = 1 for p in xrange(num_passes): # Reseeding here ensures we are repeating the same observations in each pass SimpleGaussianModel.seed(0) mm.set_adaptation_state("INITIALIZING") hmm0.begin_adapt("NETWORK") mm.set_adaptation_state("ACCUMULATING") num_obs = 11 obs = [array((0,0))] * num_obs # Dummy sequence context = hmm0.init_for_forward_pass(obs, terminal = True) # Add some mass into the system for the forward pass. To match the behavior of # standalone adaptation, we divide an initial mass of 1 evenly across the inputs hmm0.accum_input_alphas(context, array([1.0/hmm0.num_inputs] * hmm0.num_inputs)) # Actually do the forward pass. Note that we must process one more frame than the number of # observations - this is because an extra frame is automatically added which scores 1 on the exit # states of the Hmm (and 0 on all real states). XXX we might want clients to do this for # themselves at some point rather than this automatic behavior: for frame in xrange(num_obs + 1): output_alphas = hmm0.process_one_frame_forward(context) print output_alphas # Likewise, we initialize and then make the backward pass: hmm0.init_for_backward_pass(context) hmm0.accum_input_betas(context, array([1.0] * hmm0.num_outputs)) for frame in xrange(num_obs + 1): output_betas = hmm0.process_one_frame_backward(context) print output_betas # Now collect all the gamma sums; here there's only one: norm = hmm0.get_initial_gamma_sum() hmm0.add_to_gamma_sum(norm, context) # Here's where the actual accumulation happens: hmm0.do_accumulation(context, norm) mm.set_adaptation_state("APPLYING") hmm0.end_adapt() mm.apply_all_accumulators() mm.set_adaptation_state("NOT_ADAPTING") print hmm0.to_string(True)