35 *min_t = indexes[0].t;
37 for (
int32 n = 1; n < static_cast<int32>(indexes.size());
n++) {
38 *min_t = std::min(*min_t, indexes[
n].t);
39 *max_t = std::max(*max_t, indexes[
n].t);
50 const std::vector<Index> &input_indexes = request.
inputs[0].indexes;
53 int32 orig_min_t = min_t, orig_max_t = max_t;
54 int t_length = max_t + 1 - min_t;
60 min_t += std::min(4,
RandInt(0, t_length - 1));
62 t_length = max_t + 1 - min_t;
66 max_t -= std::min(4,
RandInt(0, t_length - 1));
68 t_length = max_t + 1 - min_t;
74 min_t = orig_min_t - 10;
78 int32 output_min_t, output_max_t;
81 &output_min_t, &output_max_t);
83 KALDI_LOG <<
"ComputationRequest has output (min,max) = (" << output_min_t
84 <<
',' << output_max_t <<
"), input (min,max) = (" << orig_min_t
85 <<
',' << orig_max_t <<
"), limiting deriv times to (" 99 bool limit_deriv_times = (
RandInt(0, 2) == 0);
101 std::vector<std::string> configs;
104 for (
size_t j = 0;
j < configs.size();
j++) {
105 KALDI_LOG <<
"Input config[" <<
j <<
"] is: " << configs[
j];
106 std::istringstream is(configs[
j]);
111 std::vector<Matrix<BaseFloat> > inputs;
117 request.
outputs[0].has_deriv =
true;
123 if (limit_deriv_times) {
133 std::ostringstream os;
134 computation.
Print(os, nnet);
135 KALDI_LOG <<
"Optimized computation is: " << os.str();
138 Nnet nnet_deriv(nnet);
143 int32 num_directions = 4;
148 std::vector<BaseFloat> measured_objf(num_directions + 1, 0.0),
149 predicted_objf_change(num_directions + 1, 0.0);
164 compute_opts.
debug =
true;
169 for (
int32 pass = 0; pass <= num_directions; pass++) {
170 Nnet nnet_copy(nnet);
177 (pass == 0 ? &nnet_deriv : &nnet_copy));
181 for (
size_t i = 0;
i < request.
inputs.size();
i++) {
186 KALDI_LOG <<
"Running forward computation";
190 KALDI_LOG <<
"Output sum for pass " << pass <<
" is " << output.Sum();
192 measured_objf[pass] = objf;
198 KALDI_LOG <<
"Running backward computation";
204 predicted_objf_change[pass] =
DotProduct(nnet_copy, nnet_deriv) -
210 measured_objf_change_vec(num_directions);
211 for (
int32 d = 0;
d < num_directions;
d++) {
212 BaseFloat predicted_change = predicted_objf_change[
d+1],
213 measured_change = measured_objf[
d+1] - measured_objf[0];
214 predicted_objf_change_vec(
d) = predicted_change;
215 measured_objf_change_vec(
d) = measured_change;
217 KALDI_LOG <<
"Vector of predicted objf-change is: " 218 << predicted_objf_change_vec;
219 KALDI_LOG <<
"Vector of measured objf-change is: " 220 << measured_objf_change_vec;
221 BaseFloat delta_thresh_warn = 0.05, delta_thresh_fail = 0.25;
222 if (limit_deriv_times) {
223 KALDI_LOG <<
"Not checking that predicted/measured changes matched " 224 <<
"because we limited times of derivatives.";
227 measured_objf_change_vec, delta_thresh_fail)) {
229 KALDI_WARN <<
"Predicted and measured objf-changes differ too much. " 230 <<
"(would normally be beyond error threshold, but this " 231 <<
"nnet is recurrent, so letting it pass.";
233 KALDI_ERR <<
"Predicted and measured objf-changes differ too much.";
237 measured_objf_change_vec, delta_thresh_warn)) {
238 KALDI_WARN <<
"Predicted and measured objf-changes differ quite a lot.";
253 bool allow_optimization =
true;
255 std::vector<std::string> configs;
258 for (
size_t j = 0;
j < configs.size();
j++) {
259 KALDI_LOG <<
"Input config[" <<
j <<
"] is: " << configs[
j];
260 std::istringstream is(configs[
j]);
265 std::vector<Matrix<BaseFloat> > inputs;
272 request.
inputs[
i].has_deriv =
true;
273 request.
outputs[0].has_deriv =
true;
279 compiler.CreateComputation(opts, &computation);
281 std::ostringstream os;
282 computation.Print(os, nnet);
283 KALDI_LOG <<
"Generated computation is: " << os.str();
291 if (
RandInt(0, 3) != 0 && allow_optimization) {
297 std::ostringstream os;
298 computation.Print(os, nnet);
299 KALDI_LOG <<
"Optimized computation is: " << os.str();
304 compute_opts.
debug =
true;
305 computation.ComputeCudaIndexes();
308 int32 num_directions = 3;
314 std::vector<BaseFloat> measured_objf(num_directions + 2, 0.0),
315 predicted_objf_change(num_directions + 2, 0.0);
327 std::vector<CuMatrix<BaseFloat> > delta_inputs(inputs.size());
328 std::vector<CuMatrix<BaseFloat> > input_derivs(inputs.size());
334 for (
int32 pass = 0; pass <= num_directions + 1; pass++) {
345 for (
size_t i = 0;
i < request.
inputs.size();
i++) {
348 if (pass > 0 && pass <= num_directions) {
349 delta_inputs[
i].Resize(inputs[i].NumRows(), inputs[i].NumCols());
350 delta_inputs[
i].SetRandn();
351 delta_inputs[
i].Scale(delta);
355 if (i == 0 && request.
inputs.size() > 1 &&
RandInt(0, 1) == 0)
356 delta_inputs[i].SetZero();
357 temp.
AddMat(1.0, delta_inputs[i]);
358 predicted_objf_change[pass] +=
TraceMatMat(input_derivs[i],
364 KALDI_LOG <<
"Running forward computation";
368 KALDI_LOG <<
"Output sum for pass " << pass <<
" is " << output.Sum();
370 measured_objf[pass] = objf;
376 KALDI_LOG <<
"Running backward computation";
378 for (
size_t i = 0;
i < request.
inputs.size();
i++) {
381 <<
"' is " << input_derivs[
i].FrobeniusNorm();
386 measured_objf[num_directions + 1]));
389 measured_objf_change_vec(num_directions);
390 for (
int32 d = 0;
d < num_directions;
d++) {
391 BaseFloat predicted_change = predicted_objf_change[
d+1],
392 measured_change = measured_objf[
d+1] - measured_objf[0];
393 predicted_objf_change_vec(
d) = predicted_change;
394 measured_objf_change_vec(
d) = measured_change;
396 KALDI_LOG <<
"Vector of predicted objf-change is: " 397 << predicted_objf_change_vec;
398 KALDI_LOG <<
"Vector of measured objf-change is: " 399 << measured_objf_change_vec;
400 BaseFloat delta_thresh_warn = 0.05, delta_thresh_fail = 0.25;
402 measured_objf_change_vec, delta_thresh_fail)) {
404 KALDI_WARN <<
"Predicted and measured objf-changes differ too much. " 405 <<
"(would normally be beyond error threshold, but this " 406 <<
"nnet is recurrent, so letting it pass.";
408 KALDI_ERR <<
"Predicted and measured objf-changes differ too much.";
411 measured_objf_change_vec, delta_thresh_warn)) {
412 KALDI_WARN <<
"Predicted and measured objf-changes differ quite a lot";
422 using namespace kaldi;
427 for (loop = 0; loop < 2; loop++) {
428 CuDevice::Instantiate().SetDebugStrideMode(
true);
430 CuDevice::Instantiate().SelectGpuId(
"no");
432 CuDevice::Instantiate().SelectGpuId(
"yes");
438 CuDevice::Instantiate().PrintProfile();
440 KALDI_LOG <<
"Nnet derivative tests succeeded.";
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
void ScaleNnet(BaseFloat scale, Nnet *nnet)
Scales the nnet parameters and stats by this scale.
void ReadConfig(std::istream &config_file)
bool need_model_derivative
if need_model_derivative is true, then we'll be doing either model training or model-derivative compu...
This class enables you to do the compilation and optimization in one call, and also ensures that if t...
This file contains various routines that are useful in test code.
void Print(std::ostream &os, const Nnet &nnet) const
This file contains utilities for analyzing and checking computations, which are used in the optimizat...
void AddMat(Real alpha, const CuMatrixBase< Real > &A, MatrixTransposeType trans=kNoTrans)
*this += alpha * A
std::vector< IoSpecification > inputs
This class represents a matrix that's stored on the GPU if we have one, and in memory if not...
void UnitTestNnetModelDerivatives()
void SetDerivTimesOptions(const ComputationRequest &request, NnetOptimizeOptions *opt_config)
int32 OutputDim(const std::string &output_name) const
void SetNnetAsGradient(Nnet *nnet)
Sets nnet as gradient by Setting is_gradient_ to true and learning_rate_ to 1 for each UpdatableCompo...
void SetVerboseLevel(int32 i)
This should be rarely used, except by programs using Kaldi as library; command-line programs set the ...
void AcceptInput(const std::string &node_name, CuMatrix< BaseFloat > *input)
e.g.
void ComputeExampleComputationRequestSimple(const Nnet &nnet, ComputationRequest *request, std::vector< Matrix< BaseFloat > > *inputs)
This function computes an example computation request, for testing purposes.
const CuMatrixBase< BaseFloat > & GetOutput(const std::string &node_name)
int32 MaxOutputTimeInRequest(const ComputationRequest &request)
Real TraceMatMat(const MatrixBase< Real > &A, const MatrixBase< Real > &B, MatrixTransposeType trans)
We need to declare this here as it will be a friend function.
BaseFloat DotProduct(const Nnet &nnet1, const Nnet &nnet2)
Returns dot product between two networks of the same structure (calls the DotProduct functions of the...
void UnitTestNnetInputDerivatives()
void Optimize(const NnetOptimizeOptions &config, const Nnet &nnet, int32 max_output_time_in_request, NnetComputation *computation)
This is the top-level function for optimizing a computation.
void ComputeMinAndMaxTimes(const std::vector< Index > &indexes, int32 *min_t, int32 *max_t)
std::shared_ptr< const NnetComputation > Compile(const ComputationRequest &request)
Does the compilation and returns a const pointer to the result, which is owned by this class...
Matrix for CUDA computing.
A class representing a vector.
class NnetComputer is responsible for executing the computation described in the "computation" object...
#define KALDI_ASSERT(cond)
std::vector< IoSpecification > outputs
This class creates an initial version of the NnetComputation, without any optimization or sharing of ...
void PerturbParams(BaseFloat stddev, Nnet *nnet)
Calls PerturbParams (with the given stddev) on all updatable components of the nnet.
bool NnetIsRecurrent(const Nnet &nnet)
Returns true if 'nnet' has some kind of recurrency.
void GenerateConfigSequence(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
Generates a sequence of at least one config files, output as strings, where the first in the sequence...
static bool ApproxEqual(float a, float b, float relative_tolerance=0.001)
return abs(a - b) <= relative_tolerance * (abs(a)+abs(b)).
void Resize(MatrixIndexT rows, MatrixIndexT cols, MatrixResizeType resize_type=kSetZero, MatrixStrideType stride_type=kDefaultStride)
Allocate the memory.
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
void Run()
This does either the forward or backward computation, depending when it is called (in a typical compu...