// Score implements the graph.Viterbier interface. // The argument x must be of type []float64. func (nv nodeValue) Score(x interface{}) float64 { if nv.scorer == nil { return 0 // non-emitting node. } o := model.NewFloatObs(x.([]float64), model.SimpleLabel("")) return nv.scorer.LogProb(o) }
func (m *Net) logProb(s int, x []float64) float64 { o := model.NewFloatObs(x, model.SimpleLabel("")) return m.B[s].LogProb(o) }
// should be equivalent to training a single gaussian, great for debugging. func TestSingleState(t *testing.T) { // HMM to generate data. g01 := gm.NewModel(1, gm.Name("g01"), gm.Mean([]float64{0}), gm.StdDev([]float64{1})) h0 := narray.New(3, 3) h0.Set(1, 0, 1) h0.Set(.8, 1, 1) h0.Set(.2, 1, 2) h0 = narray.Log(nil, h0.Copy()) ms0, _ := NewSet() net0, e0 := ms0.NewNet("hmm", h0, []model.Modeler{nil, g01, nil}) fatalIf(t, e0) hmm0 := NewModel(OSet(ms0)) _ = hmm0 // Create gaussian to estimate without using the HMM code. g := gm.NewModel(1, gm.Name("g1"), gm.Mean([]float64{-1}), gm.StdDev([]float64{2})) // Create initial HMM and estimate params from generated data. g1 := gm.NewModel(1, gm.Name("g1"), gm.Mean([]float64{-1}), gm.StdDev([]float64{2})) h := narray.New(3, 3) h.Set(1, 0, 1) h.Set(.5, 1, 1) h.Set(.5, 1, 2) h = narray.Log(nil, h.Copy()) ms, _ = NewSet() net, e := ms.NewNet("hmm", h, []model.Modeler{nil, g1, nil}) fatalIf(t, e) hmm := NewModel(OSet(ms), UpdateTP(true), UpdateOP(true)) iter := 5 // number of sequences m := 1000 numFrames := 0 t0 := time.Now() // Start timer. for i := 0; i < iter; i++ { t.Logf("iter [%d]", i) // Make sure we generate the same data in each iteration. r := rand.New(rand.NewSource(33)) gen := newGenerator(r, false, net0) // Reset all counters. hmm.Clear() g.Clear() // fix the seed to get the same sequence for j := 0; j < m; j++ { obs, states := gen.next("oid-" + fi(j)) numFrames += len(states) - 2 hmm.UpdateOne(obs, 1.0) // Update Gaussian for _, o := range obs.ValueAsSlice() { vec := o.([]float64) gobs := model.NewFloatObs(vec, model.SimpleLabel("")) g.UpdateOne(gobs, 1.0) } } hmm.Estimate() g.Estimate() t.Logf("iter:%d, hmm g1: %+v", i, net.B[1]) t.Logf("iter:%d, direct g1:%+v", i, g) } dur := time.Now().Sub(t0) tp0 := narray.Exp(nil, h0.Copy()) tp := narray.Exp(nil, net.A.Copy()) ns := tp.Shape[0] for i := 0; i < ns; i++ { for j := 0; j < ns; j++ { p0 := tp0.At(i, j) logp0 := h0.At(i, j) p := tp.At(i, j) logp := h.At(i, j) if p > smallNumber || p0 > smallNumber { t.Logf("TP: %d=>%d, p0:%5.2f, p:%5.2f, logp0:%8.5f, logp:%8.5f", i, j, p0, p, logp0, logp) } } } t.Log("") t.Logf("hmm0 g1:%+v", net0.B[1]) t.Logf("hmm g1: %+v", net.B[1]) t.Log("") t.Logf("direct g1:%+v", g) // Print time stats. t.Log("") t.Logf("Total time: %v", dur) t.Logf("Time per iteration: %v", dur/time.Duration(iter)) t.Logf("Time per frame: %v", dur/time.Duration(iter*numFrames*m)) gjoa.CompareSliceFloat(t, tp0.Data, tp.Data, "error in Trans Probs [0]", .03) CompareGaussians(t, net0.B[1].(*gm.Model), net.B[1].(*gm.Model), 0.03) if t.Failed() { t.FailNow() } // Recognize. sg := ms.SearchGraph() dec, e := graph.NewDecoder(sg) if e != nil { t.Fatal(e) } r := rand.New(rand.NewSource(5151)) gen := newGenerator(r, true, net0) // testDecoder(t, gen, dec, 1000) testDecoder(t, gen, dec, 10) }
// Sample returns a Gaussian sample. func (g *Model) Sample(r *rand.Rand) model.Obs { obs := model.RandNormalVector(r, g.Mean, g.StdDev) return model.NewFloatObs(obs, model.SimpleLabel("")) }