All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MultiTaskLoss Class Reference

#include <nnet-loss.h>

Inheritance diagram for MultiTaskLoss:
Collaboration diagram for MultiTaskLoss:

Public Member Functions

 MultiTaskLoss ()
 
 ~MultiTaskLoss ()
 
void InitFromString (const std::string &s)
 Initialize from string, the format for string 's' is : 'multitask,<type1>,<dim1>,<weight1>,...,<typeN>,<dimN>,<weightN>'. More...
 
void Eval (const VectorBase< BaseFloat > &frame_weights, const CuMatrixBase< BaseFloat > &net_out, const CuMatrixBase< BaseFloat > &target, CuMatrix< BaseFloat > *diff)
 Evaluate mean square error using target-matrix,. More...
 
void Eval (const VectorBase< BaseFloat > &frame_weights, const CuMatrixBase< BaseFloat > &net_out, const Posterior &target, CuMatrix< BaseFloat > *diff)
 Evaluate mean square error using target-posteior,. More...
 
std::string Report ()
 Generate string with error report. More...
 
BaseFloat AvgLoss ()
 Get loss value (frame average),. More...
 
- Public Member Functions inherited from LossItf
 LossItf ()
 
virtual ~LossItf ()
 

Private Attributes

std::vector< LossItf * > loss_vec_
 
std::vector< int32 > loss_dim_
 
std::vector< BaseFloatloss_weights_
 
std::vector< int32 > loss_dim_offset_
 
CuMatrix< BaseFloattgt_mat_
 

Detailed Description

Definition at line 173 of file nnet-loss.h.

Constructor & Destructor Documentation

MultiTaskLoss ( )
inline

Definition at line 175 of file nnet-loss.h.

176  { }
~MultiTaskLoss ( )
inline

Definition at line 178 of file nnet-loss.h.

References MultiTaskLoss::loss_vec_.

178  {
179  while (loss_vec_.size() > 0) {
180  delete loss_vec_.back();
181  loss_vec_.pop_back();
182  }
183  }
std::vector< LossItf * > loss_vec_
Definition: nnet-loss.h:213

Member Function Documentation

BaseFloat AvgLoss ( )
virtual

Get loss value (frame average),.

Implements LossItf.

Definition at line 435 of file nnet-loss.cc.

References rnnlm::i, KALDI_ISFINITE, KALDI_WARN, MultiTaskLoss::loss_vec_, and MultiTaskLoss::loss_weights_.

Referenced by MultiTaskLoss::Report().

435  {
436  BaseFloat ans(0.0);
437  for (int32 i = 0; i < loss_vec_.size(); i++) {
438  BaseFloat val = loss_weights_[i] * loss_vec_[i]->AvgLoss();
439  if (!KALDI_ISFINITE(val)) {
440  KALDI_WARN << "Loss " << i+1 << ", has bad objective function value '"
441  << val << "', using 0.0 instead.";
442  val = 0.0;
443  }
444  ans += val;
445  }
446  return ans;
447 }
#define KALDI_ISFINITE(x)
Definition: kaldi-math.h:74
std::vector< BaseFloat > loss_weights_
Definition: nnet-loss.h:215
float BaseFloat
Definition: kaldi-types.h:29
#define KALDI_WARN
Definition: kaldi-error.h:130
std::vector< LossItf * > loss_vec_
Definition: nnet-loss.h:213
void Eval ( const VectorBase< BaseFloat > &  frame_weights,
const CuMatrixBase< BaseFloat > &  net_out,
const CuMatrixBase< BaseFloat > &  target,
CuMatrix< BaseFloat > *  diff 
)
inlinevirtual

Evaluate mean square error using target-matrix,.

Implements LossItf.

Definition at line 193 of file nnet-loss.h.

References KALDI_ERR.

Referenced by main().

196  {
197  KALDI_ERR << "This is not supposed to be called!";
198  }
#define KALDI_ERR
Definition: kaldi-error.h:127
void Eval ( const VectorBase< BaseFloat > &  frame_weights,
const CuMatrixBase< BaseFloat > &  net_out,
const Posterior target,
CuMatrix< BaseFloat > *  diff 
)
virtual

Evaluate mean square error using target-posteior,.

