nnet-stats.cc
Go to the documentation of this file.
1 // nnet2/nnet-stats.cc
2 
3 // Copyright 2012 Johns Hopkins University (author: Daniel Povey)
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 "nnet2/nnet-stats.h"
21 
22 namespace kaldi {
23 namespace nnet2 {
24 
25 void NnetStats::StatsElement::PrintStats(std::ostream &os) {
26  BaseFloat c = (count == 0 ? 1 : count), // prevent division by zero.
27  deriv_mean = deriv_sum/c,
28  deriv_stddev = std::sqrt(deriv_sumsq/c - deriv_mean*deriv_mean),
29  abs_value_mean = abs_value_sum/c,
30  abs_value_stddev = std::sqrt(abs_value_sumsq/c -
31  abs_value_mean*abs_value_mean);
32 
33  os << '[' << deriv_begin << ':' << deriv_end << "] count=" << count
34  << ", deriv mean,stddev=" << deriv_mean << ',' << deriv_stddev
35  << ", abs-avg-value mean,stddev=" << abs_value_mean << ','
36  << abs_value_stddev;
37 }
38 
40  count++;
41  deriv_sum += avg_deriv;
42  deriv_sumsq += avg_deriv * avg_deriv;
43  abs_value_sum += std::abs(avg_value);
44  abs_value_sumsq += avg_value * avg_value;
45 }
46 
48  KALDI_ASSERT(avg_deriv >= 0.0);
50  // cast ratio to int. Since we do +0.5, this rounds down.
51  int32 index = static_cast<int32>(avg_deriv / bucket_width_ + 0.5);
52  while (index >= static_cast<int32>(buckets_.size()))
53  buckets_.push_back(StatsElement(buckets_.size() * bucket_width_,
54  (buckets_.size() + 1) * bucket_width_));
55  return index;
56 }
57 
58 void NnetStats::AddStats(BaseFloat avg_deriv, BaseFloat avg_value) {
59  global_.AddStats(avg_deriv, avg_value);
60  buckets_[BucketFor(avg_deriv)].AddStats(avg_deriv, avg_value);
61 }
62 
63 void NnetStats::AddStatsFromNnet(const Nnet &nnet) {
64  const AffineComponent *ac = dynamic_cast<const AffineComponent*>(
66  KALDI_ASSERT(ac != NULL); // would be an error in calling code.
67  const NonlinearComponent *nc = dynamic_cast<const NonlinearComponent*>(
69  KALDI_ASSERT(nc != NULL); // would be an error in calling code.
70 
71  double count = nc->Count();
72  if (count == 0) {
73  KALDI_WARN << "No stats stored with nonlinear component";
74  return;
75  }
76  const CuVector<double> &value_sum = nc->ValueSum();
77  const CuVector<double> &deriv_sum = nc->DerivSum();
78  if (value_sum.Dim() != deriv_sum.Dim())
79  KALDI_ERR << "Error computing nnet stats: probably you are "
80  << "trying to compute stats for a sigmoid layer.";
81  for (int32 i = 0; i < value_sum.Dim(); i++) {
82  BaseFloat avg_value = value_sum(i) / count,
83  avg_deriv = deriv_sum(i) / count;
84  AddStats(avg_deriv, avg_value);
85  }
86 }
87 
88 void NnetStats::PrintStats(std::ostream &os) {
89  os << "Stats for buckets:" << std::endl;
90  for (size_t i = 0; i < buckets_.size(); i++) {
91  buckets_[i].PrintStats(os);
92  os << std::endl;
93  }
94  os << "Global stats: ";
95  global_.PrintStats(os);
96  os << std::endl;
97 }
98 
99 void GetNnetStats(const NnetStatsConfig &config,
100  const Nnet &nnet,
101  std::vector<NnetStats> *stats) {
102  KALDI_ASSERT(stats->size() == 0);
103  for (int32 c = 0; c + 1 < nnet.NumComponents(); c++) {
104  const AffineComponent *ac = dynamic_cast<const AffineComponent*>(
105  &(nnet.GetComponent(c)));
106  if (ac == NULL) continue;
107  const NonlinearComponent *nc = dynamic_cast<const NonlinearComponent*>(
108  &(nnet.GetComponent(c + 1)));
109  if (nc == NULL) continue;
110  // exclude softmax.
111  const SoftmaxComponent *sc = dynamic_cast<const SoftmaxComponent*>(
112  &(nnet.GetComponent(c + 1)));
113  if (sc != NULL) continue;
114  stats->push_back(NnetStats(c, config.bucket_width));
115  stats->back().AddStatsFromNnet(nnet);
116  }
117 }
118 
119 
120 
121 } // namespace nnet2
122 } // namespace kaldi
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
const Component & GetComponent(int32 c) const
Definition: nnet-nnet.cc:141
This kind of Component is a base-class for things like sigmoid and softmax.
void AddStats(BaseFloat avg_deriv, BaseFloat avg_value)
Definition: nnet-stats.cc:58
std::vector< StatsElement > buckets_
Definition: nnet-stats.h:84
void PrintStats(std::ostream &os)
Definition: nnet-stats.cc:88
kaldi::int32 int32
StatsElement global_
Definition: nnet-stats.h:85
void GetNnetStats(const NnetStatsConfig &config, const Nnet &nnet, std::vector< NnetStats > *stats)
Definition: nnet-stats.cc:99
void AddStatsFromNnet(const Nnet &nnet)
Definition: nnet-stats.cc:63
StatsElement(BaseFloat deriv_begin, BaseFloat deriv_end)
Definition: nnet-stats.h:69
int32 BucketFor(BaseFloat avg_deriv)
Definition: nnet-stats.cc:47
int32 NumComponents() const
Returns number of components– think of this as similar to # of layers, but e.g.
Definition: nnet-nnet.h:69
NnetStats(int32 affine_component_index, BaseFloat bucket_width)
Definition: nnet-stats.h:46
#define KALDI_ERR
Definition: kaldi-error.h:147
const CuVector< double > & ValueSum() const
#define KALDI_WARN
Definition: kaldi-error.h:150
void PrintStats(std::ostream &os)
Definition: nnet-stats.cc:25
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
void AddStats(BaseFloat avg_deriv, BaseFloat avg_value)
Definition: nnet-stats.cc:39
const CuVector< double > & DerivSum() const
MatrixIndexT Dim() const
Dimensions.
Definition: cu-vector.h:69