mlpack 3.4.2
hmm_test_utils.hpp
Go to the documentation of this file.
1
15#ifndef MLPACK_TESTS_MAIN_TESTS_HMM_TEST_UTILS_HPP
16#define MLPACK_TESTS_MAIN_TESTS_HMM_TEST_UTILS_HPP
17
18#include <mlpack/prereqs.hpp>
20
22{
23 template<typename HMMType>
24 static void Apply(HMMType& hmm, vector<mat>* trainSeq)
25 {
26 const size_t states = 2;
27
28 // Create the initialized-to-zero model.
29 Create(hmm, *trainSeq, states);
30
31 // Initializing the emission distribution depends on the distribution.
32 // Therefore we have to use the helper functions.
33 RandomInitialize(hmm.Emission());
34 }
35
37 static void Create(HMM<DiscreteDistribution>& hmm,
38 vector<mat>& trainSeq,
39 size_t states,
40 double tolerance = 1e-05)
41 {
42 // Maximum observation is necessary so we know how to train the discrete
43 // distribution.
44 arma::Col<size_t> maxEmissions(trainSeq[0].n_rows);
45 maxEmissions.zeros();
46 for (vector<mat>::iterator it = trainSeq.begin(); it != trainSeq.end();
47 ++it)
48 {
49 arma::Col<size_t> maxSeqs =
50 arma::conv_to<arma::Col<size_t>>::from(arma::max(*it, 1)) + 1;
51 maxEmissions = arma::max(maxEmissions, maxSeqs);
52 }
53
54 hmm = HMM<DiscreteDistribution>(size_t(states),
55 DiscreteDistribution(maxEmissions), tolerance);
56 }
57
58 static void Create(HMM<GaussianDistribution>& hmm,
59 vector<mat>& trainSeq,
60 size_t states,
61 double tolerance = 1e-05)
62 {
63 // Find dimension of the data.
64 const size_t dimensionality = trainSeq[0].n_rows;
65
66 // Verify dimensionality of data.
67 for (size_t i = 0; i < trainSeq.size(); ++i)
68 {
69 if (trainSeq[i].n_rows != dimensionality)
70 {
71 Log::Fatal << "Observation sequence " << i << " dimensionality ("
72 << trainSeq[i].n_rows << " is incorrect (should be "
73 << dimensionality << ")!" << endl;
74 }
75 }
76
77 // Get the model and initialize it.
78 hmm = HMM<GaussianDistribution>(size_t(states),
79 GaussianDistribution(dimensionality), tolerance);
80 }
81
82 static void Create(HMM<GMM>& hmm,
83 vector<mat>& trainSeq,
84 size_t states,
85 double tolerance = 1e-05)
86 {
87 // Find dimension of the data.
88 const size_t dimensionality = trainSeq[0].n_rows;
89 const int gaussians = 2;
90
91 if (gaussians == 0)
92 {
93 Log::Fatal << "Number of gaussians for each GMM must be specified "
94 << "when type = 'gmm'!" << endl;
95 }
96
97 if (gaussians < 0)
98 {
99 Log::Fatal << "Invalid number of gaussians (" << gaussians << "); must "
100 << "be greater than or equal to 1." << endl;
101 }
102
103 // Create HMM object.
104 hmm = HMM<GMM>(size_t(states), GMM(size_t(gaussians), dimensionality),
105 tolerance);
106 }
107
109 static void Create(HMM<DiagonalGMM>& hmm,
110 vector<mat>& trainSeq,
111 size_t states,
112 double tolerance = 1e-05)
113 {
114 // Find dimension of the data.
115 const size_t dimensionality = trainSeq[0].n_rows;
116 const int gaussians = 2;
117
118 if (gaussians == 0)
119 {
120 Log::Fatal << "Number of gaussians for each GMM must be specified "
121 << "when type = 'diag_gmm'!" << endl;
122 }
123
124 if (gaussians < 0)
125 {
126 Log::Fatal << "Invalid number of gaussians (" << gaussians << "); must "
127 << "be greater than or equal to 1." << endl;
128 }
129
130 // Create HMM object.
131 hmm = HMM<DiagonalGMM>(size_t(states), DiagonalGMM(size_t(gaussians),
132 dimensionality), tolerance);
133 }
134
136 static void RandomInitialize(vector<DiscreteDistribution>& e)
137 {
138 for (size_t i = 0; i < e.size(); ++i)
139 {
140 e[i].Probabilities().randu();
141 e[i].Probabilities() /= arma::accu(e[i].Probabilities());
142 }
143 }
144
145 static void RandomInitialize(vector<GaussianDistribution>& e)
146 {
147 for (size_t i = 0; i < e.size(); ++i)
148 {
149 const size_t dimensionality = e[i].Mean().n_rows;
150 e[i].Mean().randu();
151 // Generate random covariance.
152 arma::mat r = arma::randu<arma::mat>(dimensionality, dimensionality);
153 e[i].Covariance(r * r.t());
154 }
155 }
156
157 static void RandomInitialize(vector<GMM>& e)
158 {
159 for (size_t i = 0; i < e.size(); ++i)
160 {
161 // Random weights.
162 e[i].Weights().randu();
163 e[i].Weights() /= arma::accu(e[i].Weights());
164
165 // Random means and covariances.
166 for (int g = 0; g < 2; ++g)
167 {
168 const size_t dimensionality = e[i].Component(g).Mean().n_rows;
169 e[i].Component(g).Mean().randu();
170
171 // Generate random covariance.
172 arma::mat r = arma::randu<arma::mat>(dimensionality,
173 dimensionality);
174 e[i].Component(g).Covariance(r * r.t());
175 }
176 }
177 }
178
180 static void RandomInitialize(vector<DiagonalGMM>& e)
181 {
182 for (size_t i = 0; i < e.size(); ++i)
183 {
184 // Random weights.
185 e[i].Weights().randu();
186 e[i].Weights() /= arma::accu(e[i].Weights());
187
188 // Random means and covariances.
189 for (int g = 0; g < 2; ++g)
190 {
191 const size_t dimensionality = e[i].Component(g).Mean().n_rows;
192 e[i].Component(g).Mean().randu();
193
194 // Generate random diagonal covariance.
195 arma::vec r = arma::randu<arma::vec>(dimensionality);
196 e[i].Component(g).Covariance(r);
197 }
198 }
199 }
200};
201
203{
204 template<typename HMMType>
205 static void Apply(HMMType& hmm, vector<arma::mat>* trainSeq)
206 {
207 // For now, perform unsupervised (Baum-Welch) training.
208 hmm.Train(*trainSeq);
209 }
210};
211
212#endif
The core includes that mlpack expects; standard C++ includes and Armadillo.
static void RandomInitialize(vector< GMM > &e)
static void RandomInitialize(vector< GaussianDistribution > &e)
static void Apply(HMMType &hmm, vector< mat > *trainSeq)
static void Create(HMM< DiscreteDistribution > &hmm, vector< mat > &trainSeq, size_t states, double tolerance=1e-05)
Helper function to create discrete HMM.
static void RandomInitialize(vector< DiagonalGMM > &e)
Helper function for diagonal GMM emission distributions.
static void Create(HMM< GMM > &hmm, vector< mat > &trainSeq, size_t states, double tolerance=1e-05)
static void Create(HMM< GaussianDistribution > &hmm, vector< mat > &trainSeq, size_t states, double tolerance=1e-05)
static void RandomInitialize(vector< DiscreteDistribution > &e)
Helper function for discrete emission distributions.
static void Create(HMM< DiagonalGMM > &hmm, vector< mat > &trainSeq, size_t states, double tolerance=1e-05)
Helper function to create Diagonal GMM HMM.
static void Apply(HMMType &hmm, vector< arma::mat > *trainSeq)