nnet-component-test.cc
Go to the documentation of this file.
1 // nnet/nnet-component-test.cc
2 // Copyright 2014-2015 Brno University of Technology (author: Karel Vesely),
3 // The Johns Hopkins University (author: Sri Harish Mallidi)
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 <sstream>
21 #include <fstream>
22 #include <algorithm>
23 
24 #include "nnet/nnet-component.h"
25 #include "nnet/nnet-nnet.h"
28 #include "util/common-utils.h"
29 
30 namespace kaldi {
31 namespace nnet1 {
32 
33  /*
34  * Helper functions
35  */
36  template<typename Real>
37  void ReadCuMatrixFromString(const std::string& s, CuMatrix<Real>* m) {
38  std::istringstream is(s + "\n");
39  m->Read(is, false); // false for ascii
40  }
41 
42  Component* ReadComponentFromString(const std::string& s) {
43  std::istringstream is(s + "\n");
44  return Component::Read(is, false); // false for ascii
45  }
46 
47 
48  /*
49  * Unit tests,
50  */
52  // make L2-length normalization component,
53  Component* c = ReadComponentFromString("<LengthNormComponent> 5 5");
54  // prepare input,
55  CuMatrix<BaseFloat> mat_in;
56  ReadCuMatrixFromString("[ 1 2 3 4 5 \n 2 3 5 6 8 ] ", &mat_in);
57  // propagate,
58  CuMatrix<BaseFloat> mat_out;
59  c->Propagate(mat_in, &mat_out);
60  // check the length,
61  mat_out.MulElements(mat_out); // ^2,
62  CuVector<BaseFloat> check_length_is_one(2);
63  check_length_is_one.AddColSumMat(1.0, mat_out, 0.0); // sum_of_cols(x^2),
64  check_length_is_one.ApplyPow(0.5); // L2norm = sqrt(sum_of_cols(x^2)),
65  CuVector<BaseFloat> ones(2);
66  ones.Set(1.0);
67  AssertEqual(check_length_is_one, ones);
68  }
69 
71  // make SimpleSentenceAveraging component,
73  "<SimpleSentenceAveragingComponent> 2 2 <GradientBoost> 10.0"
74  );
75  // prepare input,
76  CuMatrix<BaseFloat> mat_in;
77  ReadCuMatrixFromString("[ 0 0.5 \n 1 1 \n 2 1.5 ] ", &mat_in);
78 
79  // propagate,
80  CuMatrix<BaseFloat> mat_out;
81  c->Propagate(mat_in, &mat_out);
82  // check the output,
83  CuVector<BaseFloat> ones(2);
84  ones.Set(1.0);
85  for (int32 i = 0; i < mat_out.NumRows(); i++) {
86  AssertEqual(mat_out.Row(i), ones);
87  }
88 
89  // backpropagate,
90  CuMatrix<BaseFloat> dummy1(3, 2), dummy2(3, 2), diff_out(mat_in), diff_in;
91  // the average 1.0 in 'diff_in' will be boosted by 10.0,
92  c->Backpropagate(dummy1, dummy2, diff_out, &diff_in);
93  // check the output,
94  CuVector<BaseFloat> tens(2); tens.Set(10);
95  for (int32 i = 0; i < diff_in.NumRows(); i++) {
96  AssertEqual(diff_in.Row(i), tens);
97  }
98  }
99 
101  // make 'identity' convolutional component,
102  Component* c = ReadComponentFromString("<ConvolutionalComponent> 5 5 \
103  <PatchDim> 1 <PatchStep> 1 <PatchStride> 5 \
104  <LearnRateCoef> 1.0 <BiasLearnRateCoef> 1.0 \
105  <MaxNorm> 0 \
106  <Filters> [ 1 \
107  ] <Bias> [ 0 ]"
108  );
109 
110  // prepare input,
111  CuMatrix<BaseFloat> mat_in;
112  ReadCuMatrixFromString("[ 1 2 3 4 5 ] ", &mat_in);
113 
114  // propagate,
115  CuMatrix<BaseFloat> mat_out;
116  c->Propagate(mat_in, &mat_out);
117  KALDI_LOG << "mat_in" << mat_in << "mat_out" << mat_out;
118  AssertEqual(mat_in, mat_out);
119 
120  // backpropagate,
121  CuMatrix<BaseFloat> mat_out_diff(mat_in), mat_in_diff;
122  c->Backpropagate(mat_in, mat_out, mat_out_diff, &mat_in_diff);
123  KALDI_LOG << "mat_out_diff " << mat_out_diff
124  << " mat_in_diff " << mat_in_diff;
125  AssertEqual(mat_out_diff, mat_in_diff);
126 
127  // clean,
128  delete c;
129  }
130 
132  // make 3x3 convolutional component,
133  // design such weights and input so output is zero,
134  Component* c = ReadComponentFromString("<ConvolutionalComponent> 9 15 \
135  <PatchDim> 3 <PatchStep> 1 <PatchStride> 5 \
136  <LearnRateCoef> 1.0 <BiasLearnRateCoef> 1.0 \
137  <MaxNorm> 0 \
138  <Filters> [ -1 -2 -7 0 0 0 1 2 7 ; \
139  -1 0 1 -3 0 3 -2 2 0 ; \
140  -4 0 0 -3 0 3 4 0 0 ] \
141  <Bias> [ -20 -20 -20 ]"
142  );
143 
144  // prepare input, reference output,
145  CuMatrix<BaseFloat> mat_in;
146  ReadCuMatrixFromString("[ 1 3 5 7 9 2 4 6 8 10 3 5 7 9 11 ]", &mat_in);
147  CuMatrix<BaseFloat> mat_out_ref;
148  ReadCuMatrixFromString("[ 0 0 0 0 0 0 0 0 0 ]", &mat_out_ref);
149 
150  // propagate,
151  CuMatrix<BaseFloat> mat_out;
152  c->Propagate(mat_in, &mat_out);
153  KALDI_LOG << "mat_in" << mat_in << "mat_out" << mat_out;
154  AssertEqual(mat_out, mat_out_ref);
155 
156  // prepare mat_out_diff, mat_in_diff_ref,
157  CuMatrix<BaseFloat> mat_out_diff;
158  ReadCuMatrixFromString("[ 1 0 0 1 1 0 1 1 1 ]", &mat_out_diff);
159  // hand-computed back-propagated values,
160  CuMatrix<BaseFloat> mat_in_diff_ref;
161  ReadCuMatrixFromString("[ -1 -4 -15 -8 -6 0 -3 -6 3 6 1 1 14 11 7 ]",
162  &mat_in_diff_ref);
163 
164  // backpropagate,
165  CuMatrix<BaseFloat> mat_in_diff;
166  c->Backpropagate(mat_in, mat_out, mat_out_diff, &mat_in_diff);
167  KALDI_LOG << "mat_in_diff " << mat_in_diff
168  << " mat_in_diff_ref " << mat_in_diff_ref;
169  AssertEqual(mat_in_diff, mat_in_diff_ref);
170 
171  // clean,
172  delete c;
173  }
174 
175 
177  // make max-pooling component, assuming 4 conv. neurons,
178  // non-overlapping pool of size 3,
180  "<MaxPoolingComponent> <InputDim> 24 <OutputDim> 8 \
181  <PoolSize> 3 <PoolStep> 3 <PoolStride> 4"
182  );
183 
184  // input matrix,
185  CuMatrix<BaseFloat> mat_in;
186  ReadCuMatrixFromString("[ 3 8 2 9 \
187  8 3 9 3 \
188  2 4 9 6 \
189  \
190  2 4 2 0 \
191  6 4 9 4 \
192  7 3 0 3;\
193  \
194  5 4 7 8 \
195  3 9 5 6 \
196  3 4 8 9 \
197  \
198  5 4 5 6 \
199  3 1 4 5 \
200  8 2 1 7 ]", &mat_in);
201 
202  // expected output (max values in columns),
203  CuMatrix<BaseFloat> mat_out_ref;
204  ReadCuMatrixFromString("[ 8 8 9 9 \
205  7 4 9 4;\
206  5 9 8 9 \
207  8 4 5 7 ]", &mat_out_ref);
208 
209  // propagate,
210  CuMatrix<BaseFloat> mat_out;
211  c->Propagate(mat_in, &mat_out);
212  KALDI_LOG << "mat_out" << mat_out << "mat_out_ref" << mat_out_ref;
213  AssertEqual(mat_out, mat_out_ref);
214 
215  // locations of max values will be shown,
216  CuMatrix<BaseFloat> mat_out_diff(mat_out);
217  mat_out_diff.Set(1);
218  // expected backpropagated values (hand-computed),
219  CuMatrix<BaseFloat> mat_in_diff_ref;
220  ReadCuMatrixFromString("[ 0 1 0 1 \
221  1 0 1 0 \
222  0 0 1 0 \
223  \
224  0 1 0 0 \
225  0 1 1 1 \
226  1 0 0 0;\
227  \
228  1 0 0 0 \
229  0 1 0 0 \
230  0 0 1 1 \
231  \
232  0 1 1 0 \
233  0 0 0 0 \
234  1 0 0 1 ]", &mat_in_diff_ref);
235  // backpropagate,
236  CuMatrix<BaseFloat> mat_in_diff;
237  c->Backpropagate(mat_in, mat_out, mat_out_diff, &mat_in_diff);
238  KALDI_LOG << "mat_in_diff " << mat_in_diff
239  << " mat_in_diff_ref " << mat_in_diff_ref;
240  AssertEqual(mat_in_diff, mat_in_diff_ref);
241 
242  delete c;
243  }
244 
246  Component* c = ReadComponentFromString("<Dropout> 100 100 <DropoutRetention> 0.7");
247  // buffers,
248  CuMatrix<BaseFloat> in(777, 100),
249  out,
250  out_diff,
251  in_diff;
252  // init,
253  in.Set(2.0);
254 
255  // propagate,
256  c->Propagate(in, &out);
257  AssertEqual(in.Sum(), out.Sum(), 0.01);
258 
259  // backprop,
260  out_diff = in;
261  c->Backpropagate(in, out, out_diff, &in_diff);
262  AssertEqual(in_diff, out);
263 
264  delete c;
265  }
266 
267 } // namespace nnet1
268 } // namespace kaldi
269 
270 int main() {
271  using namespace kaldi;
272  using namespace kaldi::nnet1;
273 
274  for (kaldi::int32 loop = 0; loop < 2; loop++) {
275 #if HAVE_CUDA == 1
276  if (loop == 0)
277  // use no GPU,
278  CuDevice::Instantiate().SelectGpuId("no");
279  else
280  // use GPU when available,
281  CuDevice::Instantiate().SelectGpuId("optional");
282 #endif
283  // unit-tests :
290  // end of unit-tests,
291  if (loop == 0)
292  KALDI_LOG << "Tests without GPU use succeeded.";
293  else
294  KALDI_LOG << "Tests with GPU use (if available) succeeded.";
295  }
296 #if HAVE_CUDA == 1
297  CuDevice::Instantiate().PrintProfile();
298 #endif
299  return 0;
300 }
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
const CuSubVector< Real > Row(MatrixIndexT i) const
Definition: cu-matrix.h:670
int main()
void Set(Real value)
Definition: cu-vector.cc:1135
Real Sum() const
Definition: cu-matrix.cc:3012
void Backpropagate(const CuMatrixBase< BaseFloat > &in, const CuMatrixBase< BaseFloat > &out, const CuMatrixBase< BaseFloat > &out_diff, CuMatrix< BaseFloat > *in_diff)
Perform backward-pass propagation &#39;out_diff&#39; -> &#39;in_diff&#39;.
kaldi::int32 int32
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
static Component * Init(const std::string &conf_line)
Initialize component from a line in config file,.
void UnitTestSimpleSentenceAveragingComponent()
static Component * Read(std::istream &is, bool binary)
Read the component from a stream (static method),.
Component * ReadComponentFromString(const std::string &s)
void AddColSumMat(Real alpha, const CuMatrixBase< Real > &mat, Real beta=1.0)
Sum the columns of the matrix, add to vector.
Definition: cu-vector.cc:1298
void MulElements(const CuMatrixBase< Real > &A)
Multiply two matrices elementwise: C = C .* A.
Definition: cu-matrix.cc:667
void Propagate(const CuMatrixBase< BaseFloat > &in, CuMatrix< BaseFloat > *out)
Perform forward-pass propagation &#39;in&#39; -> &#39;out&#39;,.
void ApplyPow(Real power)
Definition: cu-vector.h:147
void UnitTestConvolutionalComponentUnity()
void Read(std::istream &is, bool binary)
I/O functions.
Definition: cu-matrix.cc:494
void UnitTestDropoutComponent()
static void AssertEqual(float a, float b, float relative_tolerance=0.001)
assert abs(a - b) <= relative_tolerance * (abs(a)+abs(b))
Definition: kaldi-math.h:276
Abstract class, building block of the network.
void UnitTestConvolutionalComponent3x3()
void UnitTestMaxPoolingComponent()
MatrixIndexT NumRows() const
Dimensions.
Definition: cu-matrix.h:215
#define KALDI_LOG
Definition: kaldi-error.h:153
void Set(Real value)
Definition: cu-matrix.cc:531
void ReadCuMatrixFromString(const std::string &s, CuMatrix< Real > *m)