nnet-show-progress.cc File Reference
Include dependency graph for nnet-show-progress.cc:

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 27 of file nnet-show-progress.cc.

References Nnet::AddNnet(), VectorBase< Real >::AddVec(), VectorBase< Real >::ApplyPow(), Nnet::ComponentDotProducts(), kaldi::nnet2::ComputeNnetGradient(), SequentialTableReader< Holder >::Done(), ParseOptions::GetArg(), AmNnet::GetNnet(), ParseOptions::GetOptArg(), Nnet::GetParameterDim(), KALDI_LOG, KALDI_VLOG, KALDI_WARN, SequentialTableReader< Holder >::Next(), ParseOptions::NumArgs(), Nnet::NumUpdatableComponents(), ParseOptions::PrintUsage(), AmNnet::Read(), ParseOptions::Read(), TransitionModel::Read(), ParseOptions::Register(), Nnet::Scale(), VectorBase< Real >::Scale(), Nnet::SetZero(), Input::Stream(), and SequentialTableReader< Holder >::Value().

27  {
28  try {
29  using namespace kaldi;
30  using namespace kaldi::nnet2;
31  typedef kaldi::int32 int32;
32  typedef kaldi::int64 int64;
33 
34  const char *usage =
35  "Given an old and a new model and some training examples (possibly held-out),\n"
36  "show the average objective function given the mean of the two models,\n"
37  "and the breakdown by component of why this happened (computed from\n"
38  "derivative information). Also shows parameter differences per layer.\n"
39  "If training examples not provided, only shows parameter differences per\n"
40  "layer.\n"
41  "\n"
42  "Usage: nnet-show-progress [options] <old-model-in> <new-model-in> [<training-examples-in>]\n"
43  "e.g.: nnet-show-progress 1.nnet 2.nnet ark:valid.egs\n";
44 
45  ParseOptions po(usage);
46 
47  int32 num_segments = 1;
48  int32 batch_size = 1024;
49  std::string use_gpu = "optional";
50 
51  po.Register("num-segments", &num_segments,
52  "Number of line segments used for computing derivatives");
53  po.Register("use-gpu", &use_gpu,
54  "yes|no|optional|wait, only has effect if compiled with CUDA");
55 
56  po.Read(argc, argv);
57 
58  if (po.NumArgs() < 2 || po.NumArgs() > 3) {
59  po.PrintUsage();
60  exit(1);
61  }
62 
63 #if HAVE_CUDA==1
64  CuDevice::Instantiate().SelectGpuId(use_gpu);
65 #endif
66 
67  std::string nnet1_rxfilename = po.GetArg(1),
68  nnet2_rxfilename = po.GetArg(2),
69  examples_rspecifier = po.GetOptArg(3);
70 
71  TransitionModel trans_model;
72  AmNnet am_nnet1, am_nnet2;
73  {
74  bool binary_read;
75  Input ki(nnet1_rxfilename, &binary_read);
76  trans_model.Read(ki.Stream(), binary_read);
77  am_nnet1.Read(ki.Stream(), binary_read);
78  }
79  {
80  bool binary_read;
81  Input ki(nnet2_rxfilename, &binary_read);
82  trans_model.Read(ki.Stream(), binary_read);
83  am_nnet2.Read(ki.Stream(), binary_read);
84  }
85 
86  if (am_nnet1.GetNnet().GetParameterDim() !=
87  am_nnet2.GetNnet().GetParameterDim()) {
88  KALDI_WARN << "Parameter-dim mismatch, cannot show progress.";
89  exit(0);
90  }
91 
92  int32 ret = 0;
93 
94  if (!examples_rspecifier.empty()) {
95  Nnet nnet_gradient(am_nnet2.GetNnet());
96  const bool treat_as_gradient = true;
97  nnet_gradient.SetZero(treat_as_gradient);
98 
99  std::vector<NnetExample> examples;
100  SequentialNnetExampleReader example_reader(examples_rspecifier);
101  for (; !example_reader.Done(); example_reader.Next())
102  examples.push_back(example_reader.Value());
103 
104  int32 num_examples = examples.size();
105 
106  int32 num_updatable = am_nnet1.GetNnet().NumUpdatableComponents();
107  Vector<BaseFloat> diff(num_updatable);
108 
109  for (int32 s = 0; s < num_segments; s++) {
110  // start and end segments of the line between 0 and 1
111  BaseFloat start = (s + 0.0) / num_segments,
112  end = (s + 1.0) / num_segments, middle = 0.5 * (start + end);
113  Nnet interp_nnet(am_nnet2.GetNnet());
114  interp_nnet.Scale(middle);
115  interp_nnet.AddNnet(1.0 - middle, am_nnet1.GetNnet());
116 
117  Nnet nnet_gradient(am_nnet2.GetNnet());
118  const bool treat_as_gradient = true;
119  nnet_gradient.SetZero(treat_as_gradient);
120 
121  double objf_per_frame = ComputeNnetGradient(interp_nnet, examples,
122  batch_size, &nnet_gradient);
123  KALDI_LOG << "At position " << middle << ", objf per frame is " << objf_per_frame;
124 
125  Vector<BaseFloat> old_dotprod(num_updatable), new_dotprod(num_updatable);
126  nnet_gradient.ComponentDotProducts(am_nnet1.GetNnet(), &old_dotprod);
127  nnet_gradient.ComponentDotProducts(am_nnet2.GetNnet(), &new_dotprod);
128  old_dotprod.Scale(1.0 / num_examples);
129  new_dotprod.Scale(1.0 / num_examples);
130  diff.AddVec(1.0/ num_segments, new_dotprod);
131  diff.AddVec(-1.0 / num_segments, old_dotprod);
132  KALDI_VLOG(1) << "By segment " << s << ", objf change is " << diff;
133  }
134  KALDI_LOG << "Total objf change per component is " << diff;
135  if (num_examples == 0) ret = 1;
136  }
137 
138  { // Get info about magnitude of parameter change.
139  Nnet diff_nnet(am_nnet1.GetNnet());
140  diff_nnet.AddNnet(-1.0, am_nnet2.GetNnet());
141  int32 num_updatable = diff_nnet.NumUpdatableComponents();
142  Vector<BaseFloat> dot_prod(num_updatable);
143  diff_nnet.ComponentDotProducts(diff_nnet, &dot_prod);
144  dot_prod.ApplyPow(0.5); // take sqrt to get l2 norm of diff
145  KALDI_LOG << "Parameter differences per layer are "
146  << dot_prod;
147 
148  Vector<BaseFloat> baseline_prod(num_updatable);
149  am_nnet1.GetNnet().ComponentDotProducts(am_nnet1.GetNnet(),
150  &baseline_prod);
151  baseline_prod.ApplyPow(0.5);
152  dot_prod.DivElements(baseline_prod);
153  KALDI_LOG << "Relative parameter differences per layer are "
154  << dot_prod;
155  }
156 
157  return ret;
158  } catch(const std::exception &e) {
159  std::cerr << e.what() << '\n';
160  return -1;
161  }
162 }
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
void AddNnet(const VectorBase< BaseFloat > &scales, const Nnet &other)
For each updatatable component, adds to it the corresponding element of "other" times the appropriate...
Definition: nnet-nnet.cc:576
int32 NumUpdatableComponents() const
Returns the number of updatable components.
Definition: nnet-nnet.cc:413
double ComputeNnetGradient(const Nnet &nnet, const std::vector< NnetExample > &validation_set, int32 batch_size, Nnet *gradient)
ComputeNnetGradient is mostly used to compute gradients on validation sets; it divides the example in...
Definition: nnet-update.cc:302
void ComponentDotProducts(const Nnet &other, VectorBase< BaseFloat > *dot_prod) const
Definition: nnet-nnet.cc:207
void Read(std::istream &is, bool binary)
Definition: am-nnet.cc:39
kaldi::int32 int32
virtual int32 GetParameterDim() const
Definition: nnet-nnet.cc:657
void Scale(BaseFloat scale)
Scales all the Components with the same scale.
Definition: nnet-nnet.cc:436
float BaseFloat
Definition: kaldi-types.h:29
void SetZero(bool treat_as_gradient)
Definition: nnet-nnet.cc:151
The class ParseOptions is for parsing command-line options; see Parsing command-line options for more...
Definition: parse-options.h:36
void Read(std::istream &is, bool binary)
A templated class for reading objects sequentially from an archive or script file; see The Table conc...
Definition: kaldi-table.h:287
#define KALDI_WARN
Definition: kaldi-error.h:150
A class representing a vector.
Definition: kaldi-vector.h:406
#define KALDI_VLOG(v)
Definition: kaldi-error.h:156
#define KALDI_LOG
Definition: kaldi-error.h:153
const Nnet & GetNnet() const
Definition: am-nnet.h:61