43 if (auxf_impr) *auxf_impr = 0.0;
49 &&
"We didn't make the update cover this case sensibly (update vars not means)");
53 mean->
AddVec(D, orig_mean);
56 mean->
AddVec(1.0, x_stats);
57 var->
AddVec(1.0, x2_stats);
63 if (!(flags&kGmmVariances)) var->
CopyFromVec(orig_var);
64 if (!(flags&kGmmMeans)) mean->
CopyFromVec(orig_mean);
68 double m = ((*mean)(
i)), v = ((*var)(
i));
69 if (m!=m || v!=v || m-m != 0 || v-v != 0) {
74 if (var->
Min() > 0.0) {
75 if (auxf_impr != NULL) {
81 old_auxf += (occ+D) * -0.5 * (
Log(orig_var(
i)) +
82 ((*var)(
i) + mean_diff*mean_diff)
84 new_auxf += (occ+D) * -0.5 * (
Log((*var)(
i)) + 1.0);
87 *auxf_impr = new_auxf - old_auxf;
101 int32 *num_floored_out) {
103 if (flags & ~acc_flags)
104 KALDI_ERR <<
"Incompatible flags: you requested to update flags \"" 111 if (den_stats.
Flags() != acc_flags) {
112 den_has_stats =
false;
114 KALDI_ERR <<
"Incompatible flags: num stats have flags \"" 118 den_has_stats =
true;
136 Vector<double> mean(dim), var(dim), mean_stats(dim), var_stats(dim);
138 for (
int32 g = 0; g < num_comp; g++) {
141 if (num_count == 0.0 && den_count == 0.0) {
142 KALDI_VLOG(2) <<
"Not updating Gaussian " << g <<
" since counts are zero";
153 double D = (opts.
tau + opts.
E * den_count) / 2;
154 if (D+num_count-den_count <= 0.0) {
156 D = -1.0001*(num_count-den_count) + 1.0e-10;
163 int32 iter, max_iter = 100;
164 for (iter = 0; iter < max_iter; iter++) {
169 mean_stats, var_stats, num_count-den_count,
170 &mean, &var, NULL)) {
174 double auxf_impr = 0.0;
178 mean_stats, var_stats, num_count-den_count,
179 &mean, &var, &auxf_impr);
181 KALDI_WARN <<
"Something went wrong in the EBW update. Check that your" 182 "previous update phase looks reasonable, probably your model is " 183 "already ruined. Reverting to the old values";
185 if (auxf_change_out) *auxf_change_out += auxf_impr;
186 if (count_out) *count_out += den_count;
198 if (iter > 0 && num_floored_out != NULL) (*num_floored_out)++;
199 if (iter == max_iter)
KALDI_WARN <<
"Dropped off end of loop, recomputing D. (unexpected.)";
221 if (opts.
tau == 0.0 &&
223 KALDI_LOG <<
"Not updating weights for this state because total count is " 224 << num_occs.Sum() + den_occs.Sum() <<
" < " 227 *count_out += num_occs.Sum();
230 num_occs.AddVec(opts.
tau, weights);
231 KALDI_ASSERT(weights.Dim() == num_occs.Dim() && num_occs.Dim() == den_occs.Dim());
232 if (weights.Dim() == 1)
return;
233 double weight_auxf_at_start = 0.0, weight_auxf_at_end = 0.0;
235 int32 num_comp = weights.Dim();
236 for (
int32 g = 0; g < num_comp; g++) {
237 weight_auxf_at_start +=
238 num_occs(g) * log (weights(g))
239 - den_occs(g) * weights(g) / diaggmmnormal.
weights_(g);
241 for (
int32 iter = 0; iter < 50; iter++) {
244 for (
int32 g = 0; g < num_comp; g++)
245 max_m = std::max(max_m, den_occs(g)/diaggmmnormal.
weights_(g));
246 for (
int32 g = 0; g < num_comp; g++)
247 k_jm(g) = max_m - den_occs(g)/diaggmmnormal.
weights_(g);
248 for (
int32 g = 0; g < num_comp; g++)
249 weights(g) = num_occs(g) + k_jm(g)*weights(g);
250 weights.Scale(1.0 / weights.Sum());
252 for (
int32 g = 0; g < num_comp; g++) {
256 weights.Scale(1.0 / weights.Sum());
259 for (
int32 g = 0; g < num_comp; g++) {
260 weight_auxf_at_end +=
261 num_occs(g) * log (weights(g))
262 - den_occs(g) * weights(g) / diaggmmnormal.
weights_(g);
266 *auxf_change_out += weight_auxf_at_end - weight_auxf_at_start;
268 *count_out += num_occs.
Sum();
285 int32 *num_floored_out) {
289 if (auxf_change_out) *auxf_change_out = 0.0;
290 if (count_out) *count_out = 0.0;
291 if (num_floored_out) *num_floored_out = 0.0;
295 opts, &(am_gmm->
GetPdf(pdf)), auxf_change_out,
296 count_out, num_floored_out);
309 if (auxf_change_out) *auxf_change_out = 0.0;
310 if (count_out) *count_out = 0.0;
314 opts, &(am_gmm->
GetPdf(pdf)), auxf_change_out,
323 for (
int32 g = 0; g < num_gauss; g++) {
331 x_stats.Scale(tau / occ);
332 x2_stats.
Scale(tau / occ);
347 for (
int32 g = 0; g < num_gauss; g++) {
348 double occ = state_occ * gmmnormal.
weights_(g);
350 x_stats.AddVec(occ, gmmnormal.
means_.
Row(g));
361 int num_pdfs = src_stats.
NumAccs();
363 for (
int32 pdf = 0; pdf < num_pdfs; pdf++)
370 int num_pdfs = src_model.
NumPdfs();
372 for (
int32 pdf = 0; pdf < num_pdfs; pdf++) {
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
int32 Dim() const
Returns the dimensionality of the Gaussian mean vectors.
GmmFlagsType AugmentGmmFlags(GmmFlagsType f)
Returns "augmented" version of flags: e.g.
Definition for Gaussian Mixture Model with diagonal covariances in normal mode: where the parameters ...
void UpdateEbwWeightsDiagGmm(const AccumDiagGmm &num_stats, const AccumDiagGmm &den_stats, const EbwWeightOptions &opts, DiagGmm *gmm, BaseFloat *auxf_change_out, BaseFloat *count_out)
int32 ComputeGconsts()
Sets the gconsts.
const VectorBase< double > & occupancy() const
void CopyFromDiagGmm(const DiagGmm &diaggmm)
Copies from given DiagGmm.
uint16 GmmFlagsType
Bitwise OR of the above flags.
Real Min() const
Returns the minimum value of any element, or +infinity for the empty vector.
void IsmoothStatsDiagGmm(const AccumDiagGmm &src_stats, double tau, AccumDiagGmm *dst_stats)
I-Smooth the stats. src_stats and dst_stats do not have to be different.
void UpdateEbwDiagGmm(const AccumDiagGmm &num_stats, const AccumDiagGmm &den_stats, GmmFlagsType flags, const EbwOptions &opts, DiagGmm *gmm, BaseFloat *auxf_change_out, BaseFloat *count_out, int32 *num_floored_out)
void AddVec2(const Real alpha, const VectorBase< Real > &v)
Add vector : *this = *this + alpha * rv^2 [element-wise squaring].
void UpdateEbwWeightsAmDiagGmm(const AccumAmDiagGmm &num_stats, const AccumAmDiagGmm &den_stats, const EbwWeightOptions &opts, AmDiagGmm *am_gmm, BaseFloat *auxf_change_out, BaseFloat *count_out)
void CopyFromVec(const VectorBase< Real > &v)
Copy data from another vector (must match own size).
const SubVector< Real > Row(MatrixIndexT i) const
Return specific row of matrix [const].
void IsmoothStatsAmDiagGmmFromModel(const AmDiagGmm &src_model, double tau, AccumAmDiagGmm *dst_stats)
This version of the I-smoothing function takes a model as input.
const MatrixBase< double > & variance_accumulator() const
const MatrixBase< double > & mean_accumulator() const
GmmFlagsType Flags() const
void AddStatsForComponent(int32 comp_id, double occ, const VectorBase< double > &x_stats, const VectorBase< double > &x2_stats)
Increment the stats for this component by the specified amount (not all parts may be taken...
static bool EBWUpdateGaussian(BaseFloat D, GmmFlagsType flags, const VectorBase< double > &orig_mean, const VectorBase< double > &orig_var, const VectorBase< double > &x_stats, const VectorBase< double > &x2_stats, double occ, VectorBase< double > *mean, VectorBase< double > *var, double *auxf_impr)
void IsmoothStatsAmDiagGmm(const AccumAmDiagGmm &src_stats, double tau, AccumAmDiagGmm *dst_stats)
Smooth "dst_stats" with "src_stats".
BaseFloat min_num_count_weight_update
Matrix< double > vars_
diagonal variance
int32 NumGauss() const
Returns the number of mixture components in the GMM.
MatrixIndexT Dim() const
Returns the dimension of the vector.
void Scale(Real alpha)
Multiplies all elements by this constant.
Real Sum() const
Returns sum of the elements.
int32 Dim() const
Returns the dimensionality of the feature vectors.
BaseFloat min_gaussian_weight
Matrix< double > means_
Means.
DiagGmm & GetPdf(int32 pdf_index)
Accessors.
const AccumDiagGmm & GetAcc(int32 index) const
#define KALDI_ASSERT(cond)
void CopyRowFromVec(const VectorBase< Real > &v, const MatrixIndexT row)
Copy vector into specific row of matrix.
Definition for Gaussian Mixture Model with diagonal covariances.
std::string GmmFlagsToString(GmmFlagsType flags)
Convert GMM flags to string.
void UpdateEbwAmDiagGmm(const AccumAmDiagGmm &num_stats, const AccumAmDiagGmm &den_stats, GmmFlagsType flags, const EbwOptions &opts, AmDiagGmm *am_gmm, BaseFloat *auxf_change_out, BaseFloat *count_out, int32 *num_floored_out)
Vector< double > weights_
weights (not log).
Provides a vector abstraction class.
void SetZero()
Set vector to all zeros.
void Resize(int32 num_gauss, int32 dim, GmmFlagsType flags)
Allocates memory for accumulators.
void AddVec(const Real alpha, const VectorBase< OtherReal > &v)
Add vector : *this = *this + alpha * rv (with casting between floats and doubles) ...
int32 NumGauss() const
Returns the number of mixture components.
void DiagGmmToStats(const DiagGmm &gmm, GmmFlagsType flags, double state_occ, AccumDiagGmm *dst_stats)
Creates stats from the GMM. Resizes them as needed.
void CopyToDiagGmm(DiagGmm *diaggmm, GmmFlagsType flags=kGmmAll) const
Copies to DiagGmm the requested parameters.