nnet-utils.h
Go to the documentation of this file.
1 // nnet/nnet-utils.h
2 
3 // Copyright 2015 Brno University of Technology (author: Karel Vesely)
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 
21 #ifndef KALDI_NNET_NNET_UTILS_H_
22 #define KALDI_NNET_NNET_UTILS_H_
23 
24 #include <string>
25 #include <vector>
26 #include <iterator>
27 #include <algorithm>
28 
29 #include "base/kaldi-common.h"
30 #include "cudamatrix/cu-matrix.h"
31 #include "cudamatrix/cu-array.h"
32 #include "hmm/posterior.h"
33 #include "hmm/transition-model.h"
34 
35 namespace kaldi {
36 namespace nnet1 {
37 
38 
42 template <typename T>
43 std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
44  std::copy(v.begin(), v.end(), std::ostream_iterator<T>(os, " "));
45  return os;
46 }
47 
51 template <typename T>
52 std::string ToString(const T& t) {
53  std::ostringstream os;
54  os << t;
55  return os.str();
56 }
57 
62 template <typename Real>
63 std::string MomentStatistics(const VectorBase<Real> &vec) {
64  // we use an auxiliary vector for the higher order powers
65  Vector<Real> vec_aux(vec);
66  Vector<Real> vec_no_mean(vec); // vec with mean subtracted
67  // mean
68  Real mean = vec.Sum() / vec.Dim();
69  // variance
70  vec_aux.Add(-mean);
71  vec_no_mean = vec_aux;
72  vec_aux.MulElements(vec_no_mean); // (vec-mean)^2
73  Real variance = vec_aux.Sum() / vec.Dim();
74  // skewness
75  // - negative : left tail is longer,
76  // - positive : right tail is longer,
77  // - zero : symmetric
78  vec_aux.MulElements(vec_no_mean); // (vec-mean)^3
79  Real skewness = vec_aux.Sum() / pow(variance, 3.0/2.0) / vec.Dim();
80  // kurtosis (peakedness)
81  // - makes sense for symmetric distributions (skewness is zero)
82  // - positive : 'sharper peak' than Normal distribution
83  // - negative : 'heavier tails' than Normal distribution
84  // - zero : same peakedness as the Normal distribution
85  vec_aux.MulElements(vec_no_mean); // (vec-mean)^4
86  Real kurtosis = vec_aux.Sum() / (variance * variance) / vec.Dim() - 3.0;
87  // send the statistics to stream,
88  std::ostringstream ostr;
89  ostr << " ( min " << vec.Min() << ", max " << vec.Max()
90  << ", mean " << mean
91  << ", stddev " << sqrt(variance)
92  << ", skewness " << skewness
93  << ", kurtosis " << kurtosis
94  << " ) ";
95  return ostr.str();
96 }
97 
101 template <typename Real>
102 std::string MomentStatistics(const MatrixBase<Real> &mat) {
103  Vector<Real> vec(mat.NumRows()*mat.NumCols());
104  vec.CopyRowsFromMat(mat);
105  return MomentStatistics(vec);
106 }
107 
111 template <typename Real>
112 std::string MomentStatistics(const CuVectorBase<Real> &vec) {
113  Vector<Real> vec_host(vec.Dim());
114  vec.CopyToVec(&vec_host);
115  return MomentStatistics(vec_host);
116 }
117 
121 template <typename Real>
122 std::string MomentStatistics(const CuMatrixBase<Real> &mat) {
123  Matrix<Real> mat_host(mat.NumRows(), mat.NumCols());
124  mat.CopyToMat(&mat_host);
125  return MomentStatistics(mat_host);
126 }
127 
131 template <typename Real>
132 void CheckNanInf(const CuMatrixBase<Real> &mat, const char *msg = "") {
133  Real sum = mat.Sum();
134  if (KALDI_ISINF(sum)) { KALDI_ERR << "'inf' in " << msg; }
135  if (KALDI_ISNAN(sum)) { KALDI_ERR << "'nan' in " << msg; }
136 }
137 
141 template <typename Real>
143  int32 N = mat.NumRows() * mat.NumCols();
144  Real mean = mat.Sum() / N;
145  CuMatrix<Real> pow_2(mat);
146  pow_2.MulElements(mat);
147  Real var = pow_2.Sum() / N - mean * mean;
148  if (var < 0.0) {
149  KALDI_WARN << "Forcing the variance to be non-negative! " << var << "->0.0";
150  var = 0.0;
151  }
152  return sqrt(var);
153 }
154 
155 
163 template <typename Real>
165  struct RandomState* state = NULL) {
166  // fill temporary matrix with 'Normal' samples,
167  Matrix<Real> m(mat->NumRows(), mat->NumCols(), kUndefined);
168  for (int32 r = 0; r < m.NumRows(); r++) {
169  for (int32 c = 0; c < m.NumCols(); c++) {
170  m(r, c) = RandGauss(state);
171  }
172  }
173  // re-shape the distrbution,
174  m.Scale(sigma);
175  m.Add(mu);
176  // export,
177  mat->CopyFromMat(m);
178 }
179 
187 template <typename Real>
189  struct RandomState* state = NULL) {
190  // fill temporary matrix with '0..1' samples,
191  Matrix<Real> m(mat->NumRows(), mat->NumCols(), kUndefined);
192  for (int32 r = 0; r < m.NumRows(); r++) {
193  for (int32 c = 0; c < m.NumCols(); c++) {
194  m(r, c) = Rand(state) / static_cast<Real>(RAND_MAX);
195  }
196  }
197  // re-shape the distrbution,
198  m.Scale(range); // 0..range,
199  m.Add(mu - (range / 2.0)); // mu-range/2 .. mu+range/2,
200  // export,
201  mat->CopyFromMat(m);
202 }
203 
211 template <typename Real>
213  struct RandomState* state = NULL) {
214  // fill temporary vector with '0..1' samples,
215  Vector<Real> v(vec->Dim(), kUndefined);
216  for (int32 i = 0; i < v.Dim(); i++) {
217  v(i) = Rand(state) / static_cast<Real>(RAND_MAX);
218  }
219  // re-shape the distrbution,
220  v.Scale(range); // 0..range,
221  v.Add(mu - (range / 2.0)); // mu-range/2 .. mu+range/2,
222  // export,
223  vec->CopyFromVec(v);
224 }
225 
226 
239 inline void BuildIntegerVector(const std::vector<std::vector<int32> >& in,
240  std::vector<int32>* out) {
241  // start with empty vector,
242  out->clear();
243  // loop over records,
244  for (int32 i = 0; i < in.size(); i++) {
245  // process i'th record,
246  int32 beg = 0, end = 0, step = 1;
247  switch (in[i].size()) {
248  case 1:
249  beg = in[i][0];
250  end = in[i][0];
251  step = 1;
252  break;
253  case 2:
254  beg = in[i][0];
255  end = in[i][1];
256  step = 1;
257  break;
258  case 3:
259  beg = in[i][0];
260  end = in[i][2];
261  step = in[i][1];
262  break;
263  default:
264  KALDI_ERR << "Something is wrong! (should be 1-3) : "
265  << in[i].size();
266  }
267  // check the inputs,
268  KALDI_ASSERT(beg <= end);
269  KALDI_ASSERT(step > 0); // positive,
270  // append values to vector,
271  for (int32 j = beg; j <= end; j += step) {
272  out->push_back(j);
273  }
274  }
275 }
276 
280 inline void BuildIntegerVector(const std::vector<std::vector<int32> >& in,
281  CuArray<int32>* out) {
282  std::vector<int32> v;
283  BuildIntegerVector(in, &v);
284  (*out) = v;
285 }
286 
287 
291 template <typename Real>
292 void PosteriorToMatrix(const Posterior &post,
293  const int32 post_dim, CuMatrix<Real> *mat) {
294  Matrix<Real> m;
295  PosteriorToMatrix(post, post_dim, &m);
296  (*mat) = m;
297 }
298 
299 
303 template <typename Real>
305  const TransitionModel &model,
306  CuMatrix<Real> *mat) {
308  PosteriorToPdfMatrix(post, model, &m);
309  // Copy to output GPU matrix,
310  (*mat) = m;
311 }
312 
313 
314 } // namespace nnet1
315 } // namespace kaldi
316 
317 #endif // KALDI_NNET_NNET_UTILS_H_
std::string ToString(const T &t)
Convert basic type to a string (please don&#39;t overuse),.
Definition: nnet-utils.h:52
void CopyFromMat(const MatrixBase< OtherReal > &src, MatrixTransposeType trans=kNoTrans)
Definition: cu-matrix.cc:344
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
void PosteriorToPdfMatrix(const Posterior &post, const TransitionModel &model, CuMatrix< Real > *mat)
Wrapper of PosteriorToMatrixMapped with CuMatrix argument.
Definition: nnet-utils.h:304
std::string MomentStatistics(const VectorBase< Real > &vec)
Get a string with statistics of the data in a vector, so we can print them easily.
Definition: nnet-utils.h:63
void CopyToMat(MatrixBase< OtherReal > *dst, MatrixTransposeType trans=kNoTrans) const
Definition: cu-matrix.cc:447
MatrixIndexT NumCols() const
Returns number of columns (or zero for empty matrix).
Definition: kaldi-matrix.h:67
Base class which provides matrix operations not involving resizing or allocation. ...
Definition: kaldi-matrix.h:49
#define KALDI_ISINF
Definition: kaldi-math.h:73
Real Sum() const
Definition: cu-matrix.cc:3012
void RandUniform(BaseFloat mu, BaseFloat range, CuMatrixBase< Real > *mat, struct RandomState *state=NULL)
Fill CuMatrix with random numbers (Uniform distribution): mu = the mean value, range = the &#39;width&#39; of...
Definition: nnet-utils.h:188
kaldi::int32 int32
A class for storing matrices.
Definition: kaldi-matrix.h:823
This class represents a matrix that&#39;s stored on the GPU if we have one, and in memory if not...
Definition: matrix-common.h:71
void PosteriorToMatrix(const Posterior &post, const int32 post_dim, CuMatrix< Real > *mat)
Wrapper of PosteriorToMatrix with CuMatrix argument.
Definition: nnet-utils.h:292
Real Min() const
Returns the minimum value of any element, or +infinity for the empty vector.
float BaseFloat
Definition: kaldi-types.h:29
std::vector< std::vector< std::pair< int32, BaseFloat > > > Posterior
Posterior is a typedef for storing acoustic-state (actually, transition-id) posteriors over an uttera...
Definition: posterior.h:42
void CopyFromVec(const CuVectorBase< Real > &src)
Copy functions; these will crash if the dimension do not match.
Definition: cu-vector.cc:1078
Real ComputeStdDev(const CuMatrixBase< Real > &mat)
Get the standard deviation of values in the matrix.
Definition: nnet-utils.h:142
void MulElements(const VectorBase< Real > &v)
Multiply element-by-element by another vector.
void MulElements(const CuMatrixBase< Real > &A)
Multiply two matrices elementwise: C = C .* A.
Definition: cu-matrix.cc:667
void BuildIntegerVector(const std::vector< std::vector< int32 > > &in, std::vector< int32 > *out)
Build &#39;integer vector&#39; out of vector of &#39;matlab-like&#39; representation: &#39;b, b:e, b:s:e&#39;.
Definition: nnet-utils.h:239
#define KALDI_ERR
Definition: kaldi-error.h:147
Real Max() const
Returns the maximum value of any element, or -infinity for the empty vector.
void RandGauss(BaseFloat mu, BaseFloat sigma, CuMatrixBase< Real > *mat, struct RandomState *state=NULL)
Fill CuMatrix with random numbers (Gaussian distribution): mu = the mean value, sigma = standard devi...
Definition: nnet-utils.h:164
#define KALDI_WARN
Definition: kaldi-error.h:150
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:64
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:45
Real Sum() const
Returns sum of the elements.
Matrix for CUDA computing.
Definition: matrix-common.h:69
MatrixIndexT NumCols() const
Definition: cu-matrix.h:216
A class representing a vector.
Definition: kaldi-vector.h:406
#define KALDI_ISNAN
Definition: kaldi-math.h:72
#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
void CopyRowsFromMat(const MatrixBase< Real > &M)
Performs a row stack of the matrix M.
MatrixIndexT NumRows() const
Dimensions.
Definition: cu-matrix.h:215
Provides a vector abstraction class.
Definition: kaldi-vector.h:41
void Add(Real c)
Add a constant to each element of a vector.
void CopyToVec(VectorBase< OtherReal > *dst) const
Definition: cu-vector.cc:938
void CheckNanInf(const CuMatrixBase< Real > &mat, const char *msg="")
Check that matrix contains no nan or inf.
Definition: nnet-utils.h:132
MatrixIndexT Dim() const
Dimensions.
Definition: cu-vector.h:69
Vector for CUDA computing.
Definition: matrix-common.h:72