One vector of frame_weights per loss-function, The original frame weights are multiplied with a mask of `defined targets' according to the 'Posterior'.

Implements LossItf.

Definition at line 355 of file nnet-loss.cc.

References CuMatrixBase< Real >::ColRange(), KALDI_ASSERT, MultiTaskLoss::loss_dim_, MultiTaskLoss::loss_dim_offset_, MultiTaskLoss::loss_vec_, MultiTaskLoss::loss_weights_, CuMatrixBase< Real >::NumCols(), CuMatrixBase< Real >::NumRows(), kaldi::nnet1::PosteriorToMatrix(), CuMatrix< Real >::Resize(), CuMatrixBase< Real >::Scale(), and MultiTaskLoss::tgt_mat_.

358  {
359  int32 num_frames = net_out.NumRows(),
360  num_output = net_out.NumCols();
361  KALDI_ASSERT(num_frames == post.size());
362  KALDI_ASSERT(num_output == loss_dim_offset_.back()); // sum of loss-dims,
363 
364  // convert posterior to matrix,
365  PosteriorToMatrix(post, num_output, &tgt_mat_);
366 
367  // allocate diff matrix,
368  diff->Resize(num_frames, num_output);
369 
373  std::vector<Vector<BaseFloat> > frmwei_have_tgt;
374  for (int32 l = 0; l < loss_vec_.size(); l++) {
375  // copy original weights,
376  frmwei_have_tgt.push_back(Vector<BaseFloat>(frame_weights));
377  // We need to mask-out the frames for which the 'posterior' is not defined (= is empty):
378  int32 loss_beg = loss_dim_offset_[l]; // first column of loss target,
379  int32 loss_end = loss_dim_offset_[l+1]; // (last+1) column of loss target,
380  for (int32 f = 0; f < num_frames; f++) {
381  bool tgt_defined = false;
382  for (int32 p = 0; p < post[f].size(); p++) {
383  if (post[f][p].first >= loss_beg && post[f][p].first < loss_end) {
384  tgt_defined = true;
385  break;
386  }
387  }
388  if (!tgt_defined) {
389  frmwei_have_tgt[l](f) = 0.0; // set zero_weight for the frame with no targets!
390  }
391  }
392  }
393 
394  // call the vector of loss functions,
395  CuMatrix<BaseFloat> diff_aux;
396  for (int32 l = 0; l < loss_vec_.size(); l++) {
397  loss_vec_[l]->Eval(frmwei_have_tgt[l],
398  net_out.ColRange(loss_dim_offset_[l], loss_dim_[l]),
400  &diff_aux);
401  // Scale the gradients,
402  diff_aux.Scale(loss_weights_[l]);
403  // Copy to diff,
404  diff->ColRange(loss_dim_offset_[l], loss_dim_[l]).CopyFromMat(diff_aux);
405  }
406 }
MatrixIndexT NumCols() const
Definition: cu-matrix.h:196
void PosteriorToMatrix(const Posterior &post, const int32 post_dim, CuMatrix< Real > *mat)
Wrapper of PosteriorToMatrix with CuMatrix argument.
Definition: nnet-utils.h:292
std::vector< BaseFloat > loss_weights_
Definition: nnet-loss.h:215
CuMatrix< BaseFloat > tgt_mat_
Definition: nnet-loss.h:219
CuSubMatrix< Real > ColRange(const MatrixIndexT col_offset, const MatrixIndexT num_cols) const
Definition: cu-matrix.h:544
std::vector< int32 > loss_dim_offset_
Definition: nnet-loss.h:217
void Resize(MatrixIndexT rows, MatrixIndexT cols, MatrixResizeType resize_type=kSetZero, MatrixStrideType stride_type=kDefaultStride)
Allocate the memory.
Definition: cu-matrix.cc:47
MatrixIndexT NumRows() const
Dimensions.
Definition: cu-matrix.h:195
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
std::vector< int32 > loss_dim_
Definition: nnet-loss.h:214
std::vector< LossItf * > loss_vec_
Definition: nnet-loss.h:213
void InitFromString ( const std::string &  s)

Initialize from string, the format for string 's' is : 'multitask,<type1>,<dim1>,<weight1>,...,<typeN>,<dimN>,<weightN>'.

Practically it can look like this : 'multitask,xent,2456,1.0,mse,440,0.001'

Definition at line 308 of file nnet-loss.cc.

References kaldi::ConvertStringToInteger(), kaldi::ConvertStringToReal(), rnnlm::i, KALDI_ASSERT, KALDI_ERR, MultiTaskLoss::loss_dim_, MultiTaskLoss::loss_dim_offset_, MultiTaskLoss::loss_vec_, MultiTaskLoss::loss_weights_, and kaldi::SplitStringToVector().

Referenced by main().

308  {
309  std::vector<std::string> v;
310  SplitStringToVector(s, ",:" /* delimiter */, false, &v);
311 
312  KALDI_ASSERT((v.size()-1) % 3 == 0); // triplets,
313  KALDI_ASSERT(v[0] == "multitask"); // header,
314 
315  // parse the definition of multitask loss,
316  std::vector<std::string>::iterator it(v.begin()+1); // skip header,
317  for ( ; it != v.end(); ++it) {
318  // type,
319  if (*it == "xent") {
320  loss_vec_.push_back(new Xent());
321  } else if (*it == "mse") {
322  loss_vec_.push_back(new Mse());
323  } else {
324  KALDI_ERR << "Unknown objective function code : " << *it;
325  }
326  ++it;
327  // dim,
328  int32 dim;
329  if (!ConvertStringToInteger(*it, &dim)) {
330  KALDI_ERR << "Cannot convert 'dim' " << *it << " to integer!";
331  }
332  loss_dim_.push_back(dim);
333  ++it;
334  // weight,
335  BaseFloat weight;
336  if (!ConvertStringToReal(*it, &weight)) {
337  KALDI_ERR << "Cannot convert 'weight' " << *it << " to integer!";
338  }
339  KALDI_ASSERT(weight >= 0.0);
340  loss_weights_.push_back(weight);
341  }
342 
343  // build vector with starting-point offsets,
344  loss_dim_offset_.resize(loss_dim_.size()+1, 0); // 1st zero stays,
345  for (int32 i = 1; i <= loss_dim_.size(); i++) {
347  }
348 
349  // sanity check,
350  KALDI_ASSERT(loss_vec_.size() > 0);
351  KALDI_ASSERT(loss_vec_.size() == loss_dim_.size());
352  KALDI_ASSERT(loss_vec_.size() == loss_weights_.size());
353 }
bool ConvertStringToInteger(const std::string &str, Int *out)
Converts a string into an integer via strtoll and returns false if there was any kind of problem (i...
Definition: text-utils.h:118
std::vector< BaseFloat > loss_weights_
Definition: nnet-loss.h:215
float BaseFloat
Definition: kaldi-types.h:29
std::vector< int32 > loss_dim_offset_
Definition: nnet-loss.h:217
void SplitStringToVector(const std::string &full, const char *delim, bool omit_empty_strings, std::vector< std::string > *out)
Split a string using any of the single character delimiters.
Definition: text-utils.cc:63
#define KALDI_ERR
Definition: kaldi-error.h:127
bool ConvertStringToReal(const std::string &str, T *out)
ConvertStringToReal converts a string into either float or double and returns false if there was any ...
Definition: text-utils.cc:238
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
std::vector< int32 > loss_dim_
Definition: nnet-loss.h:214
std::vector< LossItf * > loss_vec_
Definition: nnet-loss.h:213
std::string Report ( )
virtual

Generate string with error report.

Implements LossItf.

Definition at line 408 of file nnet-loss.cc.

References MultiTaskLoss::AvgLoss(), rnnlm::i, MultiTaskLoss::loss_vec_, and MultiTaskLoss::loss_weights_.

Referenced by main().

408  {
409  // calculate overall loss (weighted),
410  BaseFloat overall_loss = AvgLoss();
411  // copy the loss-values into a vector,
412  std::vector<BaseFloat> loss_values;
413  for (int32 i = 0; i < loss_vec_.size(); i++) {
414  loss_values.push_back(loss_vec_[i]->AvgLoss());
415  }
416 
417  // build the message,
418  std::ostringstream oss;
419  oss << "MultiTaskLoss, with " << loss_vec_.size()
420  << " parallel loss functions." << std::endl;
421  // individual loss reports first,
422  for (int32 i = 0; i < loss_vec_.size(); i++) {
423  oss << "Loss " << i+1 << ", " << loss_vec_[i]->Report() << std::endl;
424  }
425 
426  // overall loss is last,
427  oss << "Loss (OVERALL), "
428  << "AvgLoss: " << overall_loss << " (MultiTaskLoss), "
429  << "weights " << loss_weights_ << ", "
430  << "values " << loss_values << std::endl;
431 
432  return oss.str();
433 }
BaseFloat AvgLoss()
Get loss value (frame average),.
Definition: nnet-loss.cc:435
std::vector< BaseFloat > loss_weights_
Definition: nnet-loss.h:215
float BaseFloat
Definition: kaldi-types.h:29
std::vector< LossItf * > loss_vec_
Definition: nnet-loss.h:213

Member Data Documentation

std::vector<int32> loss_dim_
private

Definition at line 214 of file nnet-loss.h.

Referenced by MultiTaskLoss::Eval(), and MultiTaskLoss::InitFromString().

std::vector<int32> loss_dim_offset_
private

Definition at line 217 of file nnet-loss.h.

Referenced by MultiTaskLoss::Eval(), and MultiTaskLoss::InitFromString().

std::vector<BaseFloat> loss_weights_
private
CuMatrix<BaseFloat> tgt_mat_
private

Definition at line 219 of file nnet-loss.h.

Referenced by MultiTaskLoss::Eval().


The documentation for this class was generated from the following files: