Skip to content

Commit

Permalink
Merge pull request #38 from sp-nitech/update_gmm
Browse files Browse the repository at this point in the history
Update gmm
  • Loading branch information
takenori-y committed May 29, 2023
2 parents 40a13ab + 35a84e6 commit 117b1d2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 20 deletions.
4 changes: 3 additions & 1 deletion include/SPTK/math/gaussian_mixture_modeling.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,14 @@ class GaussianMixtureModeling {
* The shape is @f$[K, M+1]@f$.
* @param[in,out] covariance_matrices @f$K@f$ covariance matrices.
* The shape is @f$[K, M+1, M+1]@f$.
* @param[out] total_log_likelihood Total log-likelihood.
* @return True on success, false on failure.
*/
bool Run(const std::vector<std::vector<double> >& input_vectors,
std::vector<double>* weights,
std::vector<std::vector<double> >* mean_vectors,
std::vector<SymmetricMatrix>* covariance_matrices) const;
std::vector<SymmetricMatrix>* covariance_matrices,
double* total_log_likelihood) const;

/**
* Calculate log-probablity of data.
Expand Down
63 changes: 46 additions & 17 deletions src/main/gmm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,28 @@ void PrintUsage(std::ostream* stream) {
*stream << " usage:" << std::endl;
*stream << " gmm [ options ] [ infile ] > stdout" << std::endl;
*stream << " options:" << std::endl;
*stream << " -l l : length of vector ( int)[" << std::setw(5) << std::right << kDefaultNumOrder + 1 << "][ 1 <= l <= ]" << std::endl; // NOLINT
*stream << " -m m : order of vector ( int)[" << std::setw(5) << std::right << "l-1" << "][ 0 <= m <= ]" << std::endl; // NOLINT
*stream << " -k k : number of mixtures ( int)[" << std::setw(5) << std::right << kDefaultNumMixture << "][ 1 <= k <= ]" << std::endl; // NOLINT
*stream << " -i i : number of iterations ( int)[" << std::setw(5) << std::right << kDefaultNumIteration << "][ 1 <= i <= ]" << std::endl; // NOLINT
*stream << " -d d : convergence threshold (double)[" << std::setw(5) << std::right << kDefaultConvergenceThreshold << "][ 0.0 <= d <= ]" << std::endl; // NOLINT
*stream << " -w w : floor value of weight (double)[" << std::setw(5) << std::right << kDefaultWeightFloor << "][ 0.0 <= w <= 1/k ]" << std::endl; // NOLINT
*stream << " -v v : floor value of variance (double)[" << std::setw(5) << std::right << kDefaultVarianceFloor << "][ 0.0 <= v <= ]" << std::endl; // NOLINT
*stream << " -M M : MAP smoothing parameter (double)[" << std::setw(5) << std::right << kDefaultSmoothingParameter << "][ 0.0 <= M <= 1.0 ]" << std::endl; // NOLINT
*stream << " -U U : input filename of double (string)[" << std::setw(5) << std::right << "N/A" << "]" << std::endl; // NOLINT
*stream << " -l l : length of vector ( int)[" << std::setw(5) << std::right << kDefaultNumOrder + 1 << "][ 1 <= l <= ]" << std::endl; // NOLINT
*stream << " -m m : order of vector ( int)[" << std::setw(5) << std::right << "l-1" << "][ 0 <= m <= ]" << std::endl; // NOLINT
*stream << " -k k : number of mixtures ( int)[" << std::setw(5) << std::right << kDefaultNumMixture << "][ 1 <= k <= ]" << std::endl; // NOLINT
*stream << " -i i : number of iterations ( int)[" << std::setw(5) << std::right << kDefaultNumIteration << "][ 1 <= i <= ]" << std::endl; // NOLINT
*stream << " -d d : convergence threshold (double)[" << std::setw(5) << std::right << kDefaultConvergenceThreshold << "][ 0.0 <= d <= ]" << std::endl; // NOLINT
*stream << " -w w : floor value of weight (double)[" << std::setw(5) << std::right << kDefaultWeightFloor << "][ 0.0 <= w <= 1/k ]" << std::endl; // NOLINT
*stream << " -v v : floor value of variance (double)[" << std::setw(5) << std::right << kDefaultVarianceFloor << "][ 0.0 <= v <= ]" << std::endl; // NOLINT
*stream << " -M M : MAP smoothing parameter (double)[" << std::setw(5) << std::right << kDefaultSmoothingParameter << "][ 0.0 <= M <= 1.0 ]" << std::endl; // NOLINT
*stream << " -U U : input filename of double (string)[" << std::setw(5) << std::right << "N/A" << "]" << std::endl; // NOLINT
*stream << " type initial GMM parameters" << std::endl;
*stream << " -f : use full covariance ( bool)[" << std::setw(5) << std::right << sptk::ConvertBooleanToString(kDefaultFullCovarianceFlag) << "]" << std::endl; // NOLINT
*stream << " -V : show log-likelihood ( bool)[" << std::setw(5) << std::right << sptk::ConvertBooleanToString(kDefaultShowLikelihoodFlag) << "]" << std::endl; // NOLINT
*stream << " -S S : output filename of double (string)[" << std::setw(5) << std::right << "N/A" << "]" << std::endl; // NOLINT
*stream << " type total log-likliehood" << std::endl;
*stream << " -f : use full covariance ( bool)[" << std::setw(5) << std::right << sptk::ConvertBooleanToString(kDefaultFullCovarianceFlag) << "]" << std::endl; // NOLINT
*stream << " -V : show avg. log-likelihood ( bool)[" << std::setw(5) << std::right << sptk::ConvertBooleanToString(kDefaultShowLikelihoodFlag) << "]" << std::endl; // NOLINT
*stream << " (level 2)" << std::endl;
*stream << " -B B1 .. Bp : block size of ( int)[" << std::setw(5) << std::right << "N/A" << "][ 1 <= B <= l ]" << std::endl; // NOLINT
*stream << " -B B1 .. Bp : block size of ( int)[" << std::setw(5) << std::right << "N/A" << "][ 1 <= B <= l ]" << std::endl; // NOLINT
*stream << " covariance matrix" << std::endl;
*stream << " -h : print this message" << std::endl;
*stream << " infile:" << std::endl;
*stream << " training data sequence (double)[stdin]" << std::endl; // NOLINT
*stream << " training data sequence (double)[stdin]" << std::endl; // NOLINT
*stream << " stdout:" << std::endl;
*stream << " GMM parameters (double)" << std::endl;
*stream << " GMM parameters (double)" << std::endl;
*stream << " notice:" << std::endl;
*stream << " -B option requires B1 + B2 + ... + Bp = l" << std::endl;
*stream << " -M option requires -U option" << std::endl;
Expand Down Expand Up @@ -96,10 +98,12 @@ void PrintUsage(std::ostream* stream) {
* - MAP smoothing parameter @f$(0 \le \alpha \le 1)@f$
* - @b -U @e str
* - double-type initial GMM parameters
* - @b -S @e str
* - double-type total log-likelihood
* - @b -f
* - use full covariance
* - @b -V
* - show log likelihood at each iteration
* - show average log likelihood at each iteration
* - @b -B @e int+
* - block size of covariance matrix
* - @b infile @e str
Expand Down Expand Up @@ -137,13 +141,14 @@ int main(int argc, char* argv[]) {
double variance_floor(kDefaultVarianceFloor);
double smoothing_parameter(kDefaultSmoothingParameter);
const char* initial_gmm_file(NULL);
const char* log_likelihood_file(NULL);
bool full_covariance_flag(kDefaultFullCovarianceFlag);
bool show_likelihood_flag(kDefaultShowLikelihoodFlag);
std::vector<int> block_size;

for (;;) {
const int option_char(
getopt_long(argc, argv, "l:m:k:i:d:w:v:M:U:fVB:h", NULL, NULL));
getopt_long(argc, argv, "l:m:k:i:d:w:v:M:U:S:fVB:h", NULL, NULL));
if (-1 == option_char) break;

switch (option_char) {
Expand Down Expand Up @@ -240,6 +245,10 @@ int main(int argc, char* argv[]) {
initial_gmm_file = optarg;
break;
}
case 'S': {
log_likelihood_file = optarg;
break;
}
case 'f': {
full_covariance_flag = true;
break;
Expand Down Expand Up @@ -385,8 +394,9 @@ int main(int argc, char* argv[]) {
return 1;
}

double log_likelihood;
if (!gaussian_mixture_modeling.Run(input_vectors, &weights, &mean_vectors,
&covariance_matrices)) {
&covariance_matrices, &log_likelihood)) {
std::ostringstream error_message;
error_message << "Failed to train Gaussian mixture models. "
<< "Please consider the following attemps: "
Expand Down Expand Up @@ -432,5 +442,24 @@ int main(int argc, char* argv[]) {
}
}

if (NULL != log_likelihood_file) {
std::ofstream ofs;
ofs.open(log_likelihood_file, std::ios::out | std::ios::binary);
if (ofs.fail()) {
std::ostringstream error_message;
error_message << "Cannot open file " << log_likelihood_file;
sptk::PrintErrorMessage("gmm", error_message);
return 1;
}
std::ostream& output_stream(ofs);

if (!sptk::WriteStream(log_likelihood, &output_stream)) {
std::ostringstream error_message;
error_message << "Failed to write log-likelihood";
sptk::PrintErrorMessage("gmm", error_message);
return 1;
}
}

return 0;
}
7 changes: 5 additions & 2 deletions src/math/gaussian_mixture_modeling.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,12 @@ bool GaussianMixtureModeling::Run(
const std::vector<std::vector<double> >& input_vectors,
std::vector<double>* weights,
std::vector<std::vector<double> >* mean_vectors,
std::vector<SymmetricMatrix>* covariance_matrices) const {
std::vector<SymmetricMatrix>* covariance_matrices,
double* total_log_likelihood) const {
// Check inputs.
if (!is_valid_ || input_vectors.empty() || NULL == weights ||
NULL == mean_vectors || NULL == covariance_matrices) {
NULL == mean_vectors || NULL == covariance_matrices ||
NULL == total_log_likelihood) {
return false;
}

Expand Down Expand Up @@ -332,6 +334,7 @@ bool GaussianMixtureModeling::Run(
FloorVariance(covariance_matrices);

// Check convergence.
*total_log_likelihood = log_likelihood;
log_likelihood /= num_data;
const double change(log_likelihood - prev_log_likelihood);
if (0 == n % log_interval_) {
Expand Down

0 comments on commit 117b1d2

Please sign in to comment.