logistic-regression-test.cc
Go to the documentation of this file.
1 // ivector/logistic-regression-test.cc
2 
3 // Copyright 2014 David Snyder
4 
5 // See ../../COPYING for clarification regarding multiple authors
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 // MERCHANTABLITY OR NON-INFRINGEMENT.
17 // See the Apache 2 License for the specific language governing permissions and
18 // limitations under the License.
19 
20 #include <time.h>
22 
23 namespace kaldi {
24 
26  int32 n_features = Rand() % 600 + 10,
27  n_xs = Rand() % 200 + 100,
28  n_labels = Rand() % 20 + 10;
29 
31  conf.max_steps = 20;
32  conf.normalizer = 0.001;
33 
34  Matrix<BaseFloat> xs(n_xs, n_features);
35  xs.SetRandn();
36  Matrix<BaseFloat> weights(n_labels, n_features + 1);
37  weights.SetRandn();
39  std::vector<int32> classes;
40  for (int32 i = 0; i < weights.NumRows(); i++) {
41  classes.push_back(i);
42  }
43  classifier.SetWeights(weights, classes);
44 
45  // Get posteriors for the xs using batch and serial methods.
46  Matrix<BaseFloat> batch_log_posteriors;
47  classifier.GetLogPosteriors(xs, &batch_log_posteriors);
48  Matrix<BaseFloat> log_posteriors(n_xs, n_labels);
49  for (int32 i = 0; i < n_xs; i++) {
50  Vector<BaseFloat> x(n_features);
51  x.CopyRowFromMat(xs, i);
52  Vector<BaseFloat> log_post;
53  classifier.GetLogPosteriors(x, &log_post);
54 
55  // Verify that sum_y p(y|x) = 1.0.
56  Vector<BaseFloat> post(log_post);
57  post.ApplyExp();
58  KALDI_ASSERT(ApproxEqual(post.Sum(), 1.0));
59  log_posteriors.Row(i).CopyFromVec(log_post);
60  }
61 
62  // Verify equivalence of batch and serial methods.
63  float tolerance = 0.01;
64  KALDI_ASSERT(log_posteriors.ApproxEqual(batch_log_posteriors, tolerance));
65 }
66 
67 void UnitTestTrain() {
68 
69  int32 n_features = Rand() % 600 + 10,
70  n_xs = Rand() % 200 + 100,
71  n_labels = Rand() % 20 + 10;
72  double normalizer = 0.01;
73  Matrix<BaseFloat> xs(n_xs, n_features);
74  xs.SetRandn();
75 
76  std::vector<int32> ys;
77  for (int32 i = 0; i < n_xs; i++) {
78  ys.push_back(Rand() % n_labels);
79  }
80 
82  conf.max_steps = 20;
83  conf.normalizer = normalizer;
84  // Train the classifier
86  classifier.Train(xs, ys, conf);
87 
88  // Internally in LogisticRegression we add an additional element to
89  // the x vectors: a 1.0 which handles the prior.
90  Matrix<BaseFloat> xs_with_prior(n_xs, n_features + 1);
91  for (int32 i = 0; i < n_xs; i++) {
92  xs_with_prior(i, n_features) = 1.0;
93  }
94  SubMatrix<BaseFloat> sub_xs(xs_with_prior, 0, n_xs, 0, n_features);
95  sub_xs.CopyFromMat(xs);
96 
97  Matrix<BaseFloat> xw(n_xs, n_labels);
98  xw.AddMatMat(1.0, xs_with_prior, kNoTrans, classifier.weights_,
99  kTrans, 0.0);
100 
101  Matrix<BaseFloat> grad(classifier.weights_.NumRows(),
102  classifier.weights_.NumCols());
103 
104  double objf_trained = classifier.GetObjfAndGrad(xs_with_prior,
105  ys, xw, &grad, normalizer);
106 
107  // Calculate objective function using a random weight matrix.
108  Matrix<BaseFloat> xw_rand(n_xs, n_labels);
109 
110  Matrix<BaseFloat> weights_rand(classifier.weights_);
111  weights_rand.SetRandn();
112  xw.AddMatMat(1.0, xs_with_prior, kNoTrans, weights_rand,
113  kTrans, 0.0);
114 
115  // Verify that the objective function after training is better
116  // than the objective function with a random weight matrix.
117  double objf_rand_w = classifier.GetObjfAndGrad(xs_with_prior, ys,
118  xw_rand, &grad, normalizer);
119  KALDI_ASSERT(objf_trained > objf_rand_w);
120  KALDI_ASSERT(objf_trained > Log(1.0 / n_xs));
121 }
122 }
123 
124 int main() {
125  using namespace kaldi;
126  srand (time(NULL));
127  UnitTestTrain();
129  return 0;
130 }
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
void ApplyExp()
Apply exponential to each value in vector.
BaseFloat GetObjfAndGrad(const Matrix< BaseFloat > &xs, const std::vector< int32 > &ys, const Matrix< BaseFloat > &xw, Matrix< BaseFloat > *grad, BaseFloat normalizer)
MatrixIndexT NumCols() const
Returns number of columns (or zero for empty matrix).
Definition: kaldi-matrix.h:67
bool ApproxEqual(const MatrixBase< Real > &other, float tol=0.01) const
Returns true if ((*this)-other).FrobeniusNorm() <= tol * (*this).FrobeniusNorm(). ...
kaldi::int32 int32
void Train(const Matrix< BaseFloat > &xs, const std::vector< int32 > &ys, const LogisticRegressionConfig &conf)
void CopyFromMat(const MatrixBase< OtherReal > &M, MatrixTransposeType trans=kNoTrans)
Copy given matrix. (no resize is done).
void CopyRowFromMat(const MatrixBase< Real > &M, MatrixIndexT row)
Extracts a row of the matrix M.
void GetLogPosteriors(const Matrix< BaseFloat > &xs, Matrix< BaseFloat > *log_posteriors)
const SubVector< Real > Row(MatrixIndexT i) const
Return specific row of matrix [const].
Definition: kaldi-matrix.h:188
double Log(double x)
Definition: kaldi-math.h:100
void SetRandn()
Sets to random values of a normal distribution.
void AddMatMat(const Real alpha, const MatrixBase< Real > &A, MatrixTransposeType transA, const MatrixBase< Real > &B, MatrixTransposeType transB, const Real beta)
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:45
Real Sum() const
Returns sum of the elements.
A class representing a vector.
Definition: kaldi-vector.h:406
void SetWeights(const Matrix< BaseFloat > &weights, const std::vector< int32 > classes)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
MatrixIndexT NumRows() const
Returns number of rows (or zero for empty matrix).
Definition: kaldi-matrix.h:64
Matrix< BaseFloat > weights_
void UnitTestPosteriors()
Sub-matrix representation.
Definition: kaldi-matrix.h:988
static bool ApproxEqual(float a, float b, float relative_tolerance=0.001)
return abs(a - b) <= relative_tolerance * (abs(a)+abs(b)).
Definition: kaldi-math.h:265