All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
kaldi::nnet3 Namespace Reference

Namespaces

 computation_graph
 
 compute_computation_steps
 

Classes

struct  Access
 
class  AffineComponent
 
class  AmNnetSimple
 
struct  Analyzer
 This struct exists to set up various pieces of analysis; it helps avoid the repetition of code where we compute all these things in sequence. More...
 
class  BackpropTruncationComponent
 
class  BackpropTruncationComponentPrecomputedIndexes
 
class  BinarySumDescriptor
 BinarySumDescriptor can represent either A + B, or (A if defined, else B). More...
 
class  BlockAffineComponent
 This class implements an affine transform using a block diagonal matrix e.g., one whose weight matrix is all zeros except for blocks on the diagonal. More...
 
class  CachingOptimizingCompiler
 This class enables you to do the compilation and optimization in one call, and also ensures that if the ComputationRequest is identical to the previous one, the compilation process is not repeated. More...
 
struct  ChainObjectiveInfo
 
struct  CheckComputationOptions
 
struct  CindexHasher
 
class  CindexSet
 
class  ClipGradientComponent
 
struct  CommandAttributes
 
struct  ComparePair
 
class  Compiler
 This class creates an initial version of the NnetComputation, without any optimization or sharing of matrices. More...
 
struct  CompilerOptions
 
class  Component
 Abstract base-class for neural-net components. More...
 
class  ComponentPrecomputedIndexes
 
class  CompositeComponent
 CompositeComponent is a component representing a sequence of [simple] components. More...
 
class  ComputationAnalysis
 This class performs various kinds of specific analysis on top of what class Analyzer gives you immediately. More...
 
class  ComputationChecker
 
struct  ComputationGraph
 The first step in compilation is to turn the ComputationSpecification into a ComputationGraph, where for each Cindex we have a list of other Cindexes that it depends on. More...
 
class  ComputationGraphBuilder
 An abstract representation of a set of Cindexes. More...
 
class  ComputationRenumberer
 
struct  ComputationRequest
 
struct  ComputationRequestHasher
 
struct  ComputationRequestPtrEqual
 
class  ComputationVariables
 This class relates the matrices and sub-matrices in the computation to imaginary "variables", such that we can think of the operations as operating on sets of individual variables, and we can then do analysis that lets us do optimization. More...
 
class  ConfigLine
 This class is responsible for parsing input like hi-there xx=yyy a=b c empty= f-oo=Append(bar, sss) ba_z=123 bing='a b c' baz="a b c d='a b' e" and giving you access to the fields, in this case. More...
 
class  ConstantFunctionComponent
 
class  ConvolutionComponent
 ConvolutionalComponent implements 2d-convolution. More...
 
class  DecodableAmNnetSimple
 
class  DecodableAmNnetSimpleParallel
 
struct  DecodableNnet3OnlineOptions
 
class  DecodableNnet3SimpleOnline
 This Decodable object for class nnet3::AmNnetSimple takes feature input from class OnlineFeatureInterface, unlike, say, class DecodableAmNnet which takes feature input from a matrix. More...
 
class  DecodableNnetSimple
 
class  DerivativeTimeLimiter
 
class  Descriptor
 
struct  DiscriminativeObjectiveFunctionInfo
 
class  DistributeComponent
 This Component takes a larger input-dim than output-dim, where the input-dim must be a multiple of the output-dim, and distributes different blocks of the input dimension to different 'x' values. More...
 
class  DistributeComponentPrecomputedIndexes
 
class  DropoutComponent
 
class  ElementwiseProductComponent
 
struct  FirstElementComparator
 
struct  FirstElementIsEqualComparator
 
class  FixedAffineComponent
 FixedAffineComponent is an affine transform that is supplied at network initialization time and is not trainable. More...
 
class  FixedBiasComponent
 FixedBiasComponent applies a fixed per-element bias; it's similar to the AddShift component in the nnet1 setup (and only needed for nnet1 model conversion. More...
 
class  FixedScaleComponent
 FixedScaleComponent applies a fixed per-element scale; it's similar to the Rescale component in the nnet1 setup (and only needed for nnet1 model conversion). More...
 
class  ForwardingDescriptor
 
struct  GeneralDescriptor
 This class is only used when parsing Descriptors. More...
 
struct  Index
 struct Index is intended to represent the various indexes by which we number the rows of the matrices that the Components process: mainly 'n', the index of the member of the minibatch, 't', used for the frame index in speech recognition, and 'x', which is a catch-all extra index which we might use in convolutional setups or for other reasons. More...
 
struct  IndexHasher
 
struct  IndexLessNxt
 
class  IndexSet
 An abstract representation of a set of Indexes. More...
 
struct  IoSpecification
 
class  LogSoftmaxComponent
 
class  LstmNonlinearityComponent
 
struct  MatrixAccesses
 
class  MaxpoolingComponent
 
struct  MiscComputationInfo
 
class  ModelUpdateConsolidator
 This class is responsible for consolidating the model-update part of backprop commands, for components in (e.g.) recurrent networks that need to have many separate backprop commands, into more efficient single commands operating on consolidated data in larger matrices. More...
 
class  NaturalGradientAffineComponent
 Keywords: natural gradient descent, NG-SGD, naturalgradient. More...
 
class  NaturalGradientPerElementScaleComponent
 
class  NaturalGradientRepeatedAffineComponent
 
struct  NetworkNode
 NetworkNode is used to represent, three types of thing: either an input of the network (which pretty much just states the dimension of the input vector); a Component (e.g. More...
 
class  Nnet
 
class  NnetChainCombiner
 
class  NnetChainComputeProb
 This class is for computing objective-function values in a nnet3+chain setup, for diagnostics. More...
 
struct  NnetChainExample
 NnetChainExample is like NnetExample, but specialized for CTC training. More...
 
struct  NnetChainSupervision
 
class  NnetChainTrainer
 This class is for single-threaded training of neural nets using the 'chain' model. More...
 
struct  NnetChainTrainingOptions
 
struct  NnetCombineConfig
 Configuration class that controls neural net combination, where we combine a number of neural nets. More...
 
class  NnetCombiner
 
struct  NnetComputation
 
struct  NnetComputeOptions
 
class  NnetComputeProb
 This class is for computing cross-entropy and accuracy values in a neural network, for diagnostics. More...
 
struct  NnetComputeProbOptions
 
class  NnetComputer
 class NnetComputer is responsible for executing the computation described in the "computation" object. More...
 
class  NnetComputerFromEg
 
class  NnetDiscriminativeComputeObjf
 This class is for computing objective-function values in a nnet3 discriminative training, for diagnostics. More...
 
struct  NnetDiscriminativeExample
 NnetDiscriminativeExample is like NnetExample, but specialized for sequence training. More...
 
struct  NnetDiscriminativeOptions
 
struct  NnetDiscriminativeSupervision
 
class  NnetDiscriminativeTrainer
 This class is for single-threaded discriminative training of neural nets. More...
 
struct  NnetExample
 NnetExample is the input data and corresponding label (or labels) for one or more frames of input, used for standard cross-entropy training of neural nets (and possibly for other objective functions). More...
 
struct  NnetGenerationOptions
 
struct  NnetIo
 
class  NnetLdaStatsAccumulator
 
struct  NnetOptimizeOptions
 
struct  NnetSimpleComputationOptions
 
class  NnetTrainer
 This class is for single-threaded training of neural nets using standard objective functions such as cross-entropy (implemented with logsoftmax nonlinearity and a linear objective function) and quadratic loss. More...
 
struct  NnetTrainerOptions
 
class  NonlinearComponent
 This kind of Component is a base-class for things like sigmoid, softmax and ReLU: nonlinearities that don't change the dimension. More...
 
class  NoOpComponent
 
class  NormalizeComponent
 
struct  ObjectiveFunctionInfo
 
class  OffsetForwardingDescriptor
 
class  OnlineNaturalGradient
 Keywords for search: natural gradient, naturalgradient, NG-SGD. More...
 
class  OnlineNaturalGradientSimple
 
class  OptionalSumDescriptor
 This is the case of class SumDescriptor, in which we contain just one term, and that term is optional (an IfDefined() expression). More...
 
struct  PairIsEqualComparator
 
class  PerElementOffsetComponent
 
class  PerElementScaleComponent
 
class  PermuteComponent
 PermuteComponent changes the order of the columns (i.e. More...
 
class  PnormComponent
 
class  RandomComponent
 
class  RectifiedLinearComponent
 
class  RepeatedAffineComponent
 
class  ReplaceIndexForwardingDescriptor
 This ForwardingDescriptor modifies the indexes (n, t, x) by replacing one of them (normally t) with a constant value and keeping the rest. More...
 
class  RoundingForwardingDescriptor
 For use in clockwork RNNs and the like, this forwarding-descriptor rounds the time-index t down to the the closest t' <= t that is an exact multiple of t_modulus_. More...
 
class  SigmoidComponent
 
class  SimpleForwardingDescriptor
 
struct  SimpleObjectiveInfo
 
class  SimpleSumDescriptor
 
class  SoftmaxComponent
 
class  StatisticsExtractionComponent
 
class  StatisticsExtractionComponentPrecomputedIndexes
 
class  StatisticsPoolingComponent
 
class  StatisticsPoolingComponentPrecomputedIndexes
 
class  SumDescriptor
 This is an abstract base-class. More...
 
class  SumGroupComponent
 SumGroupComponent is used to sum up groups of posteriors. More...
 
class  SumReduceComponent
 This component is a fixed (non-trainable) nonlinearity that sums its inputs to produce outputs. More...
 
class  SwitchingForwardingDescriptor
 
class  TanhComponent
 
struct  TarjanNode
 
class  UpdatableComponent
 Class UpdatableComponent is a Component which has trainable parameters; it extends the interface of Component. More...
 
class  VariableMergingOptimizer
 This class is responsible for merging matrices, although you probably want to access it via the the function VariableMergingOptimization(). More...
 

Typedefs

typedef TableWriter
< KaldiObjectHolder
< NnetChainExample > > 
NnetChainExampleWriter
 
typedef SequentialTableReader
< KaldiObjectHolder
< NnetChainExample > > 
SequentialNnetChainExampleReader
 
typedef
RandomAccessTableReader
< KaldiObjectHolder
< NnetChainExample > > 
RandomAccessNnetChainExampleReader
 
typedef std::pair< int32, IndexCindex
 
typedef TableWriter
< KaldiObjectHolder
< NnetDiscriminativeExample > > 
NnetDiscriminativeExampleWriter
 
typedef SequentialTableReader
< KaldiObjectHolder
< NnetDiscriminativeExample > > 
SequentialNnetDiscriminativeExampleReader
 
typedef
RandomAccessTableReader
< KaldiObjectHolder
< NnetDiscriminativeExample > > 
RandomAccessNnetDiscriminativeExampleReader
 
typedef TableWriter
< KaldiObjectHolder
< NnetExample > > 
NnetExampleWriter
 
typedef SequentialTableReader
< KaldiObjectHolder
< NnetExample > > 
SequentialNnetExampleReader
 
typedef
RandomAccessTableReader
< KaldiObjectHolder
< NnetExample > > 
RandomAccessNnetExampleReader
 

Enumerations

enum  AccessType { kReadAccess, kWriteAccess, kReadWriteAccess }
 
enum  ComponentProperties {
  kSimpleComponent = 0x001, kUpdatableComponent = 0x002, kLinearInInput = 0x004, kLinearInParameters = 0x008,
  kPropagateInPlace = 0x010, kPropagateAdds = 0x020, kReordersIndexes = 0x040, kBackpropAdds = 0x080,
  kBackpropNeedsInput = 0x100, kBackpropNeedsOutput = 0x200, kBackpropInPlace = 0x400, kStoresStats = 0x800,
  kInputContiguous = 0x1000, kOutputContiguous = 0x2000
}
 
enum  CommandType {
  kAllocMatrixUndefined, kAllocMatrixZeroed, kDeallocMatrix, kAllocMatrixFromOther,
  kAllocMatrixFromOtherZeroed, kPropagate, kStoreStats, kBackprop,
  kBackpropNoModelUpdate, kMatrixCopy, kMatrixAdd, kCopyRows,
  kAddRows, kCopyRowsMulti, kCopyToRowsMulti, kAddRowsMulti,
  kAddToRowsMulti, kAddRowRanges, kNoOperation, kNoOperationMarker
}
 CommandType is an enum that describes the category of the command used in the NnetComputation. More...
 
enum  ObjectiveType { kLinear, kQuadratic }
 This enum is for a kind of annotation we associate with output nodes of the network; it's for the convenience of calling code so that if the objective is one of a few standard types, we can compute it directly and know how to interpret the supervision labels. More...
 
enum  NodeType {
  kInput, kDescriptor, kComponent, kDimRange,
  kNone
}
 

Functions

void UnitTestPreconditionDirectionsOnline ()
 
std::string PrintCommand (int32 num_commands, int32 command)
 
void UnitTestNnetAnalyze ()
 
static void IndexesMultiToSubmatrixIndexes (const std::vector< std::pair< int32, int32 > > &indexes_multi, std::vector< int32 > *submatrix_indexes)
 given a vector of pairs from computation.indexes_multi_indexes containing paris (submatrix-index, row-index), this function outputs to "submatrix_indexes" all (unique) submatrix indexes that appear; and it outputs to "contains_null_marker" true if the pair (-1, -1) appears anywhere in indexes_multi, and false otherwise. More...
 
void ComputeCommandAttributes (const Nnet &nnet, const NnetComputation &computation, const ComputationVariables &vars, std::vector< CommandAttributes > *attributes)
 
void ComputeVariableAccesses (const ComputationVariables &variables, const std::vector< CommandAttributes > &command_attributes, std::vector< std::vector< Access > > *variable_accesses)
 After the command-level attributes have been computed, this function organizes them per variable (see class ComputationVariables for how a variable is defined; it is part of a matrix). More...
 
void ComputeMatrixAccesses (const Nnet &nnet, const NnetComputation &computation, const ComputationVariables &variables, const std::vector< CommandAttributes > &command_attributes, std::vector< MatrixAccesses > *matrix_accesses)
 This function organizes information in the CommandAttributes in a way that is convenient to access per matrix. More...
 
void CheckComputation (const Nnet &nnet, const ComputationRequest &request, const NnetComputation &computation, bool check_rewrite=false)
 This is a convenience interface for class ComputationChecker. More...
 
void ComputeMatrixToSubmatrix (const NnetComputation &computation, std::vector< std::vector< int32 > > *mat_to_submat)
 This function computes a vector 'mat_to_submat', indexed by matrix index, such that (*mat_to_submat)[m] is a list of all the submatrix indexes that refer to matrix m. More...
 
void PrintMatrixAccesses (std::ostream &os, const std::vector< MatrixAccesses > &matrix_accesses)
 This function is to be used in debugging; it produces human-readable output. More...
 
void PrintCommandAttributes (std::ostream &os, const std::vector< CommandAttributes > &attributes)
 This function is to be used in debugging; it produces human-readable output. More...
 
int32 MaxMemoryUsage (const NnetComputation &computation)
 Returns the total memory, in bytes, used by the computation (just the temporary memory, not counting the memory used by the nnet itself). More...
 
static void MergeSupervision (const std::vector< const NnetChainSupervision * > &inputs, NnetChainSupervision *output)
 
void MergeChainExamples (bool compress, std::vector< NnetChainExample > *input, NnetChainExample *output)
 This function merges a list of NnetChainExample objects into a single one– intended to be used when forming minibatches for neural net training. More...
 
void TruncateDerivWeights (int32 truncate, NnetChainExample *eg)
 This sets to zero any elements of 'egs->outputs[*].deriv_weights' that correspond to frames within the first or last 'truncate' frames of the sequence (e.g. More...
 
void GetChainComputationRequest (const Nnet &nnet, const NnetChainExample &eg, bool need_model_derivative, bool store_component_stats, bool use_xent_regularization, bool use_xent_derivative, ComputationRequest *computation_request)
 This function takes a NnetChainExample and produces a ComputationRequest. More...
 
void ShiftChainExampleTimes (int32 frame_shift, const std::vector< std::string > &exclude_names, NnetChainExample *eg)
 Shifts the time-index t of everything in the input of "eg" by adding "t_offset" to all "t" values– but excluding those with names listed in "exclude_names", e.g. More...
 
void UnitTestIndexIo ()
 
void UnitTestCindexIo ()
 
static void WriteIndexVectorElementBinary (std::ostream &os, const std::vector< Index > &vec, int32 i)
 
static void ReadIndexVectorElementBinary (std::istream &is, int32 i, std::vector< Index > *vec)
 
void WriteIndexVector (std::ostream &os, bool binary, const std::vector< Index > &vec)
 
void ReadIndexVector (std::istream &is, bool binary, std::vector< Index > *vec)
 
static void WriteCindexVectorElementBinary (std::ostream &os, const std::vector< Cindex > &vec, int32 i)
 
static void ReadCindexVectorElementBinary (std::istream &is, int32 i, std::vector< Cindex > *vec)
 
void WriteCindexVector (std::ostream &os, bool binary, const std::vector< Cindex > &vec)
 
void ReadCindexVector (std::istream &is, bool binary, std::vector< Cindex > *vec)
 
std::ostream & operator<< (std::ostream &ostream, const Index &index)
 
std::ostream & operator<< (std::ostream &ostream, const Cindex &cindex)
 
void PrintCindex (std::ostream &os, const Cindex &cindex, const std::vector< std::string > &node_names)
 
void PrintIndexes (std::ostream &ostream, const std::vector< Index > &indexes)
 this will only be used for pretty-printing. More...
 
void PrintCindexes (std::ostream &ostream, const std::vector< Cindex > &cindexes, const std::vector< std::string > &node_names)
 this will only be used for pretty-printing. More...
 
void PrintIntegerVector (std::ostream &os, const std::vector< int32 > &ints)
 
void AppendCindexes (int32 node, const std::vector< Index > &indexes, std::vector< Cindex > *out)
 Appends to 'out' the pairs (node, indexes[0]), (node, indexes[1]), ... More...
 
void UnitTestNnetCompile ()
 
void PrintVectorVectorPair (std::vector< std::vector< std::pair< int32, int32 > > > vec_vec_pair)
 
void UnitTestSplitLocationsBackward (bool verbose)
 
void UnitTestHasContiguousProperty ()
 
void UnitTestEnsureContiguousProperty ()
 
void UnitTestSplitLocations (bool verbose)
 
bool SecondElementComparator (const std::pair< int32, int32 > &first_pair, const std::pair< int32, int32 > &second_pair)
 
void SortSubmatLists (const std::vector< std::vector< std::pair< int32, int32 > > > submat_lists, std::vector< std::vector< std::pair< int32, int32 > > > *sorted_submat_lists, int32 *max_submat_list_size)
 
void ComputeSubmatIndexHistogram (const std::vector< std::vector< std::pair< int32, int32 > > > sorted_submat_lists, unordered_map< int32, std::vector< int32 > > *submat_histogram)
 
void FindSubmatIndexInSubmatLists (int32 submat_index, std::vector< std::vector< std::pair< int32, int32 > > > *sorted_submat_lists, std::vector< std::vector< std::pair< int32, int32 > >::iterator > *output_iterator_list, int32 *max_remaining_submat_list_size)
 
void ExtractGivenPairsFromSubmatLists (std::vector< std::vector< std::pair< int32, int32 > >::iterator > &input_iterator_list, std::vector< std::vector< std::pair< int32, int32 > > > *sorted_submat_lists, std::vector< std::pair< int32, int32 > > *list_of_pairs)
 
static void ExtractLastPairFromSubmatLists (std::vector< std::vector< std::pair< int32, int32 > > > *sorted_submat_lists, std::vector< std::pair< int32, int32 > > *list_of_pairs)
 
static void SplitLocationsUsingSubmatHistogram (int32 max_submat_list_size, std::vector< std::vector< std::pair< int32, int32 > > > *sorted_submat_lists, std::vector< std::pair< int32, int32 > > *submat_histogram_vector, std::vector< std::vector< std::pair< int32, int32 > > > *split_lists)
 
void SplitLocations (const std::vector< std::vector< std::pair< int32, int32 > > > &submat_lists, std::vector< std::vector< std::pair< int32, int32 > > > *split_lists)
 The input to this function is a vector of lists of pairs, and this function splits it up into a list of vectors of pairs. More...
 
bool ConvertToIndexes (const std::vector< std::pair< int32, int32 > > &location_vector, int32 *first_value, std::vector< int32 > *second_values)
 If it is the case for some i >= 0 that all the .first elements of "location_vector" are either i or -1, then output i to first_value and the .second elements into "second_values", and return true. More...
 
void EnsureContiguousProperty (const std::vector< int32 > &indexes, std::vector< std::vector< int32 > > *indexes_out)
 This function takes a vector of indexes and splits it up into as separate vectors of the same size, as needed to ensure that the 'contiguous property' holds. More...
 
void SplitPairList (std::vector< std::pair< int32, int32 > > &list, std::vector< std::vector< std::pair< int32, int32 > > > *split_lists)
 This function splits a vector of pairs into a list of vectors of pairs. More...
 
void SplitLocationsBackward (const std::vector< std::vector< std::pair< int32, int32 > > > &submat_lists, std::vector< std::vector< std::pair< int32, int32 > > > *split_lists)
 This function has the same interface as SplitLocations(); however, it ensures certain additional properties of the output "split_lists", which are necessary because of the way it is used in backprop code. More...
 
bool HasContiguousProperty (const std::vector< int32 > &indexes, std::vector< std::pair< int32, int32 > > *reverse_indexes)
 This function returns true if for each integer i != -1, all the indexes j at which indexes[j] == i are consecutive with no gaps (more formally: if j1 < j2 < j3 and indexes[j1] != -1 and indexes[j1] == indexes[j3], then indexes[j1] == indexes[j2]). More...
 
static void ResetSeed (int32 rand_seed, const Component &c)
 
static bool StringsApproxEqual (const std::string &a, const std::string &b)
 
void TestNnetComponentIo (Component *c)
 
void TestNnetComponentCopy (Component *c)
 
void TestNnetComponentAddScale (Component *c)
 
void TestNnetComponentVectorizeUnVectorize (Component *c)
 
void TestStringsApproxEqual ()
 
void TestNnetComponentUpdatable (Component *c)
 
void TestSimpleComponentPropagateProperties (const Component &c)
 
bool TestSimpleComponentDataDerivative (const Component &c, BaseFloat perturb_delta)
 
bool TestSimpleComponentModelDerivative (const Component &c, BaseFloat perturb_delta, bool test_derivative)
 
void UnitTestNnetComponent ()
 
std::ostream & operator<< (std::ostream &os, const ComputationGraphBuilder::ComputableInfo &info)
 This is to be used in logging only. More...
 
void ComputeComputationGraph (const Nnet &nnet, const ComputationRequest &request, ComputationGraph *graph)
 
static int32 SumVectorSizes (const std::vector< std::vector< int32 > > &vec)
 
static void ComputeComputationPhasesForEpoch (const Nnet &nnet, const ComputationGraph &graph, const std::vector< int32 > &this_epoch, const std::vector< std::vector< int32 > > &dependencies_subset, const std::vector< std::vector< int32 > > &depend_on_subset, bool epoch_is_trivial, std::vector< int32 > *phase_indexes, std::vector< std::vector< int32 > > *phases)
 
void ComputeComputationPhases (const Nnet &nnet, const ComputationGraph &computation_graph, std::vector< std::vector< int32 > > *phases)
 This function divides a computation into 'phases', where a 'phase' is a collection of cindexes which can (as far as the computation graph is concerned) all be computed at the same time, and depend only on cindexes previously computed in earlier phases. More...
 
void ComputeComputationSteps (const Nnet &nnet, const ComputationRequest &request, const std::vector< std::vector< int32 > > &phases, ComputationGraph *computation_graph, std::vector< std::vector< int32 > > *steps)
 This function arranges the cindex_ids of the computation into a sequence of lists called "steps", which will correspond roughly to the commands in the compiled computation. More...
 
static void GetIndexesStrings (const Nnet &nnet, const NnetComputation &computation, std::vector< std::string > *indexes_strings)
 
static void GetIndexesMultiStrings (const Nnet &nnet, const NnetComputation &computation, std::vector< std::string > *indexes_multi_strings)
 
static void PrintCommand (std::ostream &os, const Nnet &nnet, const NnetComputation &computation, int32 command_index, const std::vector< std::string > &submatrix_strings, const std::vector< std::string > &indexes_strings, const std::vector< std::string > &indexes_multi_strings)
 
static void PrintComputationPreamble (std::ostream &os, const NnetComputation &c, const Nnet &nnet, const std::vector< std::string > &submatrix_strings, const std::vector< std::string > &indexes_strings, const std::vector< std::string > &indexes_multi_strings)
 
std::ostream & operator<< (std::ostream &os, NnetComputation &computation)
 
void UnitTestNnetComputationIo (NnetComputation *computation)
 
void UnitTestComputationRequestIo (ComputationRequest *request)
 
void TestNnetDecodable (const ComputationRequest &request, const std::vector< Matrix< BaseFloat > > &inputs, const Nnet &nnet, const CuMatrixBase< BaseFloat > &reference_output)
 
void UnitTestNnetCompute ()
 
void ComputeMinAndMaxTimes (const std::vector< Index > &indexes, int32 *min_t, int32 *max_t)
 
void SetDerivTimesOptions (const ComputationRequest &request, NnetOptimizeOptions *opt_config)
 
void UnitTestNnetModelDerivatives ()
 
void UnitTestNnetInputDerivatives ()
 
ForwardingDescriptorGenRandForwardingDescriptor (int32 num_nodes)
 
SumDescriptorGenRandSumDescriptor (int32 num_nodes)
 
void GenRandDescriptor (int32 num_nodes, Descriptor *desc)
 
void UnitTestDescriptorIo ()
 
void UnitTestGeneralDescriptor ()
 
std::string NormalizeTextDescriptor (const std::vector< std::string > &node_names, const std::string &desc_str)
 
void UnitTestGeneralDescriptorSpecial ()
 
static std::string ParsingContext (const std::string *token_ptr)
 
static void ExpectToken (const std::string &token, const std::string &what_we_are_parsing, const std::string **next_token)
 
static int32 ReadIntegerToken (const std::string &what_we_are_parsing, const std::string **next_token)
 
void ComputeAccuracy (const GeneralMatrix &supervision, const CuMatrixBase< BaseFloat > &nnet_output, BaseFloat *tot_weight, BaseFloat *tot_accuracy)
 This function computes the frame accuracy for this minibatch. More...
 
void MergeSupervision (const std::vector< const NnetDiscriminativeSupervision * > &inputs, NnetDiscriminativeSupervision *output)
 
void MergeDiscriminativeExamples (bool compress, std::vector< NnetDiscriminativeExample > *input, NnetDiscriminativeExample *output)
 Appends the given vector of examples (which must be non-empty) into a single output example. More...
 
void TruncateDerivWeights (int32 truncate, NnetDiscriminativeExample *eg)
 This sets to zero any elements of 'egs->outputs[*].deriv_weights' that correspond to frames within the first or last 'truncate' frames of the sequence (e.g. More...
 
void GetDiscriminativeComputationRequest (const Nnet &nnet, const NnetDiscriminativeExample &eg, bool need_model_derivative, bool store_component_stats, bool use_xent_regularization, bool use_xent_derivative, ComputationRequest *computation_request)
 This function takes a NnetDiscriminativeExample and produces a ComputationRequest. More...
 
void ShiftDiscriminativeExampleTimes (int32 frame_shift, const std::vector< std::string > &exclude_names, NnetDiscriminativeExample *eg)
 Shifts the time-index t of everything in the input of "eg" by adding "t_offset" to all "t" values– but excluding those with names listed in "exclude_names", e.g. More...
 
void UnitTestNnetExample ()
 
void UnitTestNnetMergeExamples ()
 
static void GetIoNames (const std::vector< NnetExample > &src, std::vector< std::string > *names_vec)
 
static void GetIoSizes (const std::vector< NnetExample > &src, const std::vector< std::string > &names, std::vector< int32 > *sizes)
 
static void MergeIo (const std::vector< NnetExample > &src, const std::vector< std::string > &names, const std::vector< int32 > &sizes, bool compress, NnetExample *merged_eg)
 
void MergeExamples (const std::vector< NnetExample > &src, bool compress, NnetExample *dest)
 Merge a set of input examples into a single example (typically the size of "src" will be the minibatch size). More...
 
void ShiftExampleTimes (int32 t_offset, const std::vector< std::string > &exclude_names, NnetExample *eg)
 Shifts the time-index t of everything in the "eg" by adding "t_offset" to all "t" values. More...
 
void GetComputationRequest (const Nnet &nnet, const NnetExample &eg, bool need_model_derivative, bool store_component_stats, ComputationRequest *computation_request)
 This function takes a NnetExample (which should already have been frame-selected, if desired, and merged into a minibatch) and produces a ComputationRequest. More...
 
void WriteVectorAsChar (std::ostream &os, bool binary, const VectorBase< BaseFloat > &vec)
 
void ReadVectorAsChar (std::istream &is, bool binary, Vector< BaseFloat > *vec)
 
void RoundUpNumFrames (int32 frame_subsampling_factor, int32 *num_frames, int32 *num_frames_overlap)
 
static void CopyPairVector (const CuArray< Int32Pair > &in, std::vector< std::pair< int32, int32 > > *out)
 
static void CopyPairVector (const std::vector< std::pair< int32, int32 > > &in, CuArray< Int32Pair > *out)
 
bool AssertGraphEqual (const std::vector< std::vector< int32 > > &graph1, const std::vector< std::vector< int32 > > &graph2)
 
bool AssertVectorEqual (const std::vector< int32 > &vec1, const std::vector< int32 > &vec2)
 
void BuildTestGraph (std::vector< std::vector< int32 > > *graph)
 
void BuildTestGraphTranspose (std::vector< std::vector< int32 > > *graph)
 
void BuildTestSccs (std::vector< std::vector< int32 > > *sccs)
 
void BuildTestSccGraph (std::vector< std::vector< int32 > > *scc_graph)
 
void BuildTestTopSortOrder (std::vector< int32 > *node_to_order)
 
void UnitTestComputeGraphTranspose ()
 
void UnitTestFindSccs ()
 
void UnitTestMakeSccGraph ()
 
void UnitTestComputeTopSortOrder ()
 
void UnitTestComputeTopSortOrder2 ()
 
void NnetToDirectedGraph (const Nnet &nnet, std::vector< std::vector< int32 > > *graph)
 This function takes an nnet and turns it to a directed graph on nodes. More...
 
void ComputeGraphTranspose (const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *graph_transpose)
 Outputs a graph in which the order of arcs is reversed. More...
 
void TarjanSccRecursive (int32 node, const std::vector< std::vector< int32 > > &graph, int32 *global_index, std::vector< TarjanNode > *tarjan_nodes, std::vector< int32 > *tarjan_stack, std::vector< std::vector< int32 > > *sccs)
 
void FindSccsTarjan (const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *sccs)
 
void FindSccs (const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *sccs)
 Given a directed graph (where each std::vector<int32> is a list of destination-nodes of arcs coming from the current node), partition it into strongly connected components (i.e. More...
 
void MakeSccGraph (const std::vector< std::vector< int32 > > &graph, const std::vector< std::vector< int32 > > &sccs, std::vector< std::vector< int32 > > *scc_graph)
 Given a list of sccs of a graph (e.g. More...
 
void ComputeTopSortOrderRecursive (int32 node, const std::vector< std::vector< int32 > > &graph, std::vector< bool > *cycle_detector, std::vector< bool > *is_visited, std::vector< int32 > *reversed_orders)
 
void ComputeTopSortOrder (const std::vector< std::vector< int32 > > &graph, std::vector< int32 > *node_to_order)
 Given an acyclic graph (where each std::vector<int32> is a list of destination-nodes of arcs coming from the current node), compute a topological ordering of the graph nodes. More...
 
std::string PrintGraphToString (const std::vector< std::vector< int32 > > &graph)
 Prints a graph to a string in a pretty way for human readability, e.g. More...
 
void ComputeNnetComputationEpochs (const Nnet &nnet, std::vector< int32 > *node_to_epoch)
 This function computes the order in which we need to compute each node in the graph, where each node-index n maps to an epoch-index t = 0, 1, ... More...
 
void UnitTestNnetIo ()
 
static bool UnitTestNnetOptimizeWithOptions (NnetOptimizeOptions opt_config)
 
static void UnitTestNnetOptimize ()
 
void IdentifySubmatrixArgs (NnetComputation::Command *command, std::vector< int32 * > *submatrix_args)
 This function outputs to "submatrix_args" the addresses of a subset of arguments arg1 through arg6 in "command", that correspond to the indexes of submatrices. More...
 
void IdentifySubmatrixArgs (std::vector< NnetComputation::Command > *commands, std::vector< int32 * > *submatrix_args)
 This function outputs to "submatrix_args" the addresses of the args (arguments arg1 through arg6) in the vector "commands", that correspond to the indexes of submatrices. More...
 
void IdentifyMatrixArgs (std::vector< NnetComputation::Command > *command, std::vector< int32 * > *matrix_args)
 This function outputs to "matrix_args" the addresses of a subset of the arguments arg1 through arg6 in commands in "commands", that correspond to the indexes of matrices. More...
 
void IdentifyMatrixArgsInComputation (bool include_from_submatrices, NnetComputation *computation, std::vector< int32 * > *matrix_args)
 This function outputs to "matrix_args" the addresses of indexes inside 'computation' that correspond to matrices. More...
 
void IdentifyIndexesMultiArgs (std::vector< NnetComputation::Command > *commands, std::vector< int32 * > *indexes_multi_args)
 Identifies in the vector of commands, arguments that correspond to indexes into the computation's indexes_multi array, and outputs a list of pointers to those arguments to 'indexes_multi_args'. More...
 
void IdentifyIndexesRangesArgs (std::vector< NnetComputation::Command > *commands, std::vector< int32 * > *indexes_ranges_args)
 Identifies in the vector of commands, arguments that correspond to indexes into the computation's 'indexes_ranges' array, and outputs a list of pointers to those arguments to 'indexes_ranges_args'. More...
 
void IdentifyIndexesArgs (std::vector< NnetComputation::Command > *commands, std::vector< int32 * > *indexes_args)
 Identifies in the vector of commands, arguments that correspond to indexes into the computation's 'indexes' array, and outputs a list of pointers to those arguments to 'indexes_args'. More...
 
void IdentifyMatrixArgs (NnetComputation::Command *command, std::vector< int32 * > *matrix_args)
 This function outputs to "matrix_args" the addresses of a subset of the arguments arg1 through arg6 in "command", that correspond to the indexes of matrices. More...
 
void IdentifySubmatrixArgsInComputation (NnetComputation *computation, std::vector< int32 * > *submatrix_args)
 This function outputs to "submatrix_args" the addresses of integers in 'computation' that correspond to submatrices. More...
 
void RenumberComputation (NnetComputation *computation)
 This function detects submatrices, matrices, and members of indexes_multi and indexes that are never used (e.g. More...
 
void RemoveNoOps (NnetComputation *computation)
 Removes commands of type kNoOperation in the computation. More...
 
bool ReplaceInInput (const Nnet &nnet, int32 orig_matrix_index, int32 new_matrix_index, NnetComputation *computation)
 Wherever matrix orig_matrix_index appears in the input of the network (i.e. More...
 
bool ReplaceInOutput (const Nnet &nnet, int32 orig_matrix_index, int32 new_matrix_index, NnetComputation *computation)
 Wherever matrix orig_matrix_index appears in the output of the network (i.e. More...
 
static
NnetComputation::SubMatrixInfo 
GetSubMatrixOfSubMatrix (const NnetComputation &computation, int32 submat_a, int32 submat_b)
 This static function returns a SubMatrixInfo corresponding to replacing the matrix-index in a's "matrix_index" with, essentially, sub-matrix b. More...
 
void LimitDerivativeTimes (const Nnet &nnet, int32 min_deriv_time, int32 max_deriv_time, NnetComputation *computation)
 
void MoveSizingCommands (const Nnet &nnet, NnetComputation *computation)
 This optimization moves commands that initialize matrices to as late as possible, and commands that empty matrices to as early as possible. More...
 
void RemoveUnnecessaryZeroing (const Nnet &nnet, NnetComputation *computation)
 This optimization function changes, where possible, matrix initializations of type kAllocMatrixZeroed to kAllocMatrixUndefined. More...
 
static void ComputeCommandPairs (const std::pair< std::vector< int32 >, std::vector< int32 > > &lists, std::vector< std::pair< int32, int32 > > *pairs)
 
void RemoveUnnecessaryAllocation (const Nnet &nnet, NnetComputation *computation)
 This optimization detects cases where we deallocate a matrix, and then later allocate another matrix of the same size; and replaces them with commands of type kAllocFromOther or kAllocFromOtherZeroed. More...
 
void VariableMergingOptimization (const NnetOptimizeOptions &config, const Nnet &nnet, const ComputationRequest &request, NnetComputation *computation)
 This wraps class VariableMergingOptimizer in a simplified interface. More...
 
void ConsolidateModelUpdate (const Nnet &nnet, const ComputationRequest &request, NnetComputation *computation)
 This consolidates the model-update parts of the backprop into larger operations (applicable mostly to recurrent setups)– internally it uses class ModelUpdateConsolidator. More...
 
void ConvertAdditionToAssignment (const Nnet &nnet, NnetComputation *computation)
 This converts addition operations (things with Add in their names) to copy operations (things with Copy in their names). More...
 
void Optimize (const NnetOptimizeOptions &config, const Nnet &nnet, const ComputationRequest &request, NnetComputation *computation)
 This is the top-level function for optimizing a computation. More...
 
void LimitDerivativeTimes (const Nnet &nnet, const ComputationRequest &request, const NnetOptimizeOptions &opts, NnetComputation *computation)
 This optimization, which has no effect unless you set –min-deriv-time or –max-deriv-time, modifies the backprop operations for efficiency based on the assumption that derivatives for any Cindex with t < min_deriv_time or t > max_deriv_time are zero. More...
 
void UnitTestConfigLineParse ()
 
void UnitTestReadConfig ()
 
void UnitTestDescriptorTokenize ()
 
void UnitTestSummarizeVector ()
 
void UnitTestNameMatchesPattern ()
 
void ExpectOneOrTwoTokens (std::istream &is, bool binary, const std::string &token1, const std::string &token2)
 This function is like ExpectToken but for two tokens, and it will either accept token1 and then token2, or just token2. More...
 
bool ParseFromString (const std::string &name, std::string *string, int32 *param)
 Function used in Init routines. More...
 
bool ParseFromString (const std::string &name, std::string *string, bool *param)
 This version of ParseFromString is for parameters of type bool, which can appear as any string beginning with f, F, t or T. More...
 
bool ParseFromString (const std::string &name, std::string *string, BaseFloat *param)
 This version of ParseFromString is for parameters of type BaseFloat. More...
 
bool ParseFromString (const std::string &name, std::string *string, std::string *param)
 This version of ParseFromString is for parsing strings. More...
 
bool ParseFromString (const std::string &name, std::string *string, std::vector< int32 > *param)
 This version of ParseFromString handles colon-separated or comma-separated lists of integers. More...
 
bool DescriptorTokenize (const std::string &input, std::vector< std::string > *tokens)
 This function tokenizes input when parsing Descriptor configuration values. More...
 
bool IsValidName (const std::string &name)
 Returns true if 'name' would be a valid name for a component or node in a Nnet. More...
 
void ReadConfigLines (std::istream &is, std::vector< std::string > *lines)
 This function reads in a config file and *appends* its contents to a vector of lines; it is responsible for removing comments (anything after '#') and stripping out any lines that contain only whitespace after comment removal. More...
 
std::string ErrorContext (std::istream &is)
 Return a string used in error messages. More...
 
std::string ErrorContext (const std::string &str)
 
static void PrintFloatSuccinctly (std::ostream &os, BaseFloat f)
 
std::string SummarizeVector (const Vector< BaseFloat > &vec)
 
void PrintParameterStats (std::ostringstream &os, const std::string &name, const CuVectorBase< BaseFloat > &params, bool include_mean=false)
 Print to 'os' some information about the mean and standard deviation of some parameters, used in Info() functions in nnet-simple-component.cc. More...
 
void PrintParameterStats (std::ostringstream &os, const std::string &name, const CuMatrix< BaseFloat > &params, bool include_mean=false)
 Print to 'os' some information about the mean and standard deviation of some parameters, used in Info() functions in nnet-simple-component.cc. More...
 
void ParseConfigLines (const std::vector< std::string > &lines, std::vector< ConfigLine > *config_lines)
 This function converts config-lines from a simple sequence of strings as output by ReadConfigLines(), into a sequence of first-tokens and name-value pairs. More...
 
bool NameMatchesPattern (const char *name, const char *pattern)
 
int32 YzxVectorIndex (int32 x, int32 y, int32 z, int32 input_x_dim, int32 input_y_dim, int32 input_z_dim)
 
int32 ZyxVectorIndex (int32 x, int32 y, int32 z, int32 input_x_dim, int32 input_y_dim, int32 input_z_dim)
 
void RearrangeIndexes (const std::vector< std::vector< int32 > > &in, std::vector< std::vector< int32 > > *out)
 
void GenerateConfigSequenceSimplest (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceSimpleContext (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceSimple (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceStatistics (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceRnn (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceRnnClockwork (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceLstm (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceLstmWithTruncation (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceLstmType2 (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceCnn (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceDistribute (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 
void GenerateConfigSequenceCompositeBlock (const NnetGenerationOptions &opts, std::vector< std::string > *configs)
 Generate a config string with a composite component composed only of block affine, repeated affine, and natural gradient repeated affine components. More...
 
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 is the initial nnet, and the remaining ones may do things like add layers. More...
 
void ComputeExampleComputationRequestSimple (const Nnet &nnet, ComputationRequest *request, std::vector< Matrix< BaseFloat > > *inputs)
 This function computes an example computation request, for testing purposes. More...
 
static void GenerateRandomComponentConfig (std::string *component_type, std::string *config)
 
ComponentGenerateRandomSimpleComponent ()
 Generates random simple component for testing. More...
 
bool NnetParametersAreIdentical (const Nnet &nnet1, const Nnet &nnet2, BaseFloat threshold)
 Used for testing that the updatable parameters in two networks are the same. More...
 
void GenerateSimpleNnetTrainingExample (int32 num_supervised_frames, int32 left_context, int32 right_context, int32 input_dim, int32 output_dim, int32 ivector_dim, NnetExample *example)
 Low-level function that generates an nnet training example. More...
 
bool ExampleApproxEqual (const NnetExample &eg1, const NnetExample &eg2, BaseFloat delta)
 Returns true if the examples are approximately equal (only intended to be used in testing). More...
 
void ComputeObjectiveFunction (const GeneralMatrix &supervision, ObjectiveType objective_type, const std::string &output_name, bool supply_deriv, NnetComputer *computer, BaseFloat *tot_weight, BaseFloat *tot_objf)
 This function computes the objective function, and if supply_deriv = true, supplies its derivative to the NnetComputation object. More...
 
void UnitTestNnetContext ()
 
void UnitTestConvertRepeatedToBlockAffine ()
 
void UnitTestConvertRepeatedToBlockAffineComposite ()
 
int32 NumOutputNodes (const Nnet &nnet)
 returns the number of output nodes of this nnet. More...
 
int32 NumInputNodes (const Nnet &nnet)
 returns the number of input nodes of this nnet. More...
 
bool IsSimpleNnet (const Nnet &nnet)
 This function returns true if the nnet has the following properties: It has an called "output" (other outputs are allowed but may be ignored). More...
 
void EvaluateComputationRequest (const Nnet &nnet, const ComputationRequest &request, std::vector< std::vector< bool > > *is_computable)
 Given an nnet and a computation request, this function works out which requested outputs in the computation request are computable; it outputs this information as a vector "is_computable" indexed by the same indexes as request.outputs. More...
 
static void ComputeSimpleNnetContextForShift (const Nnet &nnet, int32 input_start, int32 window_size, int32 *left_context, int32 *right_context)
 
void ComputeSimpleNnetContext (const Nnet &nnet, int32 *left_context, int32 *right_context)
 ComputeNnetContext computes the left-context and right-context of a nnet. More...
 
void SetZero (bool is_gradient, Nnet *nnet)
 Calls SetZero (with the given is_gradient parameter) on all updatable components of the nnet. More...
 
void PerturbParams (BaseFloat stddev, Nnet *nnet)
 Calls PerturbParams (with the given stddev) on all updatable components of the nnet. More...
 
void ComponentDotProducts (const Nnet &nnet1, const Nnet &nnet2, VectorBase< BaseFloat > *dot_prod)
 Returns dot products between two networks of the same structure (calls the DotProduct functions of the Updatable components and fill in the output vector). More...
 
std::string PrintVectorPerUpdatableComponent (const Nnet &nnet, const VectorBase< BaseFloat > &vec)
 This function is for printing, to a string, a vector with one element per updatable component of the nnet (e.g. More...
 
BaseFloat DotProduct (const Nnet &nnet1, const Nnet &nnet2)
 Returns dot product between two networks of the same structure (calls the DotProduct functions of the Updatable components and sums up the return values). More...
 
void ZeroComponentStats (Nnet *nnet)
 Zeroes the component stats in all nonlinear components in the nnet. More...
 
void ScaleLearningRate (BaseFloat learning_rate_scale, Nnet *nnet)
 Scales the actual learning rate for all the components in the nnet by this factor. More...
 
void SetLearningRate (BaseFloat learning_rate, Nnet *nnet)
 Sets the underlying learning rate for all the components in the nnet to this value. More...
 
void SetLearningRates (const Vector< BaseFloat > &learning_rates, Nnet *nnet)
 Sets the actual learning rates for all the updatable components in the neural net to the values in 'learning_rates' vector (one for each updatable component). More...
 
void GetLearningRates (const Nnet &nnet, Vector< BaseFloat > *learning_rates)
 Get the learning rates for all the updatable components in the neural net (the output must have dim equal to the number of updatable components). More...
 
void ScaleNnetComponents (const Vector< BaseFloat > &scales, Nnet *nnet)
 Scales the parameters of each of the updatable components. More...
 
void ScaleNnet (BaseFloat scale, Nnet *nnet)
 Scales the nnet parameters and stats by this scale. More...
 
void AddNnetComponents (const Nnet &src, const Vector< BaseFloat > &alphas, BaseFloat scale, Nnet *dest)
 Does *dest += alpha * src for updatable components (affect nnet parameters), and *dest += scale * src for other components (affect stored stats). More...
 
void AddNnet (const Nnet &src, BaseFloat alpha, Nnet *dest)
 Does *dest += alpha * src (affects nnet parameters and stored stats). More...
 
int32 NumParameters (const Nnet &src)
 Returns the total of the number of parameters in the updatable components of the nnet. More...
 
void VectorizeNnet (const Nnet &src, VectorBase< BaseFloat > *params)
 Copies the nnet parameters to *params, whose dimension must be equal to NumParameters(src). More...
 
void UnVectorizeNnet (const VectorBase< BaseFloat > &params, Nnet *dest)
 Copies the parameters from params to *dest. More...
 
int32 NumUpdatableComponents (const Nnet &dest)
 Returns the number of updatable components in the nnet. More...
 
void ConvertRepeatedToBlockAffine (CompositeComponent *c_component)
 
void ConvertRepeatedToBlockAffine (Nnet *nnet)
 Convert all components of type RepeatedAffineComponent or NaturalGradientRepeatedAffineComponent to BlockAffineComponent in nnet. More...
 
std::string NnetInfo (const Nnet &nnet)
 This function returns various info about the neural net. More...
 
void SetDropoutProportion (BaseFloat dropout_proportion, Nnet *nnet)
 This function sets the dropout proportion in all dropout component to dropout_proportion value. More...
 
void FindOrphanComponents (const Nnet &nnet, std::vector< int32 > *components)
 This function finds a list of components that are never used, and outputs the integer comopnent indexes (you can use these to index nnet.GetComponentNames() to get their names). More...
 
void FindOrphanNodes (const Nnet &nnet, std::vector< int32 > *nodes)
 This function finds a list of nodes that are never used to compute any output, and outputs the integer node indexes (you can use these to index nnet.GetNodeNames() to get their names). More...
 
void ReadEditConfig (std::istream &config_file, Nnet *nnet)
 ReadEditConfig() reads a file with a similar-looking format to the config file read by Nnet::ReadConfig(), but this consists of a sequence of operations to perform on an existing network, mostly modifying components. More...
 
BaseFloat KlDivergence (const Vector< BaseFloat > &p, const Vector< BaseFloat > &q)
 
void PrintPriorDiagnostics (const Vector< BaseFloat > &old_priors, const Vector< BaseFloat > &new_priors)
 
void SetPriors (const TransitionModel &tmodel, const Vector< double > &transition_accs, double prior_floor, AmNnetSimple *am_nnet)
 
int32 GetCount (double expected_count)
 
bool ContainsSingleExample (const NnetExample &eg, int32 *min_input_t, int32 *max_input_t, int32 *min_output_t, int32 *max_output_t)
 Returns true if the "eg" contains just a single example, meaning that all the "n" values in the indexes are zero, and the example has NnetIo members named both "input" and "output". More...
 
void FilterExample (const NnetExample &eg, int32 min_input_t, int32 max_input_t, int32 min_output_t, int32 max_output_t, NnetExample *eg_out)
 This function filters the indexes (and associated feature rows) in a NnetExample, removing any index/row in an NnetIo named "input" with t < min_input_t or t > max_input_t and any index/row in an NnetIo named "output" with t < min_output_t or t > max_output_t. More...
 
bool SelectFromExample (const NnetExample &eg, std::string frame_str, int32 left_context, int32 right_context, int32 frame_shift, NnetExample *eg_out)
 This function is responsible for possibly selecting one frame from multiple supervised frames, and reducing the left and right context as specified. More...
 
static bool ProcessFile (const discriminative::SplitDiscriminativeSupervisionOptions &config, const TransitionModel &tmodel, const MatrixBase< BaseFloat > &feats, const MatrixBase< BaseFloat > *ivector_feats, const discriminative::DiscriminativeSupervision &supervision, const std::string &utt_id, bool compress, int32 left_context, int32 right_context, int32 frames_per_eg, int32 frames_overlap_per_eg, int32 frame_subsampling_factor, int64 *num_frames_written, int64 *num_egs_written, NnetDiscriminativeExampleWriter *example_writer)
 This function does all the processing for one utterance, and outputs the supervision objects to 'example_writer'. More...
 
static void ProcessFile (const MatrixBase< BaseFloat > &feats, const MatrixBase< BaseFloat > *ivector_feats, const MatrixBase< BaseFloat > &targets, const std::string &utt_id, bool compress, int32 num_targets, int32 left_context, int32 right_context, int32 frames_per_eg, int64 *num_frames_written, int64 *num_egs_written, NnetExampleWriter *example_writer)
 
static void ProcessFile (const MatrixBase< BaseFloat > &feats, const MatrixBase< BaseFloat > *ivector_feats, const Posterior &pdf_post, const std::string &utt_id, bool compress, int32 num_pdfs, int32 left_context, int32 right_context, int32 frames_per_eg, int64 *num_frames_written, int64 *num_egs_written, NnetExampleWriter *example_writer)
 
int32 NumOutputIndexes (const NnetExample &eg)
 

Variables

static bool computation_checker_warned_unused_input = false
 Checks that we never use variables before they are allocated or after they are deallocated, and some other checks that can be done from the MatrixAccesses. More...
 

Typedef Documentation

typedef std::pair<int32, Index> Cindex

Definition at line 100 of file nnet-common.h.

Enumeration Type Documentation

enum AccessType
Enumerator
kReadAccess 
kWriteAccess 
kReadWriteAccess 

Definition at line 76 of file nnet-analyze.h.

CommandType is an enum that describes the category of the command used in the NnetComputation.

We declare it outside that class because it's so frequently used and we got tired of typing NnetComputation:: everywhere. We document the commands here.

  • kAllocMatrixUndefined: Allocate a matrix. arg1 = index of matrix.
  • kAllocMatrixZeroed: Allocate and zero a matrix. arg1 = index of matrix.
  • kDeallocMatrix: Deallocate a matrix. arg1 = index of matrix.
  • kAllocMatrixFromOther: initialize matrix indexed arg1 using memory from matrix indexed arg2 (using shallow swap).
  • kAllocMatrixFromOtherZeroed: initialize matrix indexed arg1 using memory from matrix indexed arg2 (using shallow swap), then zero the matrix we just allocated.
  • kPropagate: Forward computation of neural net, see Component::Propagate()
    • arg1 is is component-index in neural net
    • arg2 is index into ComponentPrecomputedIndexes (0 if NULL; always 0 for simple Components)
    • arg3 is sub-matrix index of input
    • arg4 is sub-matrix index of output
  • kStoreStats: Call Component::StoreStats() (used for computing diagnostics such as average activations; called after Propagate).
    • arg1 is component-index in neural net
    • arg2 is sub-matrix index of the output of the Propagate function
  • kBackprop: Do the back-propagation operation, see Component::Backprop()
    • arg1 is index of component in neural net
    • arg2 is index into ComponentPrecomputedIndexes (0 if NULL; always 0 for simple Components)
    • arg3 is submatrix-index of input value (input to Propagate()); 0 if unused
    • arg4 is submatrix-index of output value (output of Propagate()); 0 if unused
    • arg5 is submatrix-index of output derivative
    • arg6 is submatrix-index of input derivative; 0 if unused.
  • kBackpropNoModelUpdate: as kBackprop, but does not set the 'to_update' argument to the Backprop call, even if the model is updatable, so it skips the model-update phase of backprop.
  • kMatrixCopy: Copy contents of sub-matrix arg2 to sub-matrix arg1
  • kMatrixAdd: Add contents of sub-matrix arg2 to sub-matrix arg1
  • kCopyRows: call CopyRows() on sub-matrix arg1 with sub-matrix arg2 and indexes[arg3] as arguments.
  • kAddRows: call AddRows() on sub-matrix arg1 with sub-matrix arg2 and indexes[arg3] as arguments.
  • kAddRowsMulti, kAddToRowsMulti, kCopyRowsMulti, kCopyToRowsMulti: Call the corresponding function in class CuMatrix.
    • arg1 is sub-matrix index of *this matrix in operation
    • arg2 is index into "indexes_multi", of which each pair is (sub-matrix index, row index) (or (-1,-1) for NULL marker), which is turned into a vector of BaseFloat* (pointers to matrix rows) before being given as the argument to the function.
  • kAddRowRanges: call AddRowRanges() on sub-matrix arg1, with arg2 as source sub-matrix, and indexes given indexes_ranges[arg3].
  • kNoOperation: does nothing (sometimes useful during optimization)
  • kNoOperationMarker: does nothing, but used to mark end of forward commands.
Enumerator
kAllocMatrixUndefined 
kAllocMatrixZeroed 
kDeallocMatrix 
kAllocMatrixFromOther 
kAllocMatrixFromOtherZeroed 
kPropagate 
kStoreStats 
kBackprop 
kBackpropNoModelUpdate 
kMatrixCopy 
kMatrixAdd 
kCopyRows 
kAddRows 
kCopyRowsMulti 
kCopyToRowsMulti 
kAddRowsMulti 
kAddToRowsMulti 
kAddRowRanges 
kNoOperation 
kNoOperationMarker 

Definition at line 210 of file nnet-computation.h.

210  {
Enumerator
kSimpleComponent 
kUpdatableComponent 
kLinearInInput 
kLinearInParameters 
kPropagateInPlace 
kPropagateAdds 
kReordersIndexes 
kBackpropAdds 
kBackpropNeedsInput 
kBackpropNeedsOutput 
kBackpropInPlace 
kStoresStats 
kInputContiguous 
kOutputContiguous 

Definition at line 38 of file nnet-component-itf.h.

38  {
39  kSimpleComponent = 0x001, // true if number of rows of input equals number of rows
40  // of output and this component doesn't care about the indexes
41  // (i.e. it maps each row of input to each row of output without
42  // regard to the index values). Will normally be true.
43  kUpdatableComponent = 0x002, // true if the component has parameters that can
44  // be updated. Components that return this flag
45  // must be dynamic_castable to type
46  // UpdatableComponent (but components of type
47  // UpdatableComponent do not have to return this
48  // flag, e.g. if this instance is not really
49  // updatable).
50  kLinearInInput = 0x004, // true if the component's output is always a
51  // linear function of its input, i.e. alpha times
52  // input gives you alpha times output.
53  kLinearInParameters = 0x008, // true if an updatable component's output is always a
54  // linear function of its parameters, i.e. alpha times
55  // parameters gives you alpha times output. This is true
56  // for all updatable components we envisage.
57  kPropagateInPlace = 0x010, // true if we can do the propagate operation in-place
58  // (input and output matrices are the same).
59  // Note: if doing backprop, you'd also need to check
60  // that the kBackpropNeedsInput property is not true.
61  kPropagateAdds = 0x020, // true if the Propagate function adds to, rather
62  // than setting, its output. The Component chooses
63  // whether to add or set, and the calling code has to
64  // accommodate it.
65  kReordersIndexes = 0x040, // true if the ReorderIndexes function might reorder
66  // the indexes (otherwise we can skip calling it).
67  // Must not be set for simple components.
68  kBackpropAdds = 0x080, // true if the Backprop function adds to, rather than
69  // setting, the "in_deriv" output. The Component
70  // chooses whether to add or set, and the calling
71  // code has to accommodate it. Note: in the case of
72  // in-place backprop, this flag has no effect.
73  kBackpropNeedsInput = 0x100, // true if backprop operation needs access to
74  // forward-pass input.
75  kBackpropNeedsOutput = 0x200, // true if backprop operation needs access to
76  // forward-pass output (e.g. true for Sigmoid).
77  kBackpropInPlace = 0x400, // true if we can do the backprop operation in-place
78  // (input and output matrices may be the same).
79  kStoresStats = 0x800, // true if the StoreStats operation stores
80  // statistics e.g. on average node activations and
81  // derivatives of the nonlinearity, (as it does for
82  // Tanh, Sigmoid, ReLU and Softmax).
83  kInputContiguous = 0x1000, // true if the component requires its input data (and
84  // input derivatives) to have Stride()== NumCols().
85  kOutputContiguous = 0x2000 // true if the component requires its input data (and
86  // output derivatives) to have Stride()== NumCols().
87 };
enum NodeType
Enumerator
kInput 
kDescriptor 
kComponent 
kDimRange 
kNone 

Definition at line 55 of file nnet-nnet.h.

This enum is for a kind of annotation we associate with output nodes of the network; it's for the convenience of calling code so that if the objective is one of a few standard types, we can compute it directly and know how to interpret the supervision labels.

However, the core of the framework never makes use of the objective types, other than making them available to calling code which then supplies the derivatives.

  • Objective type kLinear is intended for Neural nets where the final component is a LogSoftmaxComponent, so the log-prob (negative cross-entropy) objective is just a linear function of the input.
  • Objective type kQuadratic is used to mean the objective function f(x, y) = -0.5 (x-y).(x-y), which is to be maximized, as in the kLinear case.
Enumerator
kLinear 
kQuadratic 

Definition at line 52 of file nnet-nnet.h.

Function Documentation

void AddNnet ( const Nnet &  src,
BaseFloat  alpha,
Nnet *  dest 
)

Does *dest += alpha * src (affects nnet parameters and stored stats).

Definition at line 381 of file nnet-utils.cc.

References Component::Add(), Nnet::GetComponent(), KALDI_ERR, and Nnet::NumComponents().

Referenced by main(), and NnetDiscriminativeTrainer::Train().

381  {
382  if (src.NumComponents() != dest->NumComponents())
383  KALDI_ERR << "Trying to add incompatible nnets.";
384  for (int32 c = 0; c < src.NumComponents(); c++) {
385  const Component *src_comp = src.GetComponent(c);
386  Component *dest_comp = dest->GetComponent(c);
387  dest_comp->Add(alpha, *src_comp);
388  }
389 }
#define KALDI_ERR
Definition: kaldi-error.h:127
void AddNnetComponents ( const Nnet &  src,
const Vector< BaseFloat > &  alphas,
BaseFloat  scale,
Nnet *  dest 
)

Does *dest += alpha * src for updatable components (affect nnet parameters), and *dest += scale * src for other components (affect stored stats).

Here, alphas is a vector of size equal to the number of updatable components

Definition at line 354 of file nnet-utils.cc.

References Component::Add(), VectorBase< Real >::Dim(), Nnet::GetComponent(), rnnlm::i, KALDI_ASSERT, KALDI_ERR, kUpdatableComponent, Nnet::NumComponents(), and Component::Properties().

Referenced by NnetChainTrainer::UpdateParamsWithMaxChange(), and NnetTrainer::UpdateParamsWithMaxChange().

355  {
356  if (src.NumComponents() != dest->NumComponents())
357  KALDI_ERR << "Trying to add incompatible nnets.";
358  int32 i = 0;
359  for (int32 c = 0; c < src.NumComponents(); c++) {
360  const Component *src_comp = src.GetComponent(c);
361  Component *dest_comp = dest->GetComponent(c);
362  if (src_comp->Properties() & kUpdatableComponent) {
363  // For now all updatable components inherit from class UpdatableComponent.
364  // If that changes in future, we will change this code.
365  const UpdatableComponent *src_uc =
366  dynamic_cast<const UpdatableComponent*>(src_comp);
367  UpdatableComponent *dest_uc =
368  dynamic_cast<UpdatableComponent*>(dest_comp);
369  if (src_uc == NULL || dest_uc == NULL)
370  KALDI_ERR << "Updatable component does not inherit from class "
371  "UpdatableComponent; change this code.";
372  KALDI_ASSERT(i < alphas.Dim());
373  dest_uc->Add(alphas(i++), *src_uc);
374  } else { // add stored stats
375  dest_comp->Add(scale, *src_comp);
376  }
377  }
378  KALDI_ASSERT(i == alphas.Dim());
379 }
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:59
void AppendCindexes ( int32  node,
const std::vector< Index > &  indexes,
std::vector< Cindex > *  out 
)

Appends to 'out' the pairs (node, indexes[0]), (node, indexes[1]), ...

Definition at line 1004 of file nnet-compile.cc.

References rnnlm::i.

Referenced by Compiler::OutputDebugInfo().

1005  {
1006  size_t indexes_size = indexes.size();
1007  if (indexes_size > out->size())
1008  out->reserve(out->size() + indexes_size);
1009  for (size_t i = 0; i < indexes_size; i++)
1010  out->push_back(Cindex(node, indexes[i]));
1011 }
std::pair< int32, Index > Cindex
Definition: nnet-common.h:100
bool kaldi::nnet3::AssertGraphEqual ( const std::vector< std::vector< int32 > > &  graph1,
const std::vector< std::vector< int32 > > &  graph2 
)

Definition at line 26 of file nnet-graph-test.cc.

References rnnlm::i, and rnnlm::j.

Referenced by UnitTestComputeGraphTranspose(), UnitTestFindSccs(), and UnitTestMakeSccGraph().

27  {
28  if (graph1.size() != graph2.size()) { return false; }
29  for (int32 i = 0; i < graph1.size(); ++i) {
30  if (graph1[i].size() != graph2[i].size()) { return false; }
31  for (int32 j = 0; j < graph1[i].size(); ++j) {
32  if (graph1[i][j] != graph2[i][j]) { return false; }
33  }
34  }
35  return true;
36 }
bool kaldi::nnet3::AssertVectorEqual ( const std::vector< int32 > &  vec1,
const std::vector< int32 > &  vec2 
)

Definition at line 38 of file nnet-graph-test.cc.

References rnnlm::i.

Referenced by UnitTestComputeTopSortOrder(), and UnitTestComputeTopSortOrder2().

39  {
40  if (vec1.size() != vec2.size()) { return false; }
41  for (int32 i = 0; i < vec1.size(); ++i) {
42  if (vec1[i] != vec2[i]) { return false; }
43  }
44  return true;
45 }
void kaldi::nnet3::BuildTestGraph ( std::vector< std::vector< int32 > > *  graph)

Definition at line 47 of file nnet-graph-test.cc.

References KALDI_ASSERT.

Referenced by UnitTestComputeGraphTranspose(), UnitTestFindSccs(), and UnitTestMakeSccGraph().

47  {
48  KALDI_ASSERT(graph != NULL);
49  graph->clear();
50  graph->resize(8);
51 
52  // We create the following graph for testing.
53  // 0 --> 4
54  // 1 --> 0
55  // 2 --> 1 3
56  // 3 --> 2
57  // 4 --> 1
58  // 5 --> 1 4 6
59  // 6 --> 5
60  // 7 --> 7 3 6
61  std::vector<int32> tmp;
62  tmp.resize(1); tmp[0] = 4; (*graph)[0] = tmp;
63  tmp.resize(1); tmp[0] = 0; (*graph)[1] = tmp;
64  tmp.resize(2); tmp[0] = 1; tmp[1] = 3; (*graph)[2] = tmp;
65  tmp.resize(1); tmp[0] = 2; (*graph)[3] = tmp;
66  tmp.resize(1); tmp[0] = 1; (*graph)[4] = tmp;
67  tmp.resize(3); tmp[0] = 1; tmp[1] = 4; tmp[2] = 6; (*graph)[5] = tmp;
68  tmp.resize(1); tmp[0] = 5; (*graph)[6] = tmp;
69  tmp.resize(3); tmp[0] = 7; tmp[1] = 3; tmp[2] = 6; (*graph)[7] = tmp;
70 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::BuildTestGraphTranspose ( std::vector< std::vector< int32 > > *  graph)

Definition at line 72 of file nnet-graph-test.cc.

References KALDI_ASSERT.

Referenced by UnitTestComputeGraphTranspose().

72  {
73  KALDI_ASSERT(graph != NULL);
74  graph->clear();
75  graph->resize(8);
76 
77  // We create the following graph for testing.
78  // 0 --> 1
79  // 1 --> 2 4 5
80  // 2 --> 3
81  // 3 --> 2 7
82  // 4 --> 0 5
83  // 5 --> 6
84  // 6 --> 5 7
85  // 7 --> 7
86  std::vector<int32> tmp;
87  tmp.resize(1); tmp[0] = 1; (*graph)[0] = tmp;
88  tmp.resize(3); tmp[0] = 2; tmp[1] = 4; tmp[2] = 5; (*graph)[1] = tmp;
89  tmp.resize(1); tmp[0] = 3; (*graph)[2] = tmp;
90  tmp.resize(2); tmp[0] = 2; tmp[1] = 7; (*graph)[3] = tmp;
91  tmp.resize(2); tmp[0] = 0; tmp[1] = 5; (*graph)[4] = tmp;
92  tmp.resize(1); tmp[0] = 6; (*graph)[5] = tmp;
93  tmp.resize(2); tmp[0] = 5; tmp[1] = 7; (*graph)[6] = tmp;
94  tmp.resize(1); tmp[0] = 7; (*graph)[7] = tmp;
95 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::BuildTestSccGraph ( std::vector< std::vector< int32 > > *  scc_graph)

Definition at line 114 of file nnet-graph-test.cc.

References KALDI_ASSERT.

Referenced by UnitTestComputeTopSortOrder(), and UnitTestMakeSccGraph().

114  {
115  KALDI_ASSERT(scc_graph != NULL);
116  scc_graph->clear();
117  scc_graph->resize(4);
118 
119  // We create the following SCC graph for testing.
120  // 0 -->
121  // 1 --> 0
122  // 2 --> 0
123  // 3 --> 1 2
124  std::vector<int32> tmp;
125  tmp.resize(0); (*scc_graph)[0] = tmp;
126  tmp.resize(1); tmp[0] = 0; (*scc_graph)[1] = tmp;
127  tmp.resize(1); tmp[0] = 0; (*scc_graph)[2] = tmp;
128  tmp.resize(2); tmp[0] = 1; tmp[1] = 2; (*scc_graph)[3] = tmp;
129 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::BuildTestSccs ( std::vector< std::vector< int32 > > *  sccs)

Definition at line 97 of file nnet-graph-test.cc.

References KALDI_ASSERT.

Referenced by UnitTestFindSccs(), and UnitTestMakeSccGraph().

97  {
98  KALDI_ASSERT(sccs != NULL);
99  sccs->clear();
100  sccs->resize(4);
101 
102  // We create the following SCCs for testing.
103  // 0 --> 1 4 0
104  // 1 --> 3 2
105  // 2 --> 6 5
106  // 3 --> 7
107  std::vector<int32> tmp;
108  tmp.resize(3); tmp[0] = 1; tmp[1] = 4; tmp[2] = 0; (*sccs)[0] = tmp;
109  tmp.resize(2); tmp[0] = 3; tmp[1] = 2; (*sccs)[1] = tmp;
110  tmp.resize(2); tmp[0] = 6; tmp[1] = 5; (*sccs)[2] = tmp;
111  tmp.resize(1); tmp[0] = 7; (*sccs)[3] = tmp;
112 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::BuildTestTopSortOrder ( std::vector< int32 > *  node_to_order)

Definition at line 131 of file nnet-graph-test.cc.

References KALDI_ASSERT.

Referenced by UnitTestComputeTopSortOrder().

131  {
132  KALDI_ASSERT(node_to_order != NULL);
133  node_to_order->clear();
134  node_to_order->resize(4);
135 
136  // The topological sorting order of the above SCC graph is as follows (from
137  // our particular algorithm):
138  // 0 --> 3
139  // 1 --> 2
140  // 2 --> 1
141  // 3 --> 0
142  (*node_to_order)[0] = 3;
143  (*node_to_order)[1] = 2;
144  (*node_to_order)[2] = 1;
145  (*node_to_order)[3] = 0;
146 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void CheckComputation ( const Nnet &  nnet,
const ComputationRequest &  request,
const NnetComputation &  computation,
bool  check_rewrite = false 
)

This is a convenience interface for class ComputationChecker.

Call it with check_rewrite = true only if the optimization is pre-optimization.

Definition at line 975 of file nnet-analyze.cc.

References ComputationChecker::Check(), and CheckComputationOptions::check_rewrite.

Referenced by Optimize().

978  {
979  CheckComputationOptions opts;
980  opts.check_rewrite = check_rewrite;
981  ComputationChecker checker(opts, nnet, computation);
982  checker.Check();
983 }
void ComponentDotProducts ( const Nnet &  nnet1,
const Nnet &  nnet2,
VectorBase< BaseFloat > *  dot_prod 
)

Returns dot products between two networks of the same structure (calls the DotProduct functions of the Updatable components and fill in the output vector).

Definition at line 188 of file nnet-utils.cc.

References VectorBase< Real >::Data(), VectorBase< Real >::Dim(), UpdatableComponent::DotProduct(), Nnet::GetComponent(), KALDI_ASSERT, kUpdatableComponent, Nnet::NumComponents(), and Component::Properties().

Referenced by main().

190  {
191  KALDI_ASSERT(nnet1.NumComponents() == nnet2.NumComponents());
192  int32 updatable_c = 0;
193  for (int32 c = 0; c < nnet1.NumComponents(); c++) {
194  const Component *comp1 = nnet1.GetComponent(c),
195  *comp2 = nnet2.GetComponent(c);
196  if (comp1->Properties() & kUpdatableComponent) {
197  const UpdatableComponent
198  *u_comp1 = dynamic_cast<const UpdatableComponent*>(comp1),
199  *u_comp2 = dynamic_cast<const UpdatableComponent*>(comp2);
200  KALDI_ASSERT(u_comp1 != NULL && u_comp2 != NULL);
201  dot_prod->Data()[updatable_c] = u_comp1->DotProduct(*u_comp2);
202  updatable_c++;
203  }
204  }
205  KALDI_ASSERT(updatable_c == dot_prod->Dim());
206 }
Real * Data()
Returns a pointer to the start of the vector's data.
Definition: kaldi-vector.h:65
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:59
void ComputeAccuracy ( const GeneralMatrix &  supervision,
const CuMatrixBase< BaseFloat > &  nnet_output,
BaseFloat *  tot_weight,
BaseFloat *  tot_accuracy 
)

This function computes the frame accuracy for this minibatch.

It interprets the supervision information in "supervision" as labels or soft labels; it picks the maximum element in each row and treats that as the label for purposes of computing the accuracy (in situations where you would care about the accuracy, there will normally be just one nonzero label). The hypothesized labels are computed by taking the neural net output (supplied as a CuMatrix), and finding the maximum element in each row. See also the function ComputeObjectiveFunction, declared in nnet-training.h.

Parameters
[in]supervisionThe supervision information (no elements may be negative); only the maximum in each row matters (although we expect that usually there will be just one nonzero element in each row); and the sum of each row is interpreted as a weighting factor (although we expect that this sum will usually be one).
[in]nnet_outputThe neural net output must have the same dimensions as the supervision. Only the index of the maximum value in each row matters. Ties will be broken in an unspecified way.
[out]tot_weightThe sum of the values in the supervision matrix
[out]tot_accuracyThe total accuracy, equal to the sum over all row indexes r such that the maximum column index of row r of supervision and nnet_output is the same, of the sum of the r'th row of supervision (i.e. the row's weight).

Definition at line 156 of file nnet-diagnostics.cc.

References CuMatrixBase< Real >::FindRowMaxId(), GeneralMatrix::GetFullMatrix(), GeneralMatrix::GetMatrix(), GeneralMatrix::GetSparseMatrix(), KALDI_ASSERT, KALDI_ERR, kaldi::kCompressedMatrix, kaldi::kFullMatrix, kaldi::kSparseMatrix, SparseVector< Real >::Max(), VectorBase< Real >::Max(), CuMatrixBase< Real >::NumCols(), GeneralMatrix::NumCols(), CuMatrixBase< Real >::NumRows(), GeneralMatrix::NumRows(), SparseMatrix< Real >::Row(), SparseVector< Real >::Sum(), VectorBase< Real >::Sum(), and GeneralMatrix::Type().

Referenced by NnetComputeProb::ProcessOutputs().

159  {
160  int32 num_rows = nnet_output.NumRows(),
161  num_cols = nnet_output.NumCols();
162  KALDI_ASSERT(supervision.NumRows() == num_rows &&
163  supervision.NumCols() == num_cols);
164 
165  CuArray<int32> best_index(num_rows);
166  nnet_output.FindRowMaxId(&best_index);
167  std::vector<int32> best_index_cpu;
168  // wasteful copy, but doesn't dominate.
169  best_index.CopyToVec(&best_index_cpu);
170 
171 
172  double tot_weight = 0.0,
173  tot_accuracy = 0.0;
174 
175  // note: we expect that in most cases where this code is called,
176  // supervision.Type() will be kSparseMatrix.
177  switch (supervision.Type()) {
178  case kCompressedMatrix: {
179  Matrix<BaseFloat> mat;
180  supervision.GetMatrix(&mat);
181  for (int32 r = 0; r < num_rows; r++) {
182  SubVector<BaseFloat> vec(mat, r);
183  BaseFloat row_sum = vec.Sum();
184  KALDI_ASSERT(row_sum >= 0.0);
185  int32 best_index;
186  vec.Max(&best_index); // discard max value.
187  tot_weight += row_sum;
188  if (best_index == best_index_cpu[r])
189  tot_accuracy += row_sum;
190  }
191  break;
192 
193  }
194  case kFullMatrix: {
195  const Matrix<BaseFloat> &mat = supervision.GetFullMatrix();
196  for (int32 r = 0; r < num_rows; r++) {
197  SubVector<BaseFloat> vec(mat, r);
198  BaseFloat row_sum = vec.Sum();
199  KALDI_ASSERT(row_sum >= 0.0);
200  int32 best_index;
201  vec.Max(&best_index); // discard max value.
202  tot_weight += row_sum;
203  if (best_index == best_index_cpu[r])
204  tot_accuracy += row_sum;
205  }
206  break;
207  }
208  case kSparseMatrix: {
209  const SparseMatrix<BaseFloat> &smat = supervision.GetSparseMatrix();
210  for (int32 r = 0; r < num_rows; r++) {
211  const SparseVector<BaseFloat> &row = smat.Row(r);
212  BaseFloat row_sum = row.Sum();
213  int32 best_index;
214  row.Max(&best_index);
215  KALDI_ASSERT(best_index < num_cols);
216  tot_weight += row_sum;
217  if (best_index == best_index_cpu[r])
218  tot_accuracy += row_sum;
219  }
220  break;
221  }
222  default: KALDI_ERR << "Bad general-matrix type.";
223  }
224  *tot_weight_out = tot_weight;
225  *tot_accuracy_out = tot_accuracy;
226 }
void FindRowMaxId(CuArray< int32 > *id) const
Find the id of the maximal element for each row.
Definition: cu-matrix.cc:1611
MatrixIndexT NumCols() const
Definition: cu-matrix.h:201
float BaseFloat
Definition: kaldi-types.h:29
MatrixIndexT NumRows() const
Dimensions.
Definition: cu-matrix.h:200
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeCommandAttributes ( const Nnet &  nnet,
const NnetComputation &  computation,
const ComputationVariables &  vars,
std::vector< CommandAttributes > *  attributes 
)

Definition at line 267 of file nnet-analyze.cc.

References ComputationVariables::AppendVariablesForMatrix(), NnetComputation::Command::arg1, NnetComputation::Command::arg2, NnetComputation::Command::arg3, NnetComputation::Command::arg4, NnetComputation::Command::arg5, NnetComputation::Command::arg6, NnetComputation::Command::command_type, NnetComputation::commands, count, Nnet::GetComponent(), CommandAttributes::has_side_effects, rnnlm::i, NnetComputation::indexes, NnetComputation::indexes_multi, IndexesMultiToSubmatrixIndexes(), kAddRowRanges, kAddRows, kAddRowsMulti, kAddToRowsMulti, KALDI_ERR, kAllocMatrixFromOther, kAllocMatrixFromOtherZeroed, kAllocMatrixUndefined, kAllocMatrixZeroed, kBackprop, kBackpropAdds, kBackpropNoModelUpdate, kCopyRows, kCopyRowsMulti, kCopyToRowsMulti, kDeallocMatrix, kMatrixAdd, kMatrixCopy, kNoOperation, kNoOperationMarker, kPropagate, kPropagateAdds, kReadAccess, kReadWriteAccess, kStoreStats, kUpdatableComponent, kWriteAccess, CommandAttributes::matrices_read, CommandAttributes::matrices_written, Component::Properties(), ComputationVariables::RecordAccessForSubmatrix(), kaldi::SortAndUniq(), CommandAttributes::submatrices_read, CommandAttributes::submatrices_written, CommandAttributes::variables_read, and CommandAttributes::variables_written.

Referenced by Analyzer::Init(), MoveSizingCommands(), and NnetComputer::NnetComputer().

271  {
272  int32 num_commands = computation.commands.size();
273  attributes->clear();
274  attributes->resize(num_commands);
275  for (int32 command_index = 0; command_index < num_commands; command_index++) {
276  const NnetComputation::Command &c = computation.commands[command_index];
277  CommandAttributes &attr = (*attributes)[command_index];
278  switch (c.command_type) {
279  case kAllocMatrixZeroed:
281  vars.AppendVariablesForMatrix(c.arg1, &attr.variables_written);
282  attr.matrices_written.push_back(c.arg1);
283  break;
284  case kAllocMatrixUndefined: // nothing is written here.
285  case kDeallocMatrix: // ditto.
286  case kAllocMatrixFromOther: // ditto.
287  break;
288  case kPropagate:
289  vars.RecordAccessForSubmatrix(c.arg3, kReadAccess, &attr);
290  if (nnet.GetComponent(c.arg1)->Properties() & kPropagateAdds)
291  vars.RecordAccessForSubmatrix(c.arg4, kReadWriteAccess, &attr);
292  else
293  vars.RecordAccessForSubmatrix(c.arg4, kWriteAccess, &attr);
294  break;
295  case kStoreStats:
296  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
297  break;
298  case kBackprop:
300  vars.RecordAccessForSubmatrix(c.arg3, kReadAccess, &attr);
301  vars.RecordAccessForSubmatrix(c.arg4, kReadAccess, &attr);
302  vars.RecordAccessForSubmatrix(c.arg5, kReadAccess, &attr);
303  if (nnet.GetComponent(c.arg1)->Properties() & kBackpropAdds)
304  vars.RecordAccessForSubmatrix(c.arg6, kReadWriteAccess, &attr);
305  else
306  vars.RecordAccessForSubmatrix(c.arg6, kWriteAccess, &attr);
307  if (c.command_type == kBackprop &&
308  nnet.GetComponent(c.arg1)->Properties() & kUpdatableComponent)
309  attr.has_side_effects = true;
310  break;
311  case kMatrixCopy:
312  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
313  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
314  break;
315  case kMatrixAdd:
316  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
317  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
318  break;
319  case kAddRows:
320  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
321  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
322  break;
323  case kCopyRows: {
324  const std::vector<int32> &indexes = computation.indexes[c.arg3];
325  // if there are -1's in "indexes", then the result of the operation
326  // will depend on the initial value of the matrix, so it's
327  // a "rw" operation, not a "write" operation.
328  if (std::count(indexes.begin(), indexes.end(), -1) > 0)
329  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
330  else
331  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
332  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
333  break;
334  }
335  case kAddRowsMulti: {
336  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
337  std::vector<int32> submatrix_indexes;
338  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
339  &submatrix_indexes);
340  for (size_t i = 0; i < submatrix_indexes.size(); i++)
341  vars.RecordAccessForSubmatrix(submatrix_indexes[i],
342  kReadAccess, &attr);
343  break;
344  }
345  case kCopyRowsMulti: {
346  std::vector<int32> submatrix_indexes;
347  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
348  &submatrix_indexes);
349  // note: the CopyRows command assigns zero in cases where
350  // there is no source for some row
351  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
352  for (size_t i = 0; i < submatrix_indexes.size(); i++)
353  vars.RecordAccessForSubmatrix(submatrix_indexes[i],
354  kReadAccess, &attr);
355  break;
356  }
357  case kAddToRowsMulti:
358  case kCopyToRowsMulti: {
359  vars.RecordAccessForSubmatrix(c.arg1, kReadAccess, &attr);
360  // if the submatrixes we're writing to (in kCopyToRowsMulti) had all
361  // rows covered, it would be a pure write operation.
362  std::vector<int32> submatrix_indexes;
363  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
364  &submatrix_indexes);
365  for (size_t i = 0; i < submatrix_indexes.size(); i++)
366  vars.RecordAccessForSubmatrix(submatrix_indexes[i], kReadWriteAccess,
367  &attr);
368  break;
369  }
370  case kAddRowRanges: {
371  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
372  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
373  break;
374  }
375  case kNoOperation:
376  case kNoOperationMarker:
377  break;
378  default:
379  KALDI_ERR << "Unknown command type.";
380  }
381  SortAndUniq(&attr.variables_read);
382  SortAndUniq(&attr.variables_written);
383  SortAndUniq(&attr.submatrices_read);
384  SortAndUniq(&attr.submatrices_written);
385  SortAndUniq(&attr.matrices_read);
386  SortAndUniq(&attr.matrices_written);
387  }
388 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:51
static void IndexesMultiToSubmatrixIndexes(const std::vector< std::pair< int32, int32 > > &indexes_multi, std::vector< int32 > *submatrix_indexes)
given a vector of pairs from computation.indexes_multi_indexes containing paris (submatrix-index, row-index), this function outputs to "submatrix_indexes" all (unique) submatrix indexes that appear; and it outputs to "contains_null_marker" true if the pair (-1, -1) appears anywhere in indexes_multi, and false otherwise.
const size_t count
#define KALDI_ERR
Definition: kaldi-error.h:127
static void kaldi::nnet3::ComputeCommandPairs ( const std::pair< std::vector< int32 >, std::vector< int32 > > &  lists,
std::vector< std::pair< int32, int32 > > *  pairs 
)
static

Definition at line 235 of file nnet-optimize.cc.

References kaldi::CopyVectorToSet(), rnnlm::d, and KALDI_PARANOID_ASSERT.

Referenced by RemoveUnnecessaryAllocation().

237  {
238  std::vector<int32> d_list = lists.first;
239 
240  std::set<int32> a_set;
241  CopyVectorToSet(lists.second, &a_set);
242 
243  std::vector<int32>::reverse_iterator iter = d_list.rbegin(),
244  end = d_list.rend();
245 
246  // from the latest to the earliest deallocation command...
247  for (; iter != end; ++iter) {
248  int32 d = *iter;
249  std::set<int32>::iterator a_iter = a_set.upper_bound(d);
250  // a_iter is an iterator to the first element a of the set 'a_set' such
251  // that a > d, or a_set.end() if no such element exists.
252  if (a_iter == a_set.end())
253  continue; // we will output no pair for this d.
254  int32 a = *a_iter;
255  KALDI_PARANOID_ASSERT(a > d); // or code error
256  a_set.erase(a_iter); // remove this a from 'a_set' so it doesn't get used
257  // twice
258  pairs->push_back(std::pair<int32,int32>(d, a));
259  }
260 }
void CopyVectorToSet(const std::vector< A > &v, std::set< A > *s)
Copies the contents of a vector to a set.
Definition: stl-utils.h:186
#define KALDI_PARANOID_ASSERT(cond)
Definition: kaldi-error.h:182
void kaldi::nnet3::ComputeComputationGraph ( const Nnet &  nnet,
const ComputationRequest &  request,
ComputationGraph *  graph 
)

Definition at line 1076 of file nnet-computation-graph.cc.

References kaldi::nnet3::computation_graph::AddInputToGraph(), kaldi::nnet3::computation_graph::AddOutputToGraph(), ComputationGraph::cindexes, NetworkNode::component_index, ComputationGraph::dependencies, NetworkNode::descriptor, ComputationGraph::GetCindexId(), Nnet::GetComponent(), Descriptor::GetDependencies(), Component::GetInputIndexes(), Nnet::GetNode(), rnnlm::i, ComputationGraph::is_input, KALDI_ASSERT, KALDI_ERR, kComponent, kDescriptor, kDimRange, kInput, ComputationRequest::misc_info, rnnlm::n, NetworkNode::node_index, NetworkNode::node_type, kaldi::SortAndUniq(), and NetworkNode::u.

1078  {
1079  using namespace computation_graph;
1080  // make sure graph is empty at the start.
1081  KALDI_ASSERT(graph->cindexes.empty());
1082 
1083  AddInputToGraph(request, nnet, graph);
1084  AddOutputToGraph(request, nnet, graph);
1085 
1086  // queue of cindex_ids to process.
1087  std::vector<int32> queue(graph->cindexes.size());
1088  for (int32 i = 0; i < graph->cindexes.size(); i++)
1089  queue.push_back(i);
1090 
1091  while (!queue.empty()) {
1092  int32 cindex_id = queue.back();
1093  queue.pop_back();
1094  if (static_cast<int32>(graph->dependencies.size()) <= cindex_id)
1095  graph->dependencies.resize(cindex_id + 1);
1096 
1097  if (graph->is_input[cindex_id])
1098  continue;
1099  Cindex cindex = graph->cindexes[cindex_id];
1100 
1101  // find the dependencies of this cindex.
1102  int32 n = cindex.first;
1103  const Index &index = cindex.second;
1104  const NetworkNode &node = nnet.GetNode(n);
1105 
1106  std::vector<Cindex> input_cindexes;
1107 
1108  // the following switch statement sets up "input_cindexes".
1109  switch (node.node_type) {
1110  case kDescriptor: {
1111  // desc describes how this node obtains its input from other nodes.
1112  const Descriptor &desc = node.descriptor;
1113  desc.GetDependencies(index, &input_cindexes);
1114  break;
1115  }
1116  case kComponent: {
1117  int32 c = node.u.component_index;
1118  const Component *component = nnet.GetComponent(c);
1119  std::vector<Index> input_indexes;
1120  component->GetInputIndexes(request.misc_info, index,
1121  &input_indexes);
1122  // each Component node should be preceded by a node that describes its
1123  // input, of type kDescriptor
1124  KALDI_ASSERT(nnet.GetNode(n-1).node_type ==
1125  kDescriptor);
1126 
1127  input_cindexes.resize(input_indexes.size());
1128  for (size_t i = 0; i < input_indexes.size(); i++) {
1129  input_cindexes[i].first = n - 1; // preceding node.
1130  input_cindexes[i].second = input_indexes[i];
1131  }
1132  break;
1133  }
1134  case kDimRange: {
1135  input_cindexes.resize(1);
1136  input_cindexes[0] = Cindex(node.u.node_index, index);
1137  break;
1138  }
1139  case kInput: default:
1140  // for kInput, you should have hit the "continue" statement above.
1141  KALDI_ERR << "Invalid node type";
1142  }
1143  std::vector<int32> &this_dep = graph->dependencies[cindex_id];
1144 
1145  int32 num_dependencies = input_cindexes.size();
1146  this_dep.resize(num_dependencies);
1147  for (size_t i = 0; i < num_dependencies; i++) {
1148  bool is_input = false, is_new;
1149  int32 dep_cindex_id = graph->GetCindexId(input_cindexes[i],
1150  is_input, &is_new);
1151  this_dep[i] = dep_cindex_id;
1152  if (is_new)
1153  queue.push_back(dep_cindex_id);
1154  }
1155 
1156  // remove duplicates of dependencies.
1157  SortAndUniq(&this_dep);
1158  }
1159 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:51
void AddInputToGraph(const ComputationRequest &request, const Nnet &nnet, ComputationGraph *graph)
std::pair< int32, Index > Cindex
Definition: nnet-common.h:100
void AddOutputToGraph(const ComputationRequest &request, const Nnet &nnet, ComputationGraph *graph)
struct rnnlm::@11::@12 n
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeComputationPhases ( const Nnet &  nnet,
const ComputationGraph &  computation_graph,
std::vector< std::vector< int32 > > *  phases 
)

This function divides a computation into 'phases', where a 'phase' is a collection of cindexes which can (as far as the computation graph is concerned) all be computed at the same time, and depend only on cindexes previously computed in earlier phases.

So the phases are an ordering of the Cindexes in the computation, but an ordering that depends on graph-theoretic considerations only, and not practical concerns like whether the cindexes belong to the same node [for that, see the notion of steps].

Parameters
[in]nnetThe neural network this computation is for
[in]graphThe computation graph that we're computing phases for.
[out]phasesThe phases. Suppose the computation can be completed in 20 phases, then phases->size() will be 20 at exit, and (*phases)[0] will be a sorted list of cindex_ids. that belong to the first phase, and so on. (Remember, a cindex_id is an index into graph->cindexes; it compactly identifies a cindex.) The sets represented by the elements of 'phases' will be disjoint and will cover all elements in [0 .. computation.cindexes.size() - 1].

This function will be crash if the computation cannot actualy be computed. Note: we assume you have called PruneComputationGraph() before this function.

Definition at line 1321 of file nnet-computation-graph.cc.

References ComputationGraph::cindexes, ComputeComputationPhasesForEpoch(), kaldi::nnet3::computation_graph::ComputeDependenciesSubset(), kaldi::nnet3::computation_graph::ComputeEpochInfo(), ComputeGraphTranspose(), KALDI_ASSERT, and SumVectorSizes().

Referenced by Compiler::CreateComputation().

1324  {
1325  using namespace computation_graph;
1326  int32 num_cindex_ids = graph.cindexes.size();
1327 
1328  std::vector<int32> cindex_id_to_epoch;
1329  std::vector<std::vector<int32 > > epochs;
1330  std::vector<bool> epoch_is_trivial;
1331  ComputeEpochInfo(nnet, graph, &cindex_id_to_epoch,
1332  &epochs, &epoch_is_trivial);
1333 
1334  KALDI_ASSERT(SumVectorSizes(epochs) == num_cindex_ids);
1335 
1336  // dependencies_subset contains just the subset of dependencies
1337  // of each cindex_id, that have the same epoch index as
1338  // cindex_id itself. This will be used to correctly order
1339  // cindexes within a certain epoch (relevant for things like
1340  // LSTMs).
1341  std::vector<std::vector<int32> > dependencies_subset;
1342  ComputeDependenciesSubset(graph, cindex_id_to_epoch,
1343  &dependencies_subset);
1344 
1345  // depend_on_subset is a subset of the normal "depend_on" list (i.e. a list of
1346  // all cindex_ids that depend on the current cindex_id), limited to just those
1347  // cindex_ids that have the same epoch index.
1348  std::vector<std::vector<int32> > depend_on_subset;
1349  ComputeGraphTranspose(dependencies_subset, &depend_on_subset);
1350 
1351  int32 num_epoch_indexes = epoch_is_trivial.size();
1352 
1353  // "phase_indexes" is used inside ComputeComputationPhasesForEpoch.
1354  std::vector<int32> phase_indexes(num_cindex_ids, -1);
1355 
1356  if (phases) {
1357  phases->clear();
1358  phases->reserve(50); // minimize unnecessary copies. 50 is very
1359  // arbitrarily chosen.
1360  }
1361 
1362  for (int32 epoch = 0;
1363  epoch < num_epoch_indexes;
1364  epoch++)
1366  epochs[epoch],
1367  dependencies_subset,
1368  depend_on_subset,
1369  epoch_is_trivial[epoch],
1370  &phase_indexes, phases);
1371 
1372 
1373  // make sure everything was computable. If the next assert fails it's likely
1374  // a bug in this function or in PruneComputataionGraph.
1375  KALDI_ASSERT(SumVectorSizes(*phases) == num_cindex_ids);
1376 }
static void ComputeDependenciesSubset(const ComputationGraph &graph, const std::vector< int32 > &cindex_id_to_epoch, std::vector< std::vector< int32 > > *dependencies_subset)
This function outputs to dependencies_subset[c], for each cindex_id c, the subset of elements d of gr...
void ComputeGraphTranspose(const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *graph_transpose)
Outputs a graph in which the order of arcs is reversed.
Definition: nnet-graph.cc:63
static int32 SumVectorSizes(const std::vector< std::vector< int32 > > &vec)
static void ComputeComputationPhasesForEpoch(const Nnet &nnet, const ComputationGraph &graph, const std::vector< int32 > &this_epoch, const std::vector< std::vector< int32 > > &dependencies_subset, const std::vector< std::vector< int32 > > &depend_on_subset, bool epoch_is_trivial, std::vector< int32 > *phase_indexes, std::vector< std::vector< int32 > > *phases)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void ComputeEpochInfo(const Nnet &nnet, const ComputationGraph &graph, std::vector< int32 > *cindex_id_to_epoch, std::vector< std::vector< int32 > > *epochs, std::vector< bool > *epoch_is_trivial)
This function computes certain information about "epochs" of cindex_ids.
static void kaldi::nnet3::ComputeComputationPhasesForEpoch ( const Nnet &  nnet,
const ComputationGraph &  graph,
const std::vector< int32 > &  this_epoch,
const std::vector< std::vector< int32 > > &  dependencies_subset,
const std::vector< std::vector< int32 > > &  depend_on_subset,
bool  epoch_is_trivial,
std::vector< int32 > *  phase_indexes,
std::vector< std::vector< int32 > > *  phases 
)
inlinestatic

Definition at line 1222 of file nnet-computation-graph.cc.

References rnnlm::d, KALDI_ASSERT, KALDI_ERR, and kaldi::SortAndUniq().

Referenced by ComputeComputationPhases().

1230  {
1231  std::vector<int32> this_phase, next_phase_candidates;
1232 
1233  if (this_epoch.empty())
1234  return;
1235 
1236  if (epoch_is_trivial) { // an optimization
1237  this_phase = this_epoch;
1238  } else {
1239  // Start out with all elements of this epoch that have no
1240  // dependencies within the same epoch (i.e. those that
1241  // can be computed first).
1242  std::vector<int32>::const_iterator iter = this_epoch.begin(),
1243  end = this_epoch.end();
1244  for (; iter != end; ++iter) {
1245  int32 cindex_id = *iter;
1246  if (dependencies_subset[cindex_id].empty())
1247  this_phase.push_back(cindex_id);
1248  }
1249  }
1250 
1251  // if the next assert fails, the graph at the level of cindex_ids is not acyclic.
1252  KALDI_ASSERT(!this_phase.empty() &&
1253  "Trying to process computation with cycles");
1254 
1255  while (!this_phase.empty()) {
1256  // The next two lines are a more efficient version of:
1257  // phases->push_back(this_phase);
1258  phases->resize(phases->size() + 1);
1259  phases->back().swap(this_phase);
1260  // The next if-statement is an optimization: if for this epoch index
1261  // there is just one node, we can skip the rest of this loop. Note: if
1262  // epoch == 0, even if there is just one node, cindex_ids from
1263  // multiple nodes may be put here because of the rule that cindex_ids which
1264  // are inputs always get epoch 0. But it's still true that they
1265  // will have no dependencies, so we can still skip the code below.
1266  if (epoch_is_trivial)
1267  return;
1268 
1269  int32 cur_phase_index = phases->size() - 1;
1270 
1271  // next_phases_candidates is a list of cindexes that we should check
1272  // whether they are computable now, because one of the things they depend
1273  // on just became computable.
1274  next_phase_candidates.clear();
1275  std::vector<int32>::const_iterator this_phase_iter = phases->back().begin(),
1276  this_phase_end = phases->back().end();
1277 
1278  for (; this_phase_iter != this_phase_end; ++this_phase_iter) {
1279  int32 c = *this_phase_iter; // c is a cindex_id with phase cur_phase_index.
1280  (*phase_indexes)[c] = cur_phase_index;
1281  std::vector<int32>::const_iterator iter = depend_on_subset[c].begin(),
1282  end = depend_on_subset[c].end();
1283  for (; iter != end; ++iter) {
1284  int32 d = *iter; // cindex_id that depends on c.
1285  next_phase_candidates.push_back(d);
1286  }
1287  }
1288  SortAndUniq(&next_phase_candidates);
1289  // note, at this point 'this_phase' will be the empty vector [see the 'swap'
1290  // above].
1291  this_phase.reserve(next_phase_candidates.size());
1292  // now check the candidates that might be in the next phase, and put any
1293  // members that we are currently able to compute into "this_phase".
1294  std::vector<int32>::const_iterator iter = next_phase_candidates.begin(),
1295  end = next_phase_candidates.end();
1296  for (; iter != end; ++iter) {
1297  int32 c = *iter;
1298  std::vector<int32>::const_iterator
1299  dep_iter = dependencies_subset[c].begin(),
1300  dep_end = dependencies_subset[c].end();
1301  for (; dep_iter != dep_end; ++dep_iter) {
1302  int32 d = *dep_iter; // d is cindex_id that c depends on.
1303  if ((*phase_indexes)[d] < 0) // we can't compute c yet because something we depend
1304  break; // on has not yet been computed.
1305  }
1306  if (dep_iter == dep_end) {
1307  // we reached the end and did not break -> all dependencies satisfied
1308  this_phase.push_back(c);
1309  }
1310  }
1311  if (!next_phase_candidates.empty() && this_phase.empty()) {
1312  // this should have been caught earlier so likely a code error rather than
1313  // a problem with user input.
1314  KALDI_ERR << "Your model has a type of recurrence that cannot be computed. "
1315  << "E.g. if x[t] depends on both x[t+1] and x[t-1]... no order "
1316  << "of computation will work.";
1317  }
1318  }
1319 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:51
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeComputationSteps ( const Nnet &  nnet,
const ComputationRequest &  request,
const std::vector< std::vector< int32 > > &  phases,
ComputationGraph *  computation_graph,
std::vector< std::vector< int32 > > *  steps 
)

This function arranges the cindex_ids of the computation into a sequence of lists called "steps", which will correspond roughly to the commands in the compiled computation.

The steps are finer than phases. (See Organizing the computation into steps for more info). To summarize the properties that these steps will satisfy:

  • All cindex_ids within a given step correspond to the same node in the graph
  • All dependencies of cindex_ids within a given step have been computed in earlier steps.

There are also some extra, more obscure properties that the sequence of steps must satisfy:

  • Any input or output in the ComputationRequest must be in one step, with the Indexes in the same order as specified in the ComputationRequest. (Note: inputs can be for nodes of type kComponent as well as kInput).
  • If a step corresponds to a node of type kComponent (and does not correspond to an input in the ComputationRequest), then the immediately preceding step must correspond to a node of type kDescriptor, and the sequence of Indexes in the two steps must be identical.
  • If a step corresponds to a node of type kDimRange, then there must be another step corresponding to the source node, with exactly the same Indexes appearing in the same order. (This lets us use a sub-matrix for the kDimRange node).

The reason why computation_graph is not provided as a const argument is that in order to ensure the final property we may have to add a few new cindex_ids.

Definition at line 1831 of file nnet-computation-graph.cc.

References kaldi::nnet3::compute_computation_steps::AddComponentInputSteps(), kaldi::nnet3::compute_computation_steps::AddComponentSteps(), kaldi::nnet3::compute_computation_steps::AddDimRangeSteps(), kaldi::nnet3::compute_computation_steps::AddInputSteps(), kaldi::nnet3::compute_computation_steps::AddOutputSteps(), ComputationGraph::cindexes, rnnlm::i, KALDI_ASSERT, and kaldi::nnet3::compute_computation_steps::ReorderIndexes().

Referenced by Compiler::CreateComputation().

1836  {
1837  using namespace compute_computation_steps;
1838  steps->clear();
1839  AddInputSteps(nnet, request, *graph, steps);
1840  {
1841  std::vector<std::vector<int32> > component_steps;
1842  AddComponentSteps(nnet, *graph, phases, &component_steps);
1843  AddComponentInputSteps(*graph, &component_steps, steps);
1844  }
1845  // output steps don't get reordered so we do the reordering before adding
1846  // them.
1847  ReorderIndexes(nnet, request, *graph, steps);
1848  AddDimRangeSteps(nnet, graph, steps);
1849  AddOutputSteps(nnet, request, *graph, steps);
1850 
1851  int32 num_cindexes = 0;
1852  for (int32 i = 0; i < steps->size(); i++)
1853  num_cindexes += (*steps)[i].size();
1854  // The next line has ">=" not "==" because it is possible (although unlikely
1855  // in normal setups) that some cindexes of Descriptors which are at the inputs
1856  // of Components,
1857  KALDI_ASSERT(num_cindexes >= graph->cindexes.size());
1858 }
static void AddDimRangeSteps(const Nnet &nnet, ComputationGraph *graph, std::vector< std::vector< int32 > > *all_steps)
This function inserts into "all_steps", which at this point should contain all but the output steps...
static void AddComponentSteps(const Nnet &nnet, const ComputationGraph &graph, const std::vector< std::vector< int32 > > &phases, std::vector< std::vector< int32 > > *component_steps)
Outputs into component_steps, steps corresponding to all Cindexes that correspond to Component nodes ...
void AddOutputSteps(const Nnet &nnet, const ComputationRequest &request, const ComputationGraph &graph, std::vector< std::vector< int32 > > *steps)
Adds a "step" for each of the outputs in the ComputationRequest.
int32 AddInputSteps(const Nnet &nnet, const ComputationRequest &request, const ComputationGraph &graph, std::vector< std::vector< int32 > > *steps)
Adds a "step" for each of the inputs in the ComputationRequest.
static void AddComponentInputSteps(const ComputationGraph &graph, std::vector< std::vector< int32 > > *component_steps, std::vector< std::vector< int32 > > *all_steps)
You call this function after calling AddInputSteps to add steps for inputs to "all_steps", then calling AddComponentSteps to output steps for components to "component_steps".
void ReorderIndexes(const Nnet &nnet, const ComputationRequest &request, const ComputationGraph &graph, std::vector< std::vector< int32 > > *steps)
This function would not be necessary if we had not added the ReorderIndexes function to class Compone...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeExampleComputationRequestSimple ( const Nnet &  nnet,
ComputationRequest *  request,
std::vector< Matrix< BaseFloat > > *  inputs 
)

This function computes an example computation request, for testing purposes.

The "Simple" in the name means that it currently only supports neural nets that satisfy IsSimple(nnet) (defined in nnet-utils.h). If there are 2 inputs, the "input" will be first, followed by "ivector".

In order to expand the range of things you can test with this, we guarantee that there will always be at least 3 successive frames of input available.

Definition at line 1042 of file nnet-test-utils.cc.

References ComputeSimpleNnetContext(), Nnet::InputDim(), ComputationRequest::inputs, IsSimpleNnet(), KALDI_ASSERT, rnnlm::n, ComputationRequest::need_model_derivative, ComputationRequest::outputs, kaldi::Rand(), and ComputationRequest::store_component_stats.

Referenced by UnitTestNnetAnalyze(), UnitTestNnetCompile(), UnitTestNnetCompute(), UnitTestNnetInputDerivatives(), UnitTestNnetModelDerivatives(), and UnitTestNnetOptimizeWithOptions().

1045  {
1046  KALDI_ASSERT(IsSimpleNnet(nnet));
1047 
1048  int32 left_context, right_context;
1049  ComputeSimpleNnetContext(nnet, &left_context, &right_context);
1050 
1051  int32 num_output_frames = 1 + Rand() % 10,
1052  output_start_frame = Rand() % 10,
1053  num_examples = 1 + Rand() % 10,
1054  output_end_frame = output_start_frame + num_output_frames,
1055  input_start_frame = output_start_frame - left_context - (Rand() % 3),
1056  input_end_frame = output_end_frame + right_context + (Rand() % 3),
1057  n_offset = Rand() % 2;
1058  bool need_deriv = (Rand() % 2 == 0);
1059  // make sure there are at least 3 frames of input available. this makes a
1060  // difference for our tests of statistics-pooling and statistics-extraction
1061  // component.
1062  if (input_end_frame < input_start_frame + 3)
1063  input_end_frame = input_start_frame + 3;
1064 
1065  request->inputs.clear();
1066  request->outputs.clear();
1067  inputs->clear();
1068 
1069  std::vector<Index> input_indexes, ivector_indexes, output_indexes;
1070  for (int32 n = n_offset; n < n_offset + num_examples; n++) {
1071  for (int32 t = input_start_frame; t < input_end_frame; t++)
1072  input_indexes.push_back(Index(n, t, 0));
1073  for (int32 t = output_start_frame; t < output_end_frame; t++)
1074  output_indexes.push_back(Index(n, t, 0));
1075  ivector_indexes.push_back(Index(n, 0, 0));
1076  }
1077  request->outputs.push_back(IoSpecification("output", output_indexes));
1078  if (need_deriv || (Rand() % 3 == 0))
1079  request->outputs.back().has_deriv = true;
1080  request->inputs.push_back(IoSpecification("input", input_indexes));
1081  if (need_deriv && (Rand() % 2 == 0))
1082  request->inputs.back().has_deriv = true;
1083  int32 input_dim = nnet.InputDim("input");
1084  KALDI_ASSERT(input_dim > 0);
1085  inputs->push_back(
1086  Matrix<BaseFloat>((input_end_frame - input_start_frame) * num_examples,
1087  input_dim));
1088  inputs->back().SetRandn();
1089  int32 ivector_dim = nnet.InputDim("ivector"); // may not exist.
1090  if (ivector_dim != -1) {
1091  request->inputs.push_back(IoSpecification("ivector", ivector_indexes));
1092  inputs->push_back(Matrix<BaseFloat>(num_examples, ivector_dim));
1093  inputs->back().SetRandn();
1094  if (need_deriv && (Rand() % 2 == 0))
1095  request->inputs.back().has_deriv = true;
1096  }
1097  if (Rand() % 2 == 0)
1098  request->need_model_derivative = need_deriv;
1099  if (Rand() % 2 == 0)
1100  request->store_component_stats = true;
1101 }
void ComputeSimpleNnetContext(const Nnet &nnet, int32 *left_context, int32 *right_context)
ComputeNnetContext computes the left-context and right-context of a nnet.
Definition: nnet-utils.cc:131
struct rnnlm::@11::@12 n
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
bool IsSimpleNnet(const Nnet &nnet)
This function returns true if the nnet has the following properties: It has an called "output" (other...
Definition: nnet-utils.cc:46
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeGraphTranspose ( const std::vector< std::vector< int32 > > &  graph,
std::vector< std::vector< int32 > > *  graph_transpose 
)

Outputs a graph in which the order of arcs is reversed.

Definition at line 63 of file nnet-graph.cc.

References rnnlm::n.

Referenced by ComputeComputationPhases(), FindOrphanNodes(), and UnitTestComputeGraphTranspose().

64  {
65  int32 size = graph.size();
66  graph_transpose->clear();
67  graph_transpose->resize(size);
68  for (int32 n = 0; n < size; n++) {
69  const std::vector<int32> &nodes = graph[n];
70  std::vector<int32>::const_iterator iter = nodes.begin(), end = nodes.end();
71  for (; iter != end; ++iter) {
72  int32 dest = *iter;
73  (*graph_transpose)[dest].push_back(n);
74  }
75  }
76 }
struct rnnlm::@11::@12 n
void ComputeMatrixAccesses ( const Nnet &  nnet,
const NnetComputation &  computation,
const ComputationVariables &  variables,
const std::vector< CommandAttributes > &  command_attributes,
std::vector< MatrixAccesses > *  matrix_accesses 
)

This function organizes information in the CommandAttributes in a way that is convenient to access per matrix.

See struct MatrixAccesses for the output format; the output "matrix_accesses" is indexed by the matrix index (the same index as computation.matrices).

Definition at line 436 of file nnet-analyze.cc.

References NnetComputation::Command::arg1, NnetComputation::Command::arg2, NnetComputation::Command::command_type, NnetComputation::commands, NnetComputation::input_output_info, Nnet::IsInputNode(), Nnet::IsOutputNode(), kaldi::IsSortedAndUniq(), KALDI_ASSERT, KALDI_ERR, kAllocMatrixFromOther, kAllocMatrixFromOtherZeroed, kAllocMatrixUndefined, kAllocMatrixZeroed, kDeallocMatrix, kReadAccess, kReadWriteAccess, kWriteAccess, NnetComputation::matrices, CommandAttributes::matrices_read, CommandAttributes::matrices_written, and kaldi::SortAndUniq().

Referenced by Analyzer::Init(), and MoveSizingCommands().

441  {
442  int32 num_matrices = computation.matrices.size(),
443  num_commands = command_attributes.size();
444  matrix_accesses->clear();
445  matrix_accesses->resize(num_matrices);
446  for (int32 c = 0; c < num_commands; c++) {
447  const CommandAttributes &attr = command_attributes[c];
448  KALDI_ASSERT(IsSortedAndUniq(attr.matrices_read));
449  KALDI_ASSERT(IsSortedAndUniq(attr.matrices_written));
450  std::vector<int32> all_matrices;
451  all_matrices.reserve(attr.matrices_read.size() +
452  attr.matrices_written.size());
453  all_matrices.insert(all_matrices.end(), attr.matrices_read.begin(),
454  attr.matrices_read.end());
455  all_matrices.insert(all_matrices.end(), attr.matrices_written.begin(),
456  attr.matrices_written.end());
457  SortAndUniq(&all_matrices);
458 
459  std::vector<int32>::const_iterator iter = all_matrices.begin(),
460  end = all_matrices.end();
461  for (; iter != end; ++iter) {
462  int32 matrix_index = *iter;
463  bool is_read = std::binary_search(attr.matrices_read.begin(),
464  attr.matrices_read.end(),
465  matrix_index),
466  is_written = (!is_read ? true :
467  std::binary_search(attr.matrices_written.begin(),
468  attr.matrices_written.end(),
469  matrix_index));
470  if (is_read && is_written) {
471  (*matrix_accesses)[matrix_index].accesses.push_back(
472  Access(c, kReadWriteAccess));
473  } else if (is_read) {
474  (*matrix_accesses)[matrix_index].accesses.push_back(
475  Access(c, kReadAccess));
476  } else {
477  (*matrix_accesses)[matrix_index].accesses.push_back(
478  Access(c, kWriteAccess));
479  }
480  }
481  // Now set up allocate_command and deallocate_command.
482  const NnetComputation::Command &command = computation.commands[c];
483  int32 matrix_index = command.arg1,
484  matrix_index2 = command.arg2;
485 
486  switch (command.command_type) {
487  case kAllocMatrixZeroed:
489  if ((*matrix_accesses)[matrix_index].allocate_command != -1)
490  KALDI_ERR << "Matrix " << matrix_index << " initialized twice.";
491  (*matrix_accesses)[matrix_index].allocate_command = c;
492  break;
495  if ((*matrix_accesses)[matrix_index].allocate_command != -1)
496  KALDI_ERR << "Matrix " << matrix_index << " initialized twice.";
497  (*matrix_accesses)[matrix_index].allocate_command = c;
498  if ((*matrix_accesses)[matrix_index2].deallocate_command != -1)
499  KALDI_ERR << "Matrix " << matrix_index << " destroyed twice.";
500  (*matrix_accesses)[matrix_index2].deallocate_command = c;
501  break;
502  case kDeallocMatrix:
503  if ((*matrix_accesses)[matrix_index].deallocate_command != -1)
504  KALDI_ERR << "Matrix " << matrix_index << " destroyed twice.";
505  (*matrix_accesses)[matrix_index].deallocate_command = c;
506  break;
507  default:
508  ;
509  }
510  }
511  // now set up the is_input and is_output fields.
512  unordered_map<int32, std::pair<int32, int32> >::const_iterator
513  iter = computation.input_output_info.begin(),
514  end = computation.input_output_info.end();
515  for (; iter != end; ++iter) {
516  int32 node_index = iter->first,
517  value_matrix_index = iter->second.first,
518  deriv_matrix_index = iter->second.second;
519  KALDI_ASSERT(value_matrix_index > 0 && value_matrix_index < num_matrices);
520  if (nnet.IsInputNode(node_index)) {
521  // the assert checks for repeats
522  KALDI_ASSERT(!(*matrix_accesses)[value_matrix_index].is_input);
523  (*matrix_accesses)[value_matrix_index].is_input = true;
524  if (deriv_matrix_index != 0) {
525  // the derivatives, if requested, would be outputs of the computation,
526  // even though the node is an input node.
527  KALDI_ASSERT(!(*matrix_accesses)[deriv_matrix_index].is_output);
528  (*matrix_accesses)[deriv_matrix_index].is_output = true;
529  }
530  } else {
531  KALDI_ASSERT(nnet.IsOutputNode(node_index));
532  // the assert checks for repeats
533  KALDI_ASSERT(!(*matrix_accesses)[value_matrix_index].is_output);
534  (*matrix_accesses)[value_matrix_index].is_output = true;
535  if (deriv_matrix_index != 0) {
536  // the derivatives, if provided, would be inputs to the computation,
537  // even though the node is an output node.
538  KALDI_ASSERT(!(*matrix_accesses)[deriv_matrix_index].is_input);
539  (*matrix_accesses)[deriv_matrix_index].is_input = true;
540  }
541  }
542  }
543 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:51
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
bool IsSortedAndUniq(const std::vector< T > &vec)
Returns true if the vector is sorted and contains each element only once.
Definition: stl-utils.h:75
void ComputeMatrixToSubmatrix ( const NnetComputation &  computation,
std::vector< std::vector< int32 > > *  mat_to_submat 
)

This function computes a vector 'mat_to_submat', indexed by matrix index, such that (*mat_to_submat)[m] is a list of all the submatrix indexes that refer to matrix m.

Note, (*mat_to_submat)[0] will be the empty vector.

Definition at line 985 of file nnet-analyze.cc.

References KALDI_ASSERT, NnetComputation::matrices, and NnetComputation::submatrices.

Referenced by VariableMergingOptimizer::VariableMergingOptimizer().

987  {
988  int32 num_matrices = computation.matrices.size(),
989  num_submatrices = computation.submatrices.size();
990  mat_to_submat->clear();
991  mat_to_submat->resize(num_matrices);
992  for (int32 submatrix_index = 1;
993  submatrix_index < num_submatrices;
994  submatrix_index++) {
995  int32 matrix_index = computation.submatrices[submatrix_index].matrix_index;
996  KALDI_ASSERT(matrix_index > 0 && matrix_index < num_matrices);
997  (*mat_to_submat)[matrix_index].push_back(submatrix_index);
998  }
999 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::ComputeMinAndMaxTimes ( const std::vector< Index > &  indexes,
int32 *  min_t,
int32 *  max_t 
)

Definition at line 31 of file nnet-derivative-test.cc.

References KALDI_ASSERT, and rnnlm::n.

Referenced by SetDerivTimesOptions().

33  {
34  KALDI_ASSERT(!indexes.empty());
35  *min_t = indexes[0].t;
36  *max_t = *min_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);
40  }
41 }
struct rnnlm::@11::@12 n
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeNnetComputationEpochs ( const Nnet &  nnet,
std::vector< int32 > *  node_to_epoch 
)

This function computes the order in which we need to compute each node in the graph, where each node-index n maps to an epoch-index t = 0, 1, ...

that says when we should compute it. Nodes that are part of a strongly connected component (SCC) will all be computed at the same time, but any two nodes that are not part of an SCC will have different epoch-index, and these epoch-indexes will be such that a node computed at a larger epoch-index may depend on a node computed at a smaller epoch-index, but not vice versa.

Internally it calls NnetToDirectedGraph, FindSccs, MakeSccGraph and ComputeTopSortOrder.

Definition at line 265 of file nnet-graph.cc.

References ComputeTopSortOrder(), FindSccs(), kaldi::GetVerboseLevel(), rnnlm::i, rnnlm::j, KALDI_ASSERT, KALDI_VLOG, MakeSccGraph(), NnetToDirectedGraph(), and PrintGraphToString().

Referenced by kaldi::nnet3::computation_graph::ComputeEpochInfo().

266  {
267  KALDI_ASSERT(node_to_epoch != NULL);
268 
269  std::vector<std::vector<int32> > graph;
270  NnetToDirectedGraph(nnet, &graph);
271  KALDI_VLOG(6) << "graph is: " << PrintGraphToString(graph);
272 
273  std::vector<std::vector<int32> > sccs;
274  FindSccs(graph, &sccs);
275 
276  std::vector<std::vector<int32> > scc_graph;
277  MakeSccGraph(graph, sccs, &scc_graph);
278  KALDI_VLOG(6) << "scc graph is: " << PrintGraphToString(scc_graph);
279 
280  std::vector<int32> scc_node_to_epoch;
281  ComputeTopSortOrder(scc_graph, &scc_node_to_epoch);
282  if (GetVerboseLevel() >= 6) {
283  std::ostringstream os;
284  for (int32 i = 0; i < scc_node_to_epoch.size(); i++)
285  os << scc_node_to_epoch[i] << ", ";
286  KALDI_VLOG(6) << "scc_node_to_epoch is: " << os.str();
287  }
288 
289  node_to_epoch->clear();
290  node_to_epoch->resize(graph.size());
291  for (int32 i = 0; i < sccs.size(); ++i) {
292  for (int32 j = 0; j < sccs[i].size(); ++j) {
293  int32 node = sccs[i][j];
294  KALDI_ASSERT(node >= 0 && node < graph.size());
295  (*node_to_epoch)[node] = scc_node_to_epoch[i];
296  }
297  }
298 }
void NnetToDirectedGraph(const Nnet &nnet, std::vector< std::vector< int32 > > *graph)
This function takes an nnet and turns it to a directed graph on nodes.
Definition: nnet-graph.cc:30
int32 GetVerboseLevel()
Definition: kaldi-error.h:69
void ComputeTopSortOrder(const std::vector< std::vector< int32 > > &graph, std::vector< int32 > *node_to_order)
Given an acyclic graph (where each std::vector is a list of destination-nodes of arcs coming f...
Definition: nnet-graph.cc:223
void FindSccs(const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *sccs)
Given a directed graph (where each std::vector is a list of destination-nodes of arcs coming f...
Definition: nnet-graph.cc:156
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void MakeSccGraph(const std::vector< std::vector< int32 > > &graph, const std::vector< std::vector< int32 > > &sccs, std::vector< std::vector< int32 > > *scc_graph)
Given a list of sccs of a graph (e.g.
Definition: nnet-graph.cc:164
#define KALDI_VLOG(v)
Definition: kaldi-error.h:136
std::string PrintGraphToString(const std::vector< std::vector< int32 > > &graph)
Prints a graph to a string in a pretty way for human readability, e.g.
Definition: nnet-graph.cc:248
void ComputeObjectiveFunction ( const GeneralMatrix &  supervision,
ObjectiveType  objective_type,
const std::string &  output_name,
bool  supply_deriv,
NnetComputer *  computer,
BaseFloat *  tot_weight,
BaseFloat *  tot_objf 
)

This function computes the objective function, and if supply_deriv = true, supplies its derivative to the NnetComputation object.

See also the function ComputeAccuracy(), declared in nnet-diagnostics.h.

Parameters
[in]supervisionA GeneralMatrix, typically derived from a NnetExample, containing the supervision posteriors or features.
[in]objective_typeThe objective function type: kLinear = output * supervision, or kQuadratic = -0.5 * (output - supervision)^2. kLinear is used for softmax objectives; the network contains a LogSoftmax layer which correctly normalizes its output.
[in]output_nameThe name of the output node (e.g. "output"), used to look up the output in the NnetComputer object.
[in]supply_derivIf this is true, this function will compute the derivative of the objective function and supply it to the network using the function NnetComputer::AcceptOutputDeriv
[in,out]computerThe NnetComputer object, from which we get the output using GetOutput and to which we may supply the derivatives using AcceptOutputDeriv.
[out]tot_weightThe total weight of the training examples. In the kLinear case, this is the sum of the supervision matrix; in the kQuadratic case, it is the number of rows of the supervision matrix. In order to make it possible to weight samples with quadratic objective functions, we may at some point make it possible for the supervision matrix to have an extra column containing weights. At the moment, this is not supported.
[out]tot_objfThe total objective function; divide this by the tot_weight to get the normalized objective function.

Definition at line 297 of file nnet-training.cc.

References NnetComputer::AcceptOutputDeriv(), CuMatrixBase< Real >::CopyFromGeneralMat(), CuSparseMatrix< Real >::CopyToMat(), GeneralMatrix::GetFullMatrix(), GeneralMatrix::GetMatrix(), NnetComputer::GetOutput(), GeneralMatrix::GetSparseMatrix(), KALDI_ERR, kaldi::kCompressedMatrix, kaldi::kFullMatrix, kLinear, kQuadratic, kaldi::kSparseMatrix, kaldi::kTrans, kaldi::kUndefined, CuMatrixBase< Real >::NumCols(), GeneralMatrix::NumCols(), CuMatrixBase< Real >::NumRows(), GeneralMatrix::NumRows(), CuSparseMatrix< Real >::Sum(), CuMatrixBase< Real >::Sum(), CuMatrix< Real >::Swap(), kaldi::TraceMatMat(), kaldi::TraceMatSmat(), and GeneralMatrix::Type().

Referenced by NnetComputeProb::ProcessOutputs(), and NnetTrainer::ProcessOutputs().

303  {
304  const CuMatrixBase<BaseFloat> &output = computer->GetOutput(output_name);
305 
306  if (output.NumCols() != supervision.NumCols())
307  KALDI_ERR << "Nnet versus example output dimension (num-classes) "
308  << "mismatch for '" << output_name << "': " << output.NumCols()
309  << " (nnet) vs. " << supervision.NumCols() << " (egs)\n";
310 
311  switch (objective_type) {
312  case kLinear: {
313  // objective is x * y.
314  switch (supervision.Type()) {
315  case kSparseMatrix: {
316  const SparseMatrix<BaseFloat> &post = supervision.GetSparseMatrix();
317  CuSparseMatrix<BaseFloat> cu_post(post);
318  // The cross-entropy objective is computed by a simple dot product,
319  // because after the LogSoftmaxLayer, the output is already in the form
320  // of log-likelihoods that are normalized to sum to one.
321  *tot_weight = cu_post.Sum();
322  *tot_objf = TraceMatSmat(output, cu_post, kTrans);
323  if (supply_deriv) {
324  CuMatrix<BaseFloat> output_deriv(output.NumRows(), output.NumCols(),
325  kUndefined);
326  cu_post.CopyToMat(&output_deriv);
327  computer->AcceptOutputDeriv(output_name, &output_deriv);
328  }
329  break;
330  }
331  case kFullMatrix: {
332  // there is a redundant matrix copy in here if we're not using a GPU
333  // but we don't anticipate this code branch being used in many cases.
334  CuMatrix<BaseFloat> cu_post(supervision.GetFullMatrix());
335  *tot_weight = cu_post.Sum();
336  *tot_objf = TraceMatMat(output, cu_post, kTrans);
337  if (supply_deriv)
338  computer->AcceptOutputDeriv(output_name, &cu_post);
339  break;
340  }
341  case kCompressedMatrix: {
342  Matrix<BaseFloat> post;
343  supervision.GetMatrix(&post);
344  CuMatrix<BaseFloat> cu_post;
345  cu_post.Swap(&post);
346  *tot_weight = cu_post.Sum();
347  *tot_objf = TraceMatMat(output, cu_post, kTrans);
348  if (supply_deriv)
349  computer->AcceptOutputDeriv(output_name, &cu_post);
350  break;
351  }
352  }
353  break;
354  }
355  case kQuadratic: {
356  // objective is -0.5 (x - y)^2
357  CuMatrix<BaseFloat> diff(supervision.NumRows(),
358  supervision.NumCols(),
359  kUndefined);
360  diff.CopyFromGeneralMat(supervision);
361  diff.AddMat(-1.0, output);
362  *tot_weight = diff.NumRows();
363  *tot_objf = -0.5 * TraceMatMat(diff, diff, kTrans);
364  if (supply_deriv)
365  computer->AcceptOutputDeriv(output_name, &diff);
366  break;
367  }
368  default:
369  KALDI_ERR << "Objective function type " << objective_type
370  << " not handled.";
371  }
372 }
#define KALDI_ERR
Definition: kaldi-error.h:127
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.
Real TraceMatSmat(const MatrixBase< Real > &A, const SparseMatrix< Real > &B, MatrixTransposeType trans)
void ComputeSimpleNnetContext ( const Nnet &  nnet,
int32 *  left_context,
int32 *  right_context 
)

ComputeNnetContext computes the left-context and right-context of a nnet.

The nnet must satisfy IsSimpleNnet(nnet).

It does this by constructing a ComputationRequest with a certain number of inputs available, outputs can be computed.. It does the same after shifting the time index of the output to all values 0, 1, ... n-1, where n is the output of nnet.Modulus(). Then it returns the largest left context and the largest right context that it infers from any of these computation requests.

Definition at line 131 of file nnet-utils.cc.

References ComputeSimpleNnetContextForShift(), IsSimpleNnet(), KALDI_ASSERT, and Nnet::Modulus().

Referenced by ComputeExampleComputationRequestSimple(), DecodableNnet3SimpleOnline::DecodableNnet3SimpleOnline(), DecodableNnetSimple::DecodableNnetSimple(), Nnet::Info(), NnetInfo(), AmNnetSimple::SetContext(), and UnitTestNnetContext().

133  {
134  KALDI_ASSERT(IsSimpleNnet(nnet));
135  int32 modulus = nnet.Modulus();
136  // modulus >= 1 is a number such that the network ought to be
137  // invariant to time shifts (of both the input and output) that
138  // are a multiple of this number. We need to test all shifts modulo
139  // this number in case the left and right context vary at all within
140  // this range.
141 
142  std::vector<int32> left_contexts(modulus + 1);
143  std::vector<int32> right_contexts(modulus + 1);
144 
145  // This will crash if the total context (left + right) is greater
146  // than window_size.
147  int32 window_size = 100;
148  // by going "<= modulus" instead of "< modulus" we do one more computation
149  // than we really need; it becomes a sanity check.
150  for (int32 input_start = 0; input_start <= modulus; input_start++)
151  ComputeSimpleNnetContextForShift(nnet, input_start, window_size,
152  &(left_contexts[input_start]),
153  &(right_contexts[input_start]));
154  KALDI_ASSERT(left_contexts[0] == left_contexts[modulus] &&
155  "nnet does not have the properties we expect.");
156  KALDI_ASSERT(right_contexts[0] == right_contexts[modulus] &&
157  "nnet does not have the properties we expect.");
158  *left_context =
159  *std::max_element(left_contexts.begin(), left_contexts.end());
160  *right_context =
161  *std::max_element(right_contexts.begin(), right_contexts.end());
162 }
bool IsSimpleNnet(const Nnet &nnet)
This function returns true if the nnet has the following properties: It has an called "output" (other...
Definition: nnet-utils.cc:46
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void ComputeSimpleNnetContextForShift(const Nnet &nnet, int32 input_start, int32 window_size, int32 *left_context, int32 *right_context)
Definition: nnet-utils.cc:84
static void kaldi::nnet3::ComputeSimpleNnetContextForShift ( const Nnet &  nnet,
int32  input_start,
int32  window_size,
int32 *  left_context,
int32 *  right_context 
)
static

Definition at line 84 of file nnet-utils.cc.

References EvaluateComputationRequest(), Nnet::GetNodeIndex(), IoSpecification::indexes, ComputationRequest::inputs, KALDI_ASSERT, KALDI_ERR, rnnlm::n, IoSpecification::name, and ComputationRequest::outputs.

Referenced by ComputeSimpleNnetContext().

89  {
90 
91  int32 input_end = input_start + window_size;
92  IoSpecification input;
93  input.name = "input";
94  IoSpecification output;
95  output.name = "output";
96  IoSpecification ivector; // we might or might not use this.
97  ivector.name = "ivector";
98 
99  int32 n = rand() % 10;
100  // in the IoSpecification for now we we will request all the same indexes at
101  // output that we requested at input.
102  for (int32 t = input_start; t < input_end; t++) {
103  input.indexes.push_back(Index(n, t));
104  output.indexes.push_back(Index(n, t));
105  }
106  // the assumption here is that the network just requires the ivector at time
107  // t=0.
108  ivector.indexes.push_back(Index(n, 0));
109 
110  ComputationRequest request;
111  request.inputs.push_back(input);
112  request.outputs.push_back(output);
113  if (nnet.GetNodeIndex("ivector") != -1)
114  request.inputs.push_back(ivector);
115  std::vector<std::vector<bool> > computable;
116  EvaluateComputationRequest(nnet, request, &computable);
117 
118  KALDI_ASSERT(computable.size() == 1);
119  std::vector<bool> &output_ok = computable[0];
120  std::vector<bool>::iterator iter =
121  std::find(output_ok.begin(), output_ok.end(), true);
122  int32 first_ok = iter - output_ok.begin();
123  int32 first_not_ok = std::find(iter, output_ok.end(), false) -
124  output_ok.begin();
125  if (first_ok == window_size || first_not_ok <= first_ok)
126  KALDI_ERR << "No outputs were computable (perhaps not a simple nnet?)";
127  *left_context = first_ok;
128  *right_context = window_size - first_not_ok;
129 }
void EvaluateComputationRequest(const Nnet &nnet, const ComputationRequest &request, std::vector< std::vector< bool > > *is_computable)
Given an nnet and a computation request, this function works out which requested outputs in the compu...
Definition: nnet-utils.cc:66
struct rnnlm::@11::@12 n
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::ComputeSubmatIndexHistogram ( const std::vector< std::vector< std::pair< int32, int32 > > >  sorted_submat_lists,
unordered_map< int32, std::vector< int32 > > *  submat_histogram 
)

Definition at line 113 of file nnet-compile-utils.cc.

References rnnlm::i, rnnlm::j, and KALDI_ASSERT.

Referenced by SplitLocations().

123  {
124  KALDI_ASSERT(sorted_submat_lists.size() > 0);
125  // computing the submat_histogram
126  // counting the occurrences of each element in the current submat_list;
127  // each new occurrence of the same element, in this list, is counted
128  // as a seperate symbol for frequency counts
129  for (int32 i = 0; i < sorted_submat_lists.size(); i++) {
130  int j = 0;
131  unordered_map<int32, std::vector<int32> >::iterator histogram_iterator
132  = submat_histogram->end();
133  int32 repetition_count = 0;
134  while (j < sorted_submat_lists[i].size()) {
135  if ((histogram_iterator == submat_histogram->end()) ||
136  (histogram_iterator->first != sorted_submat_lists[i][j].first)) {
137  histogram_iterator =
138  submat_histogram->find(sorted_submat_lists[i][j].first);
139  repetition_count = 0;
140  // if a histogram entry was not found for this submat_index, add one
141  if (histogram_iterator == submat_histogram->end()) {
142  (*submat_histogram)[sorted_submat_lists[i][j].first];
143  histogram_iterator = submat_histogram->find(
144  sorted_submat_lists[i][j].first);
145  }
146  }
147 
148  if (repetition_count >= (histogram_iterator->second).size()) {
149  // this is the first time the submat_index repeated this many times
150  // so add an entry for this in the count vector
151  (histogram_iterator->second).push_back(1);
152  } else {
153  (histogram_iterator->second)[repetition_count]++;
154  }
155  repetition_count++;
156  j++;
157  }
158  }
159 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeTopSortOrder ( const std::vector< std::vector< int32 > > &  graph,
std::vector< int32 > *  node_to_order 
)

Given an acyclic graph (where each std::vector<int32> is a list of destination-nodes of arcs coming from the current node), compute a topological ordering of the graph nodes.

The output format is that node_to_order[n] contains an integer t = 0, 1, ... which is the order of node n in a topological sorting. node_to_order should contain some permutation of the numbers 0 ... graph.size() - 1. This function should crash if the graph contains cycles.

Definition at line 223 of file nnet-graph.cc.

References ComputeTopSortOrderRecursive(), rnnlm::i, and KALDI_ASSERT.

Referenced by ComputeNnetComputationEpochs(), UnitTestComputeTopSortOrder(), and UnitTestComputeTopSortOrder2().

224  {
225  // Internally we use DFS, but we only put the node to <node_to_order> when all
226  // its parents have been visited.
227  KALDI_ASSERT(node_to_order != NULL);
228  node_to_order->resize(graph.size());
229 
230  std::vector<bool> cycle_detector(graph.size(), false);
231  std::vector<bool> is_visited(graph.size(), false);
232 
233  std::vector<int32> reversed_orders;
234  for(int32 i = 0; i < graph.size(); ++i) {
235  if (!is_visited[i]) {
236  ComputeTopSortOrderRecursive(i, graph, &cycle_detector,
237  &is_visited, &reversed_orders);
238  }
239  }
240 
241  KALDI_ASSERT(node_to_order->size() == reversed_orders.size());
242  for (int32 i = 0; i < reversed_orders.size(); ++i) {
243  KALDI_ASSERT(reversed_orders[i] >= 0 && reversed_orders[i] < graph.size());
244  (*node_to_order)[reversed_orders[i]] = graph.size() - i - 1;
245  }
246 }
void ComputeTopSortOrderRecursive(int32 node, const std::vector< std::vector< int32 > > &graph, std::vector< bool > *cycle_detector, std::vector< bool > *is_visited, std::vector< int32 > *reversed_orders)
Definition: nnet-graph.cc:196
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::ComputeTopSortOrderRecursive ( int32  node,
const std::vector< std::vector< int32 > > &  graph,
std::vector< bool > *  cycle_detector,
std::vector< bool > *  is_visited,
std::vector< int32 > *  reversed_orders 
)

Definition at line 196 of file nnet-graph.cc.

References rnnlm::i, KALDI_ASSERT, and KALDI_ERR.

Referenced by ComputeTopSortOrder().

200  {
201  KALDI_ASSERT(node >= 0 && node < graph.size());
202  KALDI_ASSERT(cycle_detector != NULL);
203  KALDI_ASSERT(is_visited != NULL);
204  KALDI_ASSERT(reversed_orders != NULL);
205  if ((*cycle_detector)[node]) {
206  KALDI_ERR << "Cycle detected when computing the topological sorting order";
207  }
208 
209  if (!(*is_visited)[node]) {
210  (*cycle_detector)[node] = true;
211  for (int32 i = 0; i < graph[node].size(); ++i) {
212  ComputeTopSortOrderRecursive(graph[node][i], graph,
213  cycle_detector, is_visited, reversed_orders);
214  }
215  (*cycle_detector)[node] = false;
216  (*is_visited)[node] = true;
217  // At this point we have added all the children to <reversed_orders>, so we
218  // can add the current now.
219  reversed_orders->push_back(node);
220  }
221 }
void ComputeTopSortOrderRecursive(int32 node, const std::vector< std::vector< int32 > > &graph, std::vector< bool > *cycle_detector, std::vector< bool > *is_visited, std::vector< int32 > *reversed_orders)
Definition: nnet-graph.cc:196
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeVariableAccesses ( const ComputationVariables &  variables,
const std::vector< CommandAttributes > &  command_attributes,
std::vector< std::vector< Access > > *  variable_accesses 
)

After the command-level attributes have been computed, this function organizes them per variable (see class ComputationVariables for how a variable is defined; it is part of a matrix).

Parameters
[in]variablesThe definition of variables for this computation
[in]command_attributesA vector of attributes, one per command, as obtained from ComputeCommandAttributes().
[out]variable_accessesThe output will have a size equal to the number of variables, and each element will be a vector of accesses, sorted by command index; each command will only be listed once in this vector.

Definition at line 390 of file nnet-analyze.cc.

References kaldi::IsSortedAndUniq(), KALDI_ASSERT, kReadAccess, kReadWriteAccess, kWriteAccess, ComputationVariables::NumVariables(), kaldi::SortAndUniq(), CommandAttributes::variables_read, and CommandAttributes::variables_written.

Referenced by Analyzer::Init(), and MoveSizingCommands().

393  {
394  int32 num_variables = variables.NumVariables(),
395  num_commands = command_attributes.size();
396  variable_accesses->clear();
397  variable_accesses->resize(num_variables);
398  for (int32 c = 0; c < num_commands; c++) {
399  const CommandAttributes &attr = command_attributes[c];
400  KALDI_ASSERT(IsSortedAndUniq(attr.variables_read));
401  KALDI_ASSERT(IsSortedAndUniq(attr.variables_written));
402  std::vector<int32> all_variables;
403  all_variables.reserve(attr.variables_read.size() +
404  attr.variables_written.size());
405  all_variables.insert(all_variables.end(), attr.variables_read.begin(),
406  attr.variables_read.end());
407  all_variables.insert(all_variables.end(), attr.variables_written.begin(),
408  attr.variables_written.end());
409  SortAndUniq(&all_variables);
410 
411  std::vector<int32>::const_iterator iter = all_variables.begin(),
412  end = all_variables.end();
413  for (; iter != end; ++iter) {
414  int32 variable_index = *iter;
415  bool is_read = std::binary_search(attr.variables_read.begin(),
416  attr.variables_read.end(),
417  variable_index),
418  is_written = (!is_read ? true :
419  std::binary_search(attr.variables_written.begin(),
420  attr.variables_written.end(),
421  variable_index));
422  if (is_read && is_written) {
423  (*variable_accesses)[variable_index].push_back(
424  Access(c, kReadWriteAccess));
425  } else if (is_read) {
426  (*variable_accesses)[variable_index].push_back(
427  Access(c, kReadAccess));
428  } else {
429  (*variable_accesses)[variable_index].push_back(
430  Access(c, kWriteAccess));
431  }
432  }
433  }
434 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:51
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
bool IsSortedAndUniq(const std::vector< T > &vec)
Returns true if the vector is sorted and contains each element only once.
Definition: stl-utils.h:75
void ConsolidateModelUpdate ( const Nnet &  nnet,
const ComputationRequest &  request,
NnetComputation *  computation 
)

This consolidates the model-update parts of the backprop into larger operations (applicable mostly to recurrent setups)– internally it uses class ModelUpdateConsolidator.

Will fail if called a second time.

Definition at line 346 of file nnet-optimize.cc.

References ModelUpdateConsolidator::ConsolidateModelUpdate(), and ComputationRequest::need_model_derivative.

Referenced by Optimize().

348  {
349  if (!request.need_model_derivative)
350  return; // An optimization; there would be nothing to do in this case.
351  ModelUpdateConsolidator consolidator(nnet, computation);
352  consolidator.ConsolidateModelUpdate();
353 }
bool kaldi::nnet3::ContainsSingleExample ( const NnetExample eg,
int32 *  min_input_t,
int32 *  max_input_t,
int32 *  min_output_t,
int32 *  max_output_t 
)

Returns true if the "eg" contains just a single example, meaning that all the "n" values in the indexes are zero, and the example has NnetIo members named both "input" and "output".

Also computes the minimum and maximum "t" values in the "input" and "output" NnetIo members.

Definition at line 48 of file nnet3-copy-egs.cc.

References rnnlm::i, NnetIo::indexes, NnetExample::io, KALDI_ASSERT, KALDI_WARN, and NnetIo::name.

Referenced by SelectFromExample().

52  {
53  bool done_input = false, done_output = false;
54  int32 num_indexes = eg.io.size();
55  for (int32 i = 0; i < num_indexes; i++) {
56  const NnetIo &io = eg.io[i];
57  std::vector<Index>::const_iterator iter = io.indexes.begin(),
58  end = io.indexes.end();
59  // Should not have an empty input/output type.
60  KALDI_ASSERT(!io.indexes.empty());
61  if (io.name == "input" || io.name == "output") {
62  int32 min_t = iter->t, max_t = iter->t;
63  for (; iter != end; ++iter) {
64  int32 this_t = iter->t;
65  min_t = std::min(min_t, this_t);
66  max_t = std::max(max_t, this_t);
67  if (iter->n != 0) {
68  KALDI_WARN << "Example does not contain just a single example; "
69  << "too late to do frame selection or reduce context.";
70  return false;
71  }
72  }
73  if (io.name == "input") {
74  done_input = true;
75  *min_input_t = min_t;
76  *max_input_t = max_t;
77  } else {
78  KALDI_ASSERT(io.name == "output");
79  done_output = true;
80  *min_output_t = min_t;
81  *max_output_t = max_t;
82  }
83  } else {
84  for (; iter != end; ++iter) {
85  if (iter->n != 0) {
86  KALDI_WARN << "Example does not contain just a single example; "
87  << "too late to do frame selection or reduce context.";
88  return false;
89  }
90  }
91  }
92  }
93  if (!done_input) {
94  KALDI_WARN << "Example does not have any input named 'input'";
95  return false;
96  }
97  if (!done_output) {
98  KALDI_WARN << "Example does not have any output named 'output'";
99  return false;
100  }
101  return true;
102 }
std::vector< Index > indexes
"indexes" is a vector the same length as features.NumRows(), explaining the meaning of each row of th...
Definition: nnet-example.h:42
#define KALDI_WARN
Definition: kaldi-error.h:130
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
std::string name
the name of the input in the neural net; in simple setups it will just be "input".
Definition: nnet-example.h:36
std::vector< NnetIo > io
"io" contains the input and output.
Definition: nnet-example.h:87
void ConvertAdditionToAssignment ( const Nnet &  nnet,
NnetComputation *  computation 
)

This converts addition operations (things with Add in their names) to copy operations (things with Copy in their names).

This is both slightly more efficient,

Definition at line 356 of file nnet-optimize.cc.

References Analyzer::command_attributes, NnetComputation::Command::command_type, NnetComputation::commands, ComputationAnalysis::FirstAccess(), Analyzer::Init(), kAddRows, kAddRowsMulti, kAddToRowsMulti, KALDI_ASSERT, KALDI_ERR, kAllocMatrixFromOther, kAllocMatrixUndefined, kCopyRows, kCopyRowsMulti, kCopyToRowsMulti, kMatrixAdd, and kMatrixCopy.

Referenced by Optimize().

357  {
358  Analyzer analyzer;
359  analyzer.Init(nnet, *computation);
360  ComputationAnalysis analysis(*computation, analyzer);
361  int32 num_commands = computation->commands.size();
362  for (int32 command = 0; command < num_commands; command++) {
363  NnetComputation::Command &c = computation->commands[command];
364  switch (c.command_type) {
366  KALDI_ERR << "Cannot call ConvertAdditionToAssignment after "
367  << "allowing undefined initialization.";
368  case kMatrixAdd: case kAddRows: case kAddRowsMulti:
369  case kAddToRowsMulti: {
370  const std::vector<int32> &submatrices_written =
371  analyzer.command_attributes[command].submatrices_written;
372  KALDI_ASSERT(!submatrices_written.empty());
373  std::vector<int32>::const_iterator iter = submatrices_written.begin(),
374  end = submatrices_written.end();
375  bool can_convert = true;
376  for (; iter != end; ++iter) {
377  int32 submatrix_written = *iter;
378  int32 first_access_command = analysis.FirstAccess(submatrix_written);
379  // first_access_command is first non-initialization command that
380  // accesses this submatrix. It can be assumed to be a write command,
381  // since it makes no sense to read a variable before it's written to.
382  // If it's before this command then we need to add rather than copy,
383  // we can't do the conversion to a copy command.
384  if (first_access_command != command) {
385  can_convert = false;
386  break;
387  }
388  }
389  if (can_convert) { // convert to a copy command.
390  switch (c.command_type) {
391  case kMatrixAdd: c.command_type = kMatrixCopy; break;
392  case kAddRows: c.command_type = kCopyRows; break;
393  case kAddRowsMulti: c.command_type = kCopyRowsMulti; break;
394  case kAddToRowsMulti: c.command_type = kCopyToRowsMulti; break;
395  default: KALDI_ERR << "Unexpected command type.";
396  }
397  }
398  break;
399  }
400  default:
401  break;
402  }
403  }
404 }
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::ConvertRepeatedToBlockAffine ( CompositeComponent *  c_component)

Definition at line 464 of file nnet-utils.cc.

References CompositeComponent::GetComponent(), rnnlm::i, KALDI_ASSERT, CompositeComponent::NumComponents(), CompositeComponent::SetComponent(), and Component::Type().

Referenced by ConvertRepeatedToBlockAffine(), main(), UnitTestConvertRepeatedToBlockAffine(), and UnitTestConvertRepeatedToBlockAffineComposite().

464  {
465  for(int32 i = 0; i < c_component->NumComponents(); i++) {
466  const Component *c = c_component->GetComponent(i);
467  KALDI_ASSERT(c->Type() != "CompositeComponent" &&
468  "Nesting CompositeComponent within CompositeComponent is not allowed.\n"
469  "(We may change this as more complicated components are introduced.)");
470 
471  if(c->Type() == "RepeatedAffineComponent" ||
472  c->Type() == "NaturalGradientRepeatedAffineComponent") {
473  // N.B.: NaturalGradientRepeatedAffineComponent is a subclass of
474  // RepeatedAffineComponent.
475  const RepeatedAffineComponent *rac =
476  dynamic_cast<const RepeatedAffineComponent*>(c);
477  KALDI_ASSERT(rac != NULL);
478  BlockAffineComponent *bac = new BlockAffineComponent(*rac);
479  // following call deletes rac
480  c_component->SetComponent(i, bac);
481  }
482  }
483 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ConvertRepeatedToBlockAffine ( Nnet *  nnet)

Convert all components of type RepeatedAffineComponent or NaturalGradientRepeatedAffineComponent to BlockAffineComponent in nnet.

Definition at line 485 of file nnet-utils.cc.

References ConvertRepeatedToBlockAffine(), Nnet::GetComponent(), rnnlm::i, KALDI_ASSERT, Nnet::NumComponents(), Nnet::SetComponent(), and Component::Type().

485  {
486  for(int32 i = 0; i < nnet->NumComponents(); i++) {
487  const Component *const_c = nnet->GetComponent(i);
488  if(const_c->Type() == "RepeatedAffineComponent" ||
489  const_c->Type() == "NaturalGradientRepeatedAffineComponent") {
490  // N.B.: NaturalGradientRepeatedAffineComponent is a subclass of
491  // RepeatedAffineComponent.
492  const RepeatedAffineComponent *rac =
493  dynamic_cast<const RepeatedAffineComponent*>(const_c);
494  KALDI_ASSERT(rac != NULL);
495  BlockAffineComponent *bac = new BlockAffineComponent(*rac);
496  // following call deletes rac
497  nnet->SetComponent(i, bac);
498  } else if (const_c->Type() == "CompositeComponent") {
499  // We must modify the composite component, so we use the
500  // non-const GetComponent() call here.
501  Component *c = nnet->GetComponent(i);
502  CompositeComponent *cc = dynamic_cast<CompositeComponent*>(c);
503  KALDI_ASSERT(cc != NULL);
505  }
506  }
507 }
void ConvertRepeatedToBlockAffine(Nnet *nnet)
Convert all components of type RepeatedAffineComponent or NaturalGradientRepeatedAffineComponent to B...
Definition: nnet-utils.cc:485
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
bool ConvertToIndexes ( const std::vector< std::pair< int32, int32 > > &  location_vector,
int32 *  first_value,
std::vector< int32 > *  second_values 
)

If it is the case for some i >= 0 that all the .first elements of "location_vector" are either i or -1, then output i to first_value and the .second elements into "second_values", and return true.

Otherwise return false and the outputs are don't-cares.

Definition at line 377 of file nnet-compile-utils.cc.

Referenced by Compiler::DoBackwardComputationFromSubmatLocations(), Compiler::DoForwardComputationFromSubmatLocations(), SplitLocationsBackward(), UnitTestSplitLocations(), and UnitTestSplitLocationsBackward().

380  {
381  *first_value = -1;
382  second_values->clear();
383  second_values->reserve(location_vector.size());
384  std::vector<std::pair<int32, int32> >::const_iterator iter;
385  for (iter = location_vector.begin(); iter < location_vector.end(); ++iter) {
386  if (iter->first != -1) {
387  if (*first_value == -1)
388  *first_value = iter->first;
389  if (iter->first != *first_value)
390  return false;
391  second_values->push_back(iter->second);
392  } else {
393  second_values->push_back(-1);
394  }
395  }
396  return true;
397 }
static void kaldi::nnet3::CopyPairVector ( const CuArray< Int32Pair > &  in,
std::vector< std::pair< int32, int32 > > *  out 
)
static

Definition at line 31 of file nnet-general-component.cc.

References CuArray< T >::CopyToVec().

Referenced by StatisticsExtractionComponentPrecomputedIndexes::Read(), StatisticsPoolingComponentPrecomputedIndexes::Read(), StatisticsExtractionComponentPrecomputedIndexes::Write(), and StatisticsPoolingComponentPrecomputedIndexes::Write().

32  {
33  in.CopyToVec(reinterpret_cast<std::vector<Int32Pair>*>(out));
34 }
void CopyToVec(std::vector< T > *dst) const
This function resizes *dst if needed.
Definition: cu-array-inl.h:133
static void kaldi::nnet3::CopyPairVector ( const std::vector< std::pair< int32, int32 > > &  in,
CuArray< Int32Pair > *  out 
)
static

Definition at line 36 of file nnet-general-component.cc.

References CuArray< T >::CopyFromVec().

37  {
38  const std::vector<Int32Pair> *in_cast =
39  reinterpret_cast<const std::vector<Int32Pair>*>(&in);
40  out->CopyFromVec(*in_cast);
41 }
void CopyFromVec(const std::vector< T > &src)
This function resizes if needed.
Definition: cu-array-inl.h:98
bool DescriptorTokenize ( const std::string &  input,
std::vector< std::string > *  tokens 
)

This function tokenizes input when parsing Descriptor configuration values.

A token in this context is not the same as a generic Kaldi token, e.g. as defined in IsToken() in util/text_utils.h, which just means a non-empty whitespace-free string. Here a token is more like a programming-language token, and currently the following are allowed as tokens: "(" ")" ","

  • A nonempty string beginning with A-Za-z_, and containing only -_A-Za-z0-9.
  • An integer, optionally beginning with - or + and then a nonempty sequence of 0-9.

This function should return false and print an informative error with local context if it can't tokenize the input.

Definition at line 377 of file nnet-parse.cc.

References kaldi::ConvertStringToInteger(), ErrorContext(), IsValidName(), KALDI_ASSERT, and KALDI_WARN.

Referenced by NormalizeTextDescriptor(), Nnet::ProcessComponentNodeConfigLine(), Nnet::ProcessOutputNodeConfigLine(), Nnet::RemoveSomeNodes(), UnitTestDescriptorIo(), UnitTestDescriptorTokenize(), and UnitTestGeneralDescriptor().

378  {
379  KALDI_ASSERT(tokens != NULL);
380  size_t start = input.find_first_not_of(" \t"), size = input.size();
381  tokens->clear();
382  while (start < size) {
383  KALDI_ASSERT(!isspace(input[start]));
384  if (input[start] == '(' || input[start] == ')' || input[start] == ',') {
385  tokens->push_back(std::string(input, start, 1));
386  start = input.find_first_not_of(" \t", start + 1);
387  } else {
388  size_t found = input.find_first_of(" \t(),", start);
389  KALDI_ASSERT(found != start);
390  if (found == std::string::npos) {
391  std::string str(input, start, input.size() - start);
392  int32 tmp;
393  if (!IsValidName(str) && !ConvertStringToInteger(str, &tmp)) {
394  KALDI_WARN << "Could not parse line " << ErrorContext(std::string(input, start));
395  return false;
396  }
397  tokens->push_back(str);
398  break;
399  } else {
400  if (input[found] == '(' || input[found] == ')' || input[found] == ',') {
401  std::string str(input, start, found - start);
402  int32 tmp;
403  if (!IsValidName(str) && !ConvertStringToInteger(str, &tmp)) {
404  KALDI_WARN << "Could not parse line " << ErrorContext(std::string(input, start));
405  return false;
406  }
407  tokens->push_back(str);
408  start = found;
409  } else {
410  std::string str(input, start, found - start);
411  int32 tmp;
412  if (!IsValidName(str) && !ConvertStringToInteger(str, &tmp)) {
413  KALDI_WARN << "Could not parse line " << ErrorContext(std::string(input, start));
414  return false;
415  }
416  tokens->push_back(str);
417  start = input.find_first_not_of(" \t", found);
418  }
419  }
420  }
421  }
422  return true;
423 }
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:114
std::string ErrorContext(const std::string &str)
Definition: nnet-parse.cc:461
#define KALDI_WARN
Definition: kaldi-error.h:130
bool IsValidName(const std::string &name)
Returns true if 'name' would be a valid name for a component or node in a Nnet.
Definition: nnet-parse.cc:425
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
BaseFloat DotProduct ( const Nnet &  nnet1,
const Nnet &  nnet2 
)

Returns dot product between two networks of the same structure (calls the DotProduct functions of the Updatable components and sums up the return values).

Definition at line 227 of file nnet-utils.cc.

References UpdatableComponent::DotProduct(), Nnet::GetComponent(), KALDI_ASSERT, kUpdatableComponent, Nnet::NumComponents(), and Component::Properties().

Referenced by NnetDiscriminativeTrainer::Train(), and UnitTestNnetModelDerivatives().

228  {
229  KALDI_ASSERT(nnet1.NumComponents() == nnet2.NumComponents());
230  BaseFloat ans = 0.0;
231  for (int32 c = 0; c < nnet1.NumComponents(); c++) {
232  const Component *comp1 = nnet1.GetComponent(c),
233  *comp2 = nnet2.GetComponent(c);
234  if (comp1->Properties() & kUpdatableComponent) {
235  const UpdatableComponent
236  *u_comp1 = dynamic_cast<const UpdatableComponent*>(comp1),
237  *u_comp2 = dynamic_cast<const UpdatableComponent*>(comp2);
238  KALDI_ASSERT(u_comp1 != NULL && u_comp2 != NULL);
239  ans += u_comp1->DotProduct(*u_comp2);
240  }
241  }
242  return ans;
243 }
float BaseFloat
Definition: kaldi-types.h:29
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void EnsureContiguousProperty ( const std::vector< int32 > &  indexes,
std::vector< std::vector< int32 > > *  indexes_out 
)

This function takes a vector of indexes and splits it up into as separate vectors of the same size, as needed to ensure that the 'contiguous property' holds.

This is done via padding with -1's. An example will clarify this. Suppose the input is: [ -1 1 1 1 2 2 1 1 ] which lacks the contiguous property because 1's appear in 2 different places, it would split it up as [ -1 1 1 1 2 2 -1 -1 ] [ -1 -1 -1 -1 -1 -1 1 1 ] If 'indexes' is empty or only contains -1's, 'indexes_out' will be empty.

Definition at line 401 of file nnet-compile-utils.cc.

References rnnlm::i.

Referenced by SplitLocationsBackward(), and UnitTestEnsureContiguousProperty().

403  {
404  indexes_out->clear();
405  indexes_out->reserve(3);
406  if (indexes.empty()) return;
407  int32 max_value = *std::max_element(indexes.begin(), indexes.end());
408  if (max_value == -1) return;
409  std::vector<int32> num_segments_seen(max_value + 1, 0);
410  int32 dim = indexes.size(), num_output_vectors = 0;
411  for (int32 i = 0; i < dim;) {
412  // note, we increment i within the loop.
413  if (indexes[i] == -1) {
414  i++;
415  continue;
416  }
417  int32 value = indexes[i], start_index = i;
418  for (; i < dim && indexes[i] == value; i++);
419  int32 end_index = i; // one past the end.
420  // the input 'indexes' contains a sequence of possibly-repeated instances of
421  // the value 'value', starting at index 'start_index', with 'end_index' as
422  // one past the end.
423  int32 this_num_segments_seen = num_segments_seen[value]++;
424  if (this_num_segments_seen >= num_output_vectors) { // we have nowhere to
425  // put it.
426  indexes_out->resize(++num_output_vectors);
427  indexes_out->back().resize(dim, -1); // fill newly added vector with -1's.
428  }
429  std::vector<int32> &this_out_vec((*indexes_out)[this_num_segments_seen]);
430  std::vector<int32>::iterator iter = this_out_vec.begin() + start_index,
431  end = this_out_vec.begin() + end_index;
432  // Fill the appropriate range of the output vector with 'value'
433  for (; iter != end; ++iter) *iter = value;
434  }
435 }
std::string ErrorContext ( std::istream &  is)

Return a string used in error messages.

Here, "is" will be from an istringstream derived from a single line or part of a line. If "is" is at EOF or in error state, this should just say "end of line", else if the contents of "is" before EOF is <20 characters it should return it all, else it should return the first 20 characters followed by "...".

Definition at line 451 of file nnet-parse.cc.

Referenced by DescriptorTokenize().

451  {
452  if (!is.good()) return "end of line";
453  char buf[21];
454  is.read(buf, 21);
455  if (is) {
456  return (std::string(buf, 20) + "...");
457  }
458  return std::string(buf, is.gcount());
459 }
std::string ErrorContext ( const std::string &  str)

Definition at line 461 of file nnet-parse.cc.

461  {
462  if (str.size() == 0) return "end of line";
463  if (str.size() <= 20) return str;
464  return std::string(str, 0, 20) + "...";
465 }
void EvaluateComputationRequest ( const Nnet &  nnet,
const ComputationRequest &  request,
std::vector< std::vector< bool > > *  is_computable 
)

Given an nnet and a computation request, this function works out which requested outputs in the computation request are computable; it outputs this information as a vector "is_computable" indexed by the same indexes as request.outputs.

It does this by executing some of the early stages of compilation.

Definition at line 66 of file nnet-utils.cc.

References ComputationGraphBuilder::Compute(), ComputationGraphBuilder::GetComputableInfo(), Nnet::GetNodeNames(), kaldi::GetVerboseLevel(), KALDI_VLOG, and ComputationGraph::Print().

Referenced by ComputeSimpleNnetContextForShift().

69  {
70  ComputationGraph graph;
71  ComputationGraphBuilder builder(nnet, request, &graph);
72  builder.Compute();
73  builder.GetComputableInfo(is_computable);
74  if (GetVerboseLevel() >= 2) {
75  std::ostringstream graph_pretty;
76  graph.Print(graph_pretty, nnet.GetNodeNames());
77  KALDI_VLOG(2) << "Graph is " << graph_pretty.str();
78  }
79 }
int32 GetVerboseLevel()
Definition: kaldi-error.h:69
#define KALDI_VLOG(v)
Definition: kaldi-error.h:136
bool ExampleApproxEqual ( const NnetExample &  eg1,
const NnetExample &  eg2,
BaseFloat  delta 
)

Returns true if the examples are approximately equal (only intended to be used in testing).

Definition at line 1517 of file nnet-test-utils.cc.

References kaldi::ApproxEqual(), NnetIo::features, GeneralMatrix::GetMatrix(), rnnlm::i, NnetIo::indexes, NnetExample::io, and NnetIo::name.

Referenced by UnitTestNnetExample().

1519  {
1520  if (eg1.io.size() != eg2.io.size())
1521  return false;
1522  for (size_t i = 0; i < eg1.io.size(); i++) {
1523  NnetIo io1 = eg1.io[i], io2 = eg2.io[i];
1524  if (io1.name != io2.name || io1.indexes != io2.indexes)
1525  return false;
1526  Matrix<BaseFloat> feat1, feat2;
1527  io1.features.GetMatrix(&feat1);
1528  io2.features.GetMatrix(&feat2);
1529  if (!ApproxEqual(feat1, feat2, delta))
1530  return false;
1531  }
1532  return true;
1533 }
static bool ApproxEqual(float a, float b, float relative_tolerance=0.001)
return abs(a - b) <= relative_tolerance * (abs(a)+abs(b)).
Definition: kaldi-math.h:262
void ExpectOneOrTwoTokens ( std::istream &  is,
bool  binary,
const std::string &  token1,
const std::string &  token2 
)

This function is like ExpectToken but for two tokens, and it will either accept token1 and then token2, or just token2.

This is useful in Read functions where the first token may already have been consumed.

Definition at line 224 of file nnet-parse.cc.

References ExpectToken(), KALDI_ASSERT, KALDI_ERR, and kaldi::ReadToken().

Referenced by PnormComponent::Read(), DistributeComponent::Read(), DropoutComponent::Read(), DistributeComponentPrecomputedIndexes::Read(), ElementwiseProductComponent::Read(), StatisticsExtractionComponent::Read(), StatisticsExtractionComponentPrecomputedIndexes::Read(), SumReduceComponent::Read(), StatisticsPoolingComponent::Read(), StatisticsPoolingComponentPrecomputedIndexes::Read(), NonlinearComponent::Read(), BackpropTruncationComponent::Read(), BackpropTruncationComponentPrecomputedIndexes::Read(), FixedAffineComponent::Read(), SumGroupComponent::Read(), FixedScaleComponent::Read(), FixedBiasComponent::Read(), ClipGradientComponent::Read(), PermuteComponent::Read(), and MaxpoolingComponent::Read().

226  {
227  KALDI_ASSERT(token1 != token2);
228  std::string temp;
229  ReadToken(is, binary, &temp);
230  if (temp == token1) {
231  ExpectToken(is, binary, token2);
232  } else {
233  if (temp != token2) {
234  KALDI_ERR << "Expecting token " << token1 << " or " << token2
235  << " but got " << temp;
236  }
237  }
238 }
void ReadToken(std::istream &is, bool binary, std::string *str)
ReadToken gets the next token and puts it in str (exception on failure).
Definition: io-funcs.cc:154
void ExpectToken(std::istream &is, bool binary, const char *token)
ExpectToken tries to read in the given token, and throws an exception on failure. ...
Definition: io-funcs.cc:188
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void kaldi::nnet3::ExpectToken ( const std::string &  token,
const std::string &  what_we_are_parsing,
const std::string **  next_token 
)
static

Definition at line 45 of file nnet-descriptor.cc.

References KALDI_ERR, and ParsingContext().

Referenced by ExpectOneOrTwoTokens(), GeneralDescriptor::Parse(), GeneralDescriptor::ParseFailover(), GeneralDescriptor::ParseIfDefined(), GeneralDescriptor::ParseOffset(), GeneralDescriptor::ParseReplaceIndex(), GeneralDescriptor::ParseRound(), AmNnetSimple::Read(), Index::Read(), NnetIo::Read(), PnormComponent::Read(), DistributeComponent::Read(), NnetExample::Read(), NnetDiscriminativeSupervision::Read(), IoSpecification::Read(), NnetChainSupervision::Read(), NnetOptimizeOptions::Read(), DropoutComponent::Read(), NnetDiscriminativeExample::Read(), NnetChainExample::Read(), ComputationRequest::Read(), DistributeComponentPrecomputedIndexes::Read(), ElementwiseProductComponent::Read(), Nnet::Read(), NormalizeComponent::Read(), StatisticsExtractionComponent::Read(), NnetComputation::MatrixInfo::Read(), NnetComputation::MatrixDebugInfo::Read(), NnetComputation::SubMatrixInfo::Read(), NnetComputation::Command::Read(), StatisticsExtractionComponentPrecomputedIndexes::Read(), SumReduceComponent::Read(), StatisticsPoolingComponent::Read(), NnetComputation::Read(), AffineComponent::Read(), StatisticsPoolingComponentPrecomputedIndexes::Read(), NonlinearComponent::Read(), BackpropTruncationComponent::Read(), BlockAffineComponent::Read(), BackpropTruncationComponentPrecomputedIndexes::Read(), RepeatedAffineComponent::Read(), NaturalGradientAffineComponent::Read(), FixedAffineComponent::Read(), FixedScaleComponent::Read(), FixedBiasComponent::Read(), ClipGradientComponent::Read(), PermuteComponent::Read(), PerElementScaleComponent::Read(), PerElementOffsetComponent::Read(), ConstantFunctionComponent::Read(), NaturalGradientPerElementScaleComponent::Read(), ConvolutionComponent::Read(), LstmNonlinearityComponent::Read(), MaxpoolingComponent::Read(), CompositeComponent::Read(), CachingOptimizingCompiler::ReadCache(), ReadCindexVector(), and ReadIndexVector().

47  {
48  if (**next_token != token)
49  KALDI_ERR << "Expected '" << token << "' while parsing "
50  << what_we_are_parsing << ", got "
51  << **next_token << ParsingContext(*next_token);
52  else // advance token pointer.
53  (*next_token)++;
54 }
static std::string ParsingContext(const std::string *token_ptr)
#define KALDI_ERR
Definition: kaldi-error.h:127
void kaldi::nnet3::ExtractGivenPairsFromSubmatLists ( std::vector< std::vector< std::pair< int32, int32 > >::iterator > &  input_iterator_list,
std::vector< std::vector< std::pair< int32, int32 > > > *  sorted_submat_lists,
std::vector< std::pair< int32, int32 > > *  list_of_pairs 
)

Definition at line 203 of file nnet-compile-utils.cc.

References rnnlm::i.

Referenced by SplitLocationsUsingSubmatHistogram().

207  {
208  list_of_pairs->reserve(sorted_submat_lists->size());
209  for (int32 i = 0; i < input_iterator_list.size(); i++) {
210  if (input_iterator_list[i] != (*sorted_submat_lists)[i].end()) {
211  // there was an element with the submat_index in the current list
212  list_of_pairs->push_back(*input_iterator_list[i]);
213  (*sorted_submat_lists)[i].erase(input_iterator_list[i]);
214  } else {
215  // insert a dummy element. Callers of this function expect the dummy
216  // element to be (-1, -1)
217  list_of_pairs->push_back(std::make_pair(-1, -1));
218  }
219  }
220 }
static void kaldi::nnet3::ExtractLastPairFromSubmatLists ( std::vector< std::vector< std::pair< int32, int32 > > > *  sorted_submat_lists,
std::vector< std::pair< int32, int32 > > *  list_of_pairs 
)
static

Definition at line 224 of file nnet-compile-utils.cc.

References rnnlm::i.

Referenced by SplitLocationsUsingSubmatHistogram().

226  {
227  list_of_pairs->reserve(sorted_submat_lists->size());
228  for (int32 i = 0; i < sorted_submat_lists->size(); i++) {
229  if ((*sorted_submat_lists)[i].size() == 0) {
230  // the value of the dummy has to be (-1, -1) as down stream code has
231  // expects -1 values for dummies
232  list_of_pairs->push_back(std::make_pair(-1, -1));
233  continue;
234  }
235  list_of_pairs->push_back((*sorted_submat_lists)[i].back());
236  (*sorted_submat_lists)[i].pop_back();
237  }
238 }
void kaldi::nnet3::FilterExample ( const NnetExample eg,
int32  min_input_t,
int32  max_input_t,
int32  min_output_t,
int32  max_output_t,
NnetExample eg_out 
)

This function filters the indexes (and associated feature rows) in a NnetExample, removing any index/row in an NnetIo named "input" with t < min_input_t or t > max_input_t and any index/row in an NnetIo named "output" with t < min_output_t or t > max_output_t.

Will crash if filtering removes all Indexes of "input" or "output".

Definition at line 111 of file nnet3-copy-egs.cc.

References NnetIo::features, kaldi::FilterGeneralMatrixRows(), rnnlm::i, NnetIo::indexes, NnetExample::io, KALDI_ASSERT, KALDI_ERR, NnetIo::name, and GeneralMatrix::NumRows().

Referenced by SelectFromExample().

116  {
117  eg_out->io.clear();
118  eg_out->io.resize(eg.io.size());
119  for (size_t i = 0; i < eg.io.size(); i++) {
120  bool is_input_or_output;
121  int32 min_t, max_t;
122  const NnetIo &io_in = eg.io[i];
123  NnetIo &io_out = eg_out->io[i];
124  const std::string &name = io_in.name;
125  io_out.name = name;
126  if (name == "input") {
127  min_t = min_input_t;
128  max_t = max_input_t;
129  is_input_or_output = true;
130  } else if (name == "output") {
131  min_t = min_output_t;
132  max_t = max_output_t;
133  is_input_or_output = true;
134  } else {
135  is_input_or_output = false;
136  }
137  if (!is_input_or_output) { // Just copy everything.
138  io_out.indexes = io_in.indexes;
139  io_out.features = io_in.features;
140  } else {
141  const std::vector<Index> &indexes_in = io_in.indexes;
142  std::vector<Index> &indexes_out = io_out.indexes;
143  indexes_out.reserve(indexes_in.size());
144  int32 num_indexes = indexes_in.size(), num_kept = 0;
145  KALDI_ASSERT(io_in.features.NumRows() == num_indexes);
146  std::vector<bool> keep(num_indexes, false);
147  std::vector<Index>::const_iterator iter_in = indexes_in.begin(),
148  end_in = indexes_in.end();
149  std::vector<bool>::iterator iter_out = keep.begin();
150  for (; iter_in != end_in; ++iter_in,++iter_out) {
151  int32 t = iter_in->t;
152  bool is_within_range = (t >= min_t && t <= max_t);
153  *iter_out = is_within_range;
154  if (is_within_range) {
155  indexes_out.push_back(*iter_in);
156  num_kept++;
157  }
158  }
159  KALDI_ASSERT(iter_out == keep.end());
160  if (num_kept == 0)
161  KALDI_ERR << "FilterExample removed all indexes for '" << name << "'";
162 
163  FilterGeneralMatrixRows(io_in.features, keep,
164  &io_out.features);
165  KALDI_ASSERT(io_out.features.NumRows() == num_kept &&
166  indexes_out.size() == static_cast<size_t>(num_kept));
167  }
168  }
169 }
GeneralMatrix features
The features or labels.
Definition: nnet-example.h:46
std::vector< Index > indexes
"indexes" is a vector the same length as features.NumRows(), explaining the meaning of each row of th...
Definition: nnet-example.h:42
void FilterGeneralMatrixRows(const GeneralMatrix &in, const std::vector< bool > &keep_rows, GeneralMatrix *out)
Outputs a GeneralMatrix containing only the rows r of "in" such that keep_rows[r] == true...
MatrixIndexT NumRows() const
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
std::string name
the name of the input in the neural net; in simple setups it will just be "input".
Definition: nnet-example.h:36
std::vector< NnetIo > io
"io" contains the input and output.
Definition: nnet-example.h:87
void FindOrphanComponents ( const Nnet &  nnet,
std::vector< int32 > *  components 
)

This function finds a list of components that are never used, and outputs the integer comopnent indexes (you can use these to index nnet.GetComponentNames() to get their names).

Definition at line 536 of file nnet-utils.cc.

References NetworkNode::component_index, Nnet::GetNode(), rnnlm::i, Nnet::IsComponentNode(), KALDI_ASSERT, Nnet::NumComponents(), Nnet::NumNodes(), and NetworkNode::u.

Referenced by Nnet::Check(), and Nnet::RemoveOrphanComponents().

536  {
537  int32 num_components = nnet.NumComponents(), num_nodes = nnet.NumNodes();
538  std::vector<bool> is_used(num_components, false);
539  for (int32 i = 0; i < num_nodes; i++) {
540  if (nnet.IsComponentNode(i)) {
541  int32 c = nnet.GetNode(i).u.component_index;
542  KALDI_ASSERT(c >= 0 && c < num_components);
543  is_used[c] = true;
544  }
545  }
546  components->clear();
547  for (int32 i = 0; i < num_components; i++)
548  if (!is_used[i])
549  components->push_back(i);
550 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void FindOrphanNodes ( const Nnet &  nnet,
std::vector< int32 > *  nodes 
)

This function finds a list of nodes that are never used to compute any output, and outputs the integer node indexes (you can use these to index nnet.GetNodeNames() to get their names).

Definition at line 552 of file nnet-utils.cc.

References ComputeGraphTranspose(), rnnlm::i, Nnet::IsOutputNode(), rnnlm::j, NnetToDirectedGraph(), and Nnet::NumNodes().

Referenced by Nnet::Check(), and Nnet::RemoveOrphanNodes().

552  {
553 
554  std::vector<std::vector<int32> > depend_on_graph, dependency_graph;
555  NnetToDirectedGraph(nnet, &depend_on_graph);
556  // depend_on_graph[i] is a list of all the nodes that depend on i.
557  ComputeGraphTranspose(depend_on_graph, &dependency_graph);
558  // dependency_graph[i] is a list of all the nodes that i depends on,
559  // to be computed.
560 
561  // Find all nodes required to produce the outputs.
562  int32 num_nodes = nnet.NumNodes();
563  assert(num_nodes == static_cast<int32>(dependency_graph.size()));
564  std::vector<bool> node_is_required(num_nodes, false);
565  std::vector<int32> queue;
566  for (int32 i = 0; i < num_nodes; i++) {
567  if (nnet.IsOutputNode(i))
568  queue.push_back(i);
569  }
570  while (!queue.empty()) {
571  int32 i = queue.back();
572  queue.pop_back();
573  if (!node_is_required[i]) {
574  node_is_required[i] = true;
575  for (size_t j = 0; j < dependency_graph[i].size(); j++)
576  queue.push_back(dependency_graph[i][j]);
577  }
578  }
579  nodes->clear();
580  for (int32 i = 0; i < num_nodes; i++) {
581  if (!node_is_required[i])
582  nodes->push_back(i);
583  }
584 }
void NnetToDirectedGraph(const Nnet &nnet, std::vector< std::vector< int32 > > *graph)
This function takes an nnet and turns it to a directed graph on nodes.
Definition: nnet-graph.cc:30
void ComputeGraphTranspose(const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *graph_transpose)
Outputs a graph in which the order of arcs is reversed.
Definition: nnet-graph.cc:63
void FindSccs ( const std::vector< std::vector< int32 > > &  graph,
std::vector< std::vector< int32 > > *  sccs 
)

Given a directed graph (where each std::vector<int32> is a list of destination-nodes of arcs coming from the current node), partition it into strongly connected components (i.e.

within each SCC, all nodes are reachable from all other nodes).

Definition at line 156 of file nnet-graph.cc.

References FindSccsTarjan(), and KALDI_ASSERT.

Referenced by ComputeNnetComputationEpochs(), and UnitTestFindSccs().

157  {
158  // Internally we call Tarjan's SCC algorithm, as it only requires one DFS. We
159  // can change this to other methods later on if necessary.
160  KALDI_ASSERT(sccs != NULL);
161  FindSccsTarjan(graph, sccs);
162 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void FindSccsTarjan(const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *sccs)
Definition: nnet-graph.cc:138
void kaldi::nnet3::FindSccsTarjan ( const std::vector< std::vector< int32 > > &  graph,
std::vector< std::vector< int32 > > *  sccs 
)

Definition at line 138 of file nnet-graph.cc.

References KALDI_ASSERT, rnnlm::n, and TarjanSccRecursive().

Referenced by FindSccs().

139  {
140  KALDI_ASSERT(sccs != NULL);
141 
142  // Initialization.
143  std::vector<TarjanNode> tarjan_nodes(graph.size());
144  std::vector<int32> tarjan_stack;
145  int32 global_index = 0;
146 
147  // Calls the recursive function.
148  for (int32 n = 0; n < graph.size(); ++n) {
149  if (tarjan_nodes[n].index == -1) {
150  TarjanSccRecursive(n, graph,
151  &global_index, &tarjan_nodes, &tarjan_stack, sccs);
152  }
153  }
154 }
struct rnnlm::@11::@12 n
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void TarjanSccRecursive(int32 node, const std::vector< std::vector< int32 > > &graph, int32 *global_index, std::vector< TarjanNode > *tarjan_nodes, std::vector< int32 > *tarjan_stack, std::vector< std::vector< int32 > > *sccs)
Definition: nnet-graph.cc:85
void kaldi::nnet3::FindSubmatIndexInSubmatLists ( int32  submat_index,
std::vector< std::vector< std::pair< int32, int32 > > > *  sorted_submat_lists,
std::vector< std::vector< std::pair< int32, int32 > >::iterator > *  output_iterator_list,
int32 *  max_remaining_submat_list_size 
)

Definition at line 167 of file nnet-compile-utils.cc.

References rnnlm::i.

Referenced by SplitLocationsUsingSubmatHistogram().

177  {
178 
179  output_iterator_list->reserve(sorted_submat_lists->size());
180  *max_remaining_submat_list_size = 0;
181  for (int32 i = 0; i < sorted_submat_lists->size(); i++) {
182  std::vector< std::pair<int32, int32> > & submat_list =
183  (*sorted_submat_lists)[i];
184  output_iterator_list->push_back(
185  std::find_if(submat_list.begin(), submat_list.end(),
186  FirstElementIsEqualComparator(submat_index)));
187  int32 remaining_submat_list_size = submat_list.size();
188  if (output_iterator_list->back() != submat_list.end()) {
189  // since the submat_index is present in this submat_list
190  // if submat_index was deleted from the list
191  // the remaining submat_list's size is reduced by 1
192  remaining_submat_list_size--;
193  }
194  *max_remaining_submat_list_size = remaining_submat_list_size
195  > *max_remaining_submat_list_size ? remaining_submat_list_size :
196  *max_remaining_submat_list_size;
197  }
198 }
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 is the initial nnet, and the remaining ones may do things like add layers.

Definition at line 973 of file nnet-test-utils.cc.

References NnetGenerationOptions::allow_context, NnetGenerationOptions::allow_nonlinearity, NnetGenerationOptions::allow_recursion, GenerateConfigSequenceCnn(), GenerateConfigSequenceCompositeBlock(), GenerateConfigSequenceDistribute(), GenerateConfigSequenceLstm(), GenerateConfigSequenceLstmWithTruncation(), GenerateConfigSequenceRnn(), GenerateConfigSequenceRnnClockwork(), GenerateConfigSequenceSimple(), GenerateConfigSequenceSimpleContext(), GenerateConfigSequenceSimplest(), GenerateConfigSequenceStatistics(), KALDI_ASSERT, KALDI_ERR, and kaldi::RandInt().

Referenced by UnitTestNnetAnalyze(), UnitTestNnetCompile(), UnitTestNnetCompute(), UnitTestNnetContext(), UnitTestNnetInputDerivatives(), UnitTestNnetIo(), UnitTestNnetModelDerivatives(), and UnitTestNnetOptimizeWithOptions().

975  {
976 start:
977  int32 network_type = RandInt(0, 11);
978  switch(network_type) {
979  case 0:
980  GenerateConfigSequenceSimplest(opts, configs);
981  break;
982  case 1:
983  if (!opts.allow_context)
984  goto start;
986  break;
987  case 2:
988  if (!opts.allow_context || !opts.allow_nonlinearity)
989  goto start;
990  GenerateConfigSequenceSimple(opts, configs);
991  break;
992  case 3:
993  if (!opts.allow_recursion || !opts.allow_context ||
994  !opts.allow_nonlinearity)
995  goto start;
996  GenerateConfigSequenceRnn(opts, configs);
997  break;
998  case 4:
999  if (!opts.allow_recursion || !opts.allow_context ||
1000  !opts.allow_nonlinearity)
1001  goto start;
1002  GenerateConfigSequenceRnnClockwork(opts, configs);
1003  break;
1004  case 5:
1005  if (!opts.allow_recursion || !opts.allow_context ||
1006  !opts.allow_nonlinearity)
1007  goto start;
1008  GenerateConfigSequenceLstm(opts, configs);
1009  break;
1010  case 6:
1011  if (!opts.allow_recursion || !opts.allow_context ||
1012  !opts.allow_nonlinearity)
1013  goto start;
1014  GenerateConfigSequenceLstm(opts, configs);
1015  break;
1016  case 7:
1017  if (!opts.allow_nonlinearity)
1018  goto start;
1019  GenerateConfigSequenceCnn(opts, configs);
1020  break;
1021  case 8:
1022  GenerateConfigSequenceDistribute(opts, configs);
1023  break;
1024  case 9:
1025  GenerateConfigSequenceCompositeBlock(opts, configs);
1026  break;
1027  case 10:
1028  GenerateConfigSequenceStatistics(opts, configs);
1029  break;
1030  case 11:
1031  if (!opts.allow_recursion || !opts.allow_context ||
1032  !opts.allow_nonlinearity)
1033  goto start;
1035  break;
1036  default:
1037  KALDI_ERR << "Error generating config sequence.";
1038  }
1039  KALDI_ASSERT(!configs->empty());
1040 }
void GenerateConfigSequenceLstm(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
void GenerateConfigSequenceRnnClockwork(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
void GenerateConfigSequenceLstmWithTruncation(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
void GenerateConfigSequenceSimpleContext(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
void GenerateConfigSequenceDistribute(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
void GenerateConfigSequenceRnn(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
void GenerateConfigSequenceCnn(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
#define KALDI_ERR
Definition: kaldi-error.h:127
void GenerateConfigSequenceStatistics(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
void GenerateConfigSequenceSimplest(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void GenerateConfigSequenceSimple(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
void GenerateConfigSequenceCompositeBlock(const NnetGenerationOptions &opts, std::vector< std::string > *configs)
Generate a config string with a composite component composed only of block affine, repeated affine, and natural gradient repeated affine components.
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:100
void kaldi::nnet3::GenerateConfigSequenceCnn ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 828 of file nnet-test-utils.cc.

References kaldi::Rand().

Referenced by GenerateConfigSequence().

830  {
831  std::ostringstream os;
832 
833 
834  int32 input_x_dim = 10 + Rand() % 20,
835  input_y_dim = 10 + Rand() % 20,
836  input_z_dim = 3 + Rand() % 10,
837  filt_x_dim = 1 + Rand() % input_x_dim,
838  filt_y_dim = 1 + Rand() % input_y_dim,
839  num_filters = 10 + Rand() % 20,
840  filt_x_step = (1 + Rand() % filt_x_dim),
841  filt_y_step = (1 + Rand() % filt_y_dim);
842  int32 remainder = (input_x_dim - filt_x_dim) % filt_x_step;
843  // adjusting input_x_dim to ensure divisibility
844  input_x_dim = input_x_dim - remainder;
845  remainder = (input_y_dim - filt_y_dim) % filt_y_step;
846  // adjusting input_x_dim to ensure divisibility
847  input_y_dim = input_y_dim - remainder;
848 
849  int32 input_vectorization = Rand() % 2;
850  std::string vectorization;
851  if (input_vectorization == 0) {
852  vectorization = "yzx";
853  } else {
854  vectorization = "zyx";
855  }
856 
857  os << "component name=conv type=ConvolutionComponent "
858  << " input-x-dim=" << input_x_dim
859  << " input-y-dim=" << input_y_dim
860  << " input-z-dim=" << input_z_dim
861  << " filt-x-dim=" << filt_x_dim
862  << " filt-y-dim=" << filt_y_dim
863  << " filt-x-step=" << filt_x_step
864  << " filt-y-step=" << filt_y_step
865  << " num-filters=" << num_filters
866  << " input-vectorization-order=" << vectorization
867  << std::endl;
868 
869  int32 conv_output_x_dim = (1 + (input_x_dim - filt_x_dim) / filt_x_step);
870  int32 conv_output_y_dim = (1 + (input_y_dim - filt_y_dim) / filt_y_step);
871  int32 conv_output_z_dim = num_filters;
872  int32 pool_x_size = 1 + Rand() % conv_output_x_dim;
873  int32 pool_y_size = 1 + Rand() % conv_output_y_dim;
874  int32 pool_z_size = 1 + Rand() % conv_output_z_dim;
875  int32 pool_x_step = 1;
876  int32 pool_y_step = 1;
877  int32 pool_z_step = 1;
878  do {
879  pool_x_step = (1 + Rand() % pool_x_size);
880  } while((conv_output_x_dim - pool_x_size) % pool_x_step);
881  do {
882  pool_y_step = (1 + Rand() % pool_y_size);
883  } while((conv_output_y_dim - pool_y_size) % pool_y_step);
884  do {
885  pool_z_step = (1 + Rand() % pool_z_size);
886  } while((conv_output_z_dim - pool_z_size) % pool_z_step);
887 
888  os << "component name=maxpooling type=MaxpoolingComponent "
889  << " input-x-dim=" << conv_output_x_dim
890  << " input-y-dim=" << conv_output_y_dim
891  << " input-z-dim=" << conv_output_z_dim
892  << " pool-x-size=" << pool_x_size
893  << " pool-y-size=" << pool_y_size
894  << " pool-z-size=" << pool_z_size
895  << " pool-x-step=" << pool_x_step
896  << " pool-y-step=" << pool_y_step
897  << " pool-z-step=" << pool_z_step
898  << std::endl;
899 
900  os << "input-node name=input dim=" << (input_x_dim * input_y_dim * input_z_dim) << std::endl;
901  os << "component-node name=conv_node component=conv input=input\n";
902  os << "component-node name=maxpooling_node component=maxpooling input=conv_node\n";
903  os << "output-node name=output input=conv_node\n";
904  configs->push_back(os.str());
905 }
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
void GenerateConfigSequenceCompositeBlock ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Generate a config string with a composite component composed only of block affine, repeated affine, and natural gradient repeated affine components.

Definition at line 934 of file nnet-test-utils.cc.

References rnnlm::i, KALDI_WARN, NnetGenerationOptions::output_dim, and kaldi::RandInt().

Referenced by GenerateConfigSequence(), and UnitTestConvertRepeatedToBlockAffineComposite().

935  {
936  int32 num_components = RandInt(1,5);
937  int32 input_dim = 10 * RandInt(1,10);
938  if (opts.output_dim > 0) {
939  KALDI_WARN << "This function doesn't take a requested output_dim due to "
940  "implementation complications.";
941  }
942  int32 max_rows_process = 512 + 512 * RandInt(1,3);
943  std::ostringstream os;
944  os << "component name=composite1 type=CompositeComponent max-rows-process="
945  << max_rows_process << " num-components=" << num_components;
946 
947  int32 types_length = 3;
948  std::string types[] = {"BlockAffineComponent",
949  "RepeatedAffineComponent",
950  "NaturalGradientRepeatedAffineComponent"};
951  int32 last_output_dim = input_dim;
952  // components within a composite component are indexed from 1.
953  for(int32 i = 1; i <= num_components; i++) {
954  os << " component" << i << "=";
955  int32 rand_index = RandInt(0, types_length - 1);
956  std::string rand_type = types[rand_index];
957  os << "'type=" << rand_type << " input-dim=" << last_output_dim;
958  int32 current_output_dim = 10 * RandInt(1,10);
959  // must be a divisor or current_output_dim and last_output_dim
960  int32 num_repeats = 10;
961  os << " output-dim=" << current_output_dim;
962  std::string repeats_string = (rand_type == "BlockAffineComponent") ? "num-blocks": "num-repeats";
963  os << " " << repeats_string << "=" << num_repeats << "'";
964  last_output_dim = current_output_dim;
965  }
966  os << std::endl << std::endl;
967  os << "input-node name=input dim=" << input_dim << std::endl;
968  os << "component-node name=composite1 component=composite1 input=input\n";
969  os << "output-node name=output input=composite1\n";
970  configs->push_back(os.str());
971 }
#define KALDI_WARN
Definition: kaldi-error.h:130
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:100
void kaldi::nnet3::GenerateConfigSequenceDistribute ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 908 of file nnet-test-utils.cc.

References rnnlm::i, NnetGenerationOptions::output_dim, and kaldi::RandInt().

Referenced by GenerateConfigSequence().

910  {
911  int32 output_dim = (opts.output_dim > 0 ? opts.output_dim : 100);
912  int32 x_expand = RandInt(1, 5), after_expand_dim = RandInt(10, 20),
913  input_dim = x_expand * after_expand_dim;
914  std::ostringstream os;
915  os << "input-node name=input dim=" << input_dim << std::endl;
916  os << "component name=distribute type=DistributeComponent input-dim="
917  << input_dim << " output-dim=" << after_expand_dim << std::endl;
918  os << "component-node name=distribute component=distribute input=input\n";
919  os << "component name=affine type=AffineComponent input-dim="
920  << after_expand_dim << " output-dim=" << output_dim << std::endl;
921  os << "component-node name=affine component=affine input=distribute\n";
922  os << "output-node name=output input=Sum(";
923  for (int32 i = 0; i < x_expand; i++) {
924  if (i > 0) os << ", ";
925  os << "ReplaceIndex(affine, x, " << i << ")";
926  }
927  os << ")\n";
928  configs->push_back(os.str());
929 }
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:100
void kaldi::nnet3::GenerateConfigSequenceLstm ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 361 of file nnet-test-utils.cc.

References rnnlm::i, NnetGenerationOptions::output_dim, and kaldi::Rand().

Referenced by GenerateConfigSequence().

363  {
364  std::ostringstream os;
365 
366  std::vector<int32> splice_context;
367  for (int32 i = -5; i < 4; i++)
368  if (Rand() % 3 == 0)
369  splice_context.push_back(i);
370  if (splice_context.empty())
371  splice_context.push_back(0);
372 
373  int32 input_dim = 10 + Rand() % 20,
374  spliced_dim = input_dim * splice_context.size(),
375  output_dim = (opts.output_dim > 0 ?
376  opts.output_dim :
377  100 + Rand() % 200),
378  cell_dim = 40 + Rand() % 50,
379  projection_dim = std::ceil(cell_dim / (Rand() % 10 + 1));
380 
381  os << "input-node name=input dim=" << input_dim << std::endl;
382 
383  // Parameter Definitions W*(* replaced by - to have valid names)
384  // Input gate control : Wi* matrices
385  os << "component name=Wi-xr type=NaturalGradientAffineComponent"
386  << " input-dim=" << spliced_dim + projection_dim
387  << " output-dim=" << cell_dim << std::endl;
388  os << "component name=Wic type=PerElementScaleComponent "
389  << " dim=" << cell_dim << std::endl;
390 
391  // Forget gate control : Wf* matrices
392  os << "component name=Wf-xr type=NaturalGradientAffineComponent"
393  << " input-dim=" << spliced_dim + projection_dim
394  << " output-dim=" << cell_dim << std::endl;
395  os << "component name=Wfc type=PerElementScaleComponent "
396  << " dim=" << cell_dim << std::endl;
397 
398  // Output gate control : Wo* matrices
399  os << "component name=Wo-xr type=NaturalGradientAffineComponent"
400  << " input-dim=" << spliced_dim + projection_dim
401  << " output-dim=" << cell_dim << std::endl;
402  os << "component name=Woc type=PerElementScaleComponent "
403  << " dim=" << cell_dim << std::endl;
404 
405  // Cell input matrices : Wc* matrices
406  os << "component name=Wc-xr type=NaturalGradientAffineComponent"
407  << " input-dim=" << spliced_dim + projection_dim
408  << " output-dim=" << cell_dim << std::endl;
409 
410 
411 
412  // projection matrices : Wrm and Wpm
413  os << "component name=W-m type=NaturalGradientAffineComponent "
414  << " input-dim=" << cell_dim
415  << " output-dim=" << 2 * projection_dim << std::endl;
416 
417  // Output : Wyr and Wyp
418  os << "component name=Wy- type=NaturalGradientAffineComponent "
419  << " input-dim=" << 2 * projection_dim
420  << " output-dim=" << cell_dim << std::endl;
421 
422  // Defining the diagonal matrices
423  // Defining the final affine transform
424  os << "component name=final_affine type=NaturalGradientAffineComponent "
425  << "input-dim=" << cell_dim << " output-dim=" << output_dim << std::endl;
426  os << "component name=logsoftmax type=LogSoftmaxComponent dim="
427  << output_dim << std::endl;
428 
429  // Defining the non-linearities
430  // declare a no-op component so that we can use a sum descriptor's output
431  // multiple times, and to make the config more readable given the equations
432  os << "component name=i type=SigmoidComponent dim="
433  << cell_dim << std::endl;
434  os << "component name=f type=SigmoidComponent dim="
435  << cell_dim << std::endl;
436  os << "component name=o type=SigmoidComponent dim="
437  << cell_dim << std::endl;
438  os << "component name=g type=TanhComponent dim="
439  << cell_dim << std::endl;
440  os << "component name=h type=TanhComponent dim="
441  << cell_dim << std::endl;
442  os << "component name=c1 type=ElementwiseProductComponent "
443  << " input-dim=" << 2 * cell_dim
444  << " output-dim=" << cell_dim << std::endl;
445  os << "component name=c2 type=ElementwiseProductComponent "
446  << " input-dim=" << 2 * cell_dim
447  << " output-dim=" << cell_dim << std::endl;
448  os << "component name=m type=ElementwiseProductComponent "
449  << " input-dim=" << 2 * cell_dim
450  << " output-dim=" << cell_dim << std::endl;
451 
452  // Defining the computations
453  std::ostringstream temp_string_stream;
454  for (size_t i = 0; i < splice_context.size(); i++) {
455  int32 offset = splice_context[i];
456  temp_string_stream << "Offset(input, " << offset << ")";
457  if (i + 1 < splice_context.size())
458  temp_string_stream << ", ";
459  }
460  std::string spliced_input = temp_string_stream.str();
461 
462  std::string c_tminus1 = "Sum(IfDefined(Offset(c1_t, -1)), IfDefined(Offset( c2_t, -1)))";
463 
464  // i_t
465  os << "component-node name=i1 component=Wi-xr input=Append("
466  << spliced_input << ", IfDefined(Offset(r_t, -1)))\n";
467  os << "component-node name=i2 component=Wic "
468  << " input=" << c_tminus1 << std::endl;
469  os << "component-node name=i_t component=i input=Sum(i1, i2)\n";
470 
471  // f_t
472  os << "component-node name=f1 component=Wf-xr input=Append("
473  << spliced_input << ", IfDefined(Offset(r_t, -1)))\n";
474  os << "component-node name=f2 component=Wfc "
475  << " input=" << c_tminus1 << std::endl;
476  os << "component-node name=f_t component=f input=Sum(f1, f2)\n";
477 
478  // o_t
479  os << "component-node name=o1 component=Wo-xr input=Append("
480  << spliced_input << ", IfDefined(Offset(r_t, -1)))\n";
481  os << "component-node name=o2 component=Woc input=Sum(c1_t, c2_t)\n";
482  os << "component-node name=o_t component=o input=Sum(o1, o2)\n";
483 
484  // h_t
485  os << "component-node name=h_t component=h input=Sum(c1_t, c2_t)\n";
486 
487  // g_t
488  os << "component-node name=g1 component=Wc-xr input=Append("
489  << spliced_input << ", IfDefined(Offset(r_t, -1)))\n";
490  os << "component-node name=g_t component=g input=g1\n";
491 
492  // parts of c_t
493  os << "component-node name=c1_t component=c1 "
494  << " input=Append(f_t, " << c_tminus1 << ")\n";
495  os << "component-node name=c2_t component=c2 input=Append(i_t, g_t)\n";
496 
497  // m_t
498  os << "component-node name=m_t component=m input=Append(o_t, h_t)\n";
499 
500  // r_t and p_t
501  os << "component-node name=rp_t component=W-m input=m_t\n";
502  // Splitting outputs of Wy- node
503  os << "dim-range-node name=r_t input-node=rp_t dim-offset=0 "
504  << "dim=" << projection_dim << std::endl;
505 
506  // y_t
507  os << "component-node name=y_t component=Wy- input=rp_t\n";
508 
509  // Final affine transform
510  os << "component-node name=final_affine component=final_affine input=y_t\n";
511  os << "component-node name=posteriors component=logsoftmax input=final_affine\n";
512  os << "output-node name=output input=posteriors\n";
513  configs->push_back(os.str());
514 }
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
void kaldi::nnet3::GenerateConfigSequenceLstmType2 ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 690 of file nnet-test-utils.cc.

References rnnlm::i, KALDI_ERR, NnetGenerationOptions::output_dim, and kaldi::Rand().

692  {
693  KALDI_ERR << "Not Implemented";
694  std::ostringstream os;
695 
696  std::vector<int32> splice_context;
697  for (int32 i = -5; i < 4; i++)
698  if (Rand() % 3 == 0)
699  splice_context.push_back(i);
700  if (splice_context.empty())
701  splice_context.push_back(0);
702 
703  int32 input_dim = 10 + Rand() % 20,
704  spliced_dim = input_dim * splice_context.size(),
705  output_dim = (opts.output_dim > 0 ?
706  opts.output_dim :
707  100 + Rand() % 200),
708  cell_dim = 40 + Rand() % 50,
709  projection_dim = std::ceil(cell_dim / (Rand() % 10 + 2));
710 
711  os << "input-node name=input dim=" << input_dim << std::endl;
712  // Parameter Definitions W*(* replaced by - to have valid names)
713  os << "component name=W-x type=NaturalGradientAffineComponent input-dim="
714  << spliced_dim << " output-dim=" << 4 * cell_dim << std::endl;
715  os << "component name=W-r type=NaturalGradientAffineComponent input-dim="
716  << projection_dim << " output-dim=" << 4 * cell_dim << std::endl;
717  os << "component name=W-m type=NaturalGradientAffineComponent input-dim="
718  << cell_dim << " output-dim=" << 2 * projection_dim << std::endl;
719  os << "component name=Wyr type=NaturalGradientAffineComponent input-dim="
720  << projection_dim << " output-dim=" << cell_dim << std::endl;
721  os << "component name=Wyp type=NaturalGradientAffineComponent input-dim="
722  << projection_dim << " output-dim=" << cell_dim << std::endl;
723  // Defining the diagonal matrices
724  os << "component name=Wic type=PerElementScaleComponent "
725  << " dim=" << cell_dim << std::endl;
726  os << "component name=Wfc type=PerElementScaleComponent "
727  << " dim=" << cell_dim << std::endl;
728  os << "component name=Woc type=PerElementScaleComponent "
729  << " dim=" << cell_dim << std::endl;
730  // Defining the final affine transform
731  os << "component name=final_affine type=NaturalGradientAffineComponent "
732  << "input-dim=" << cell_dim << " output-dim=" << output_dim << std::endl;
733  os << "component name=logsoftmax type=LogSoftmaxComponent dim="
734  << output_dim << std::endl;
735 
736  // Defining the non-linearities
737  // declare a no-op component so that we can use a sum descriptor's output
738  // multiple times, and to make the config more readable given the equations
739  os << "component name=c_t type=NoOpComponent dim="
740  << cell_dim << std::endl;
741  os << "component name=i_t type=SigmoidComponent dim="
742  << cell_dim << std::endl;
743  os << "component name=f_t type=SigmoidComponent dim="
744  << cell_dim << std::endl;
745  os << "component name=o_t type=SigmoidComponent dim="
746  << cell_dim << std::endl;
747  os << "component name=g type=TanhComponent dim="
748  << cell_dim << std::endl;
749  os << "component name=h type=TanhComponent dim="
750  << cell_dim << std::endl;
751  os << "component name=f_t-c_tminus1 type=ElementwiseProductComponent "
752  << " input-dim=" << 2 * cell_dim
753  << " output-dim=" << cell_dim << std::endl;
754  os << "component name=i_t-g type=ElementwiseProductComponent "
755  << " input-dim=" << 2 * cell_dim
756  << " output-dim=" << cell_dim << std::endl;
757  os << "component name=m_t type=ElementwiseProductComponent "
758  << " input-dim=" << 2 * cell_dim
759  << " output-dim=" << cell_dim << std::endl;
760 
761 
762  // Defining the computations
763  os << "component-node name=W-x component=W-x input=Append(";
764  for (size_t i = 0; i < splice_context.size(); i++) {
765  int32 offset = splice_context[i];
766  os << "Offset(input, " << offset << ")";
767  if (i + 1 < splice_context.size())
768  os << ", ";
769  }
770  os << ")\n";
771 
772  os << "component-node name=W-r component=W-r input=IfDefined(Offset(r_t, -1))\n";
773  os << "component-node name=W-m component=W-m input=m_t \n";
774  os << "component-node name=Wic component=Wic input=IfDefined(Offset(c_t, -1))\n";
775  os << "component-node name=Wfc component=Wfc input=IfDefined(Offset(c_t, -1))\n";
776  os << "component-node name=Woc component=Woc input=c_t\n";
777 
778  // Splitting the outputs of W*m node
779  os << "dim-range-node name=r_t input-node=W-m dim-offset=0 "
780  << "dim=" << projection_dim << std::endl;
781  os << "dim-range-node name=p_t input-node=W-m dim-offset=" << projection_dim
782  << " dim=" << projection_dim << std::endl;
783 
784  // Splitting outputs of W*x node
785  os << "dim-range-node name=W_ix-x_t input-node=W-x dim-offset=0 "
786  << "dim=" << cell_dim << std::endl;
787  os << "dim-range-node name=W_fx-x_t input-node=W-x "
788  << "dim-offset=" << cell_dim << " dim="<<cell_dim << std::endl;
789  os << "dim-range-node name=W_cx-x_t input-node=W-x "
790  << "dim-offset=" << 2 * cell_dim << " dim="<<cell_dim << std::endl;
791  os << "dim-range-node name=W_ox-x_t input-node=W-x "
792  << "dim-offset=" << 3 * cell_dim << " dim="<<cell_dim << std::endl;
793 
794  // Splitting outputs of W*r node
795  os << "dim-range-node name=W_ir-r_tminus1 input-node=W-r dim-offset=0 "
796  << "dim=" << cell_dim << std::endl;
797  os << "dim-range-node name=W_fr-r_tminus1 input-node=W-r "
798  << "dim-offset=" << cell_dim << " dim="<<cell_dim << std::endl;
799  os << "dim-range-node name=W_cr-r_tminus1 input-node=W-r "
800  << "dim-offset=" << 2 * cell_dim << " dim="<<cell_dim << std::endl;
801  os << "dim-range-node name=W_or-r_tminus1 input-node=W-r "
802  << "dim-offset=" << 3 * cell_dim << " dim="<<cell_dim << std::endl;
803 
804  // Non-linear operations
805  os << "component-node name=c_t component=c_t input=Sum(f_t-c_tminus1, i_t-g)\n";
806  os << "component-node name=h component=h input=c_t\n";
807  os << "component-node name=i_t component=i_t input=Sum(W_ix-x_t, Sum(W_ir-r_tminus1, Wic))\n";
808  os << "component-node name=f_t component=f_t input=Sum(W_fx-x_t, Sum(W_fr-r_tminus1, Wfc))\n";
809  os << "component-node name=o_t component=o_t input=Sum(W_ox-x_t, Sum(W_or-r_tminus1, Woc))\n";
810  os << "component-node name=f_t-c_tminus1 component=f_t-c_tminus1 input=Append(f_t, Offset(c_t, -1))\n";
811  os << "component-node name=i_t-g component=i_t-g input=Append(i_t, g)\n";
812  os << "component-node name=m_t component=m_t input=Append(o_t, h)\n";
813 
814  os << "component-node name=g component=g input=Sum(W_cx-x_t, W_cr-r_tminus1)\n";
815 
816  // Final affine transform
817  os << "component-node name=Wyr component=Wyr input=r_t\n";
818  os << "component-node name=Wyp component=Wyp input=p_t\n";
819 
820  os << "component-node name=final_affine component=final_affine input=Sum(Wyr, Wyp)\n";
821 
822  os << "component-node name=posteriors component=logsoftmax input=final_affine\n";
823  os << "output-node name=output input=posteriors\n";
824 
825  configs->push_back(os.str());
826 }
#define KALDI_ERR
Definition: kaldi-error.h:127
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
void kaldi::nnet3::GenerateConfigSequenceLstmWithTruncation ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 516 of file nnet-test-utils.cc.

References rnnlm::i, NnetGenerationOptions::output_dim, kaldi::Rand(), and kaldi::RandInt().

Referenced by GenerateConfigSequence().

518  {
519  std::ostringstream os;
520 
521  std::vector<int32> splice_context;
522  for (int32 i = -5; i < 4; i++)
523  if (Rand() % 3 == 0)
524  splice_context.push_back(i);
525  if (splice_context.empty())
526  splice_context.push_back(0);
527 
528  int32 input_dim = 10 + Rand() % 20,
529  spliced_dim = input_dim * splice_context.size(),
530  output_dim = (opts.output_dim > 0 ?
531  opts.output_dim :
532  100 + Rand() % 200),
533  cell_dim = 40 + Rand() % 50,
534  projection_dim = std::ceil(cell_dim / (Rand() % 10 + 1));
535  int32 clipping_threshold = RandInt(6, 50),
536  zeroing_threshold = RandInt(1, 5),
537  zeroing_interval = RandInt(1, 5) * 10;
538 
539  os << "input-node name=input dim=" << input_dim << std::endl;
540 
541  // Parameter Definitions W*(* replaced by - to have valid names)
542  // Input gate control : Wi* matrices
543  os << "component name=Wi-xr type=NaturalGradientAffineComponent"
544  << " input-dim=" << spliced_dim + projection_dim
545  << " output-dim=" << cell_dim << std::endl;
546  os << "component name=Wic type=PerElementScaleComponent "
547  << " dim=" << cell_dim << std::endl;
548 
549  // Forget gate control : Wf* matrices
550  os << "component name=Wf-xr type=NaturalGradientAffineComponent"
551  << " input-dim=" << spliced_dim + projection_dim
552  << " output-dim=" << cell_dim << std::endl;
553  os << "component name=Wfc type=PerElementScaleComponent "
554  << " dim=" << cell_dim << std::endl;
555 
556  // Output gate control : Wo* matrices
557  os << "component name=Wo-xr type=NaturalGradientAffineComponent"
558  << " input-dim=" << spliced_dim + projection_dim
559  << " output-dim=" << cell_dim << std::endl;
560  os << "component name=Woc type=PerElementScaleComponent "
561  << " dim=" << cell_dim << std::endl;
562 
563  // Cell input matrices : Wc* matrices
564  os << "component name=Wc-xr type=NaturalGradientAffineComponent"
565  << " input-dim=" << spliced_dim + projection_dim
566  << " output-dim=" << cell_dim << std::endl;
567 
568 
569 
570  // projection matrices : Wrm and Wpm
571  os << "component name=W-m type=NaturalGradientAffineComponent "
572  << " input-dim=" << cell_dim
573  << " output-dim=" << 2 * projection_dim << std::endl;
574 
575  // Output : Wyr and Wyp
576  os << "component name=Wy- type=NaturalGradientAffineComponent "
577  << " input-dim=" << 2 * projection_dim
578  << " output-dim=" << cell_dim << std::endl;
579 
580  // Defining the diagonal matrices
581  // Defining the final affine transform
582  os << "component name=final_affine type=NaturalGradientAffineComponent "
583  << "input-dim=" << cell_dim << " output-dim=" << output_dim << std::endl;
584  os << "component name=logsoftmax type=LogSoftmaxComponent dim="
585  << output_dim << std::endl;
586 
587  // Defining the non-linearities
588  // declare a no-op component so that we can use a sum descriptor's output
589  // multiple times, and to make the config more readable given the equations
590  os << "component name=i type=SigmoidComponent dim="
591  << cell_dim << std::endl;
592  os << "component name=f type=SigmoidComponent dim="
593  << cell_dim << std::endl;
594  os << "component name=o type=SigmoidComponent dim="
595  << cell_dim << std::endl;
596  os << "component name=g type=TanhComponent dim="
597  << cell_dim << std::endl;
598  os << "component name=h type=TanhComponent dim="
599  << cell_dim << std::endl;
600  os << "component name=c1 type=ElementwiseProductComponent "
601  << " input-dim=" << 2 * cell_dim
602  << " output-dim=" << cell_dim << std::endl;
603  os << "component name=c2 type=ElementwiseProductComponent "
604  << " input-dim=" << 2 * cell_dim
605  << " output-dim=" << cell_dim << std::endl;
606  os << "component name=m type=ElementwiseProductComponent "
607  << " input-dim=" << 2 * cell_dim
608  << " output-dim=" << cell_dim << std::endl;
609  os << "component name=c type=BackpropTruncationComponent dim="
610  << cell_dim
611  << " clipping-threshold=" << clipping_threshold
612  << " zeroing-threshold=" << zeroing_threshold
613  << " zeroing-interval=" << zeroing_interval
614  << " recurrence-interval=1" << std::endl;
615  os << "component name=r type=BackpropTruncationComponent dim="
616  << projection_dim
617  << " clipping-threshold=" << clipping_threshold
618  << " zeroing-threshold=" << zeroing_threshold
619  << " zeroing-interval=" << zeroing_interval
620  << " recurrence-interval=1" << std::endl;
621 
622  // Defining the computations
623  std::ostringstream temp_string_stream;
624  for (size_t i = 0; i < splice_context.size(); i++) {
625  int32 offset = splice_context[i];
626  temp_string_stream << "Offset(input, " << offset << ")";
627  if (i + 1 < splice_context.size())
628  temp_string_stream << ", ";
629  }
630  std::string spliced_input = temp_string_stream.str();
631 
632  std::string c_tminus1 = "IfDefined(Offset(c_t, -1))";
633  os << "component-node name=c_t component=c input=Sum(c1_t, c2_t)\n";
634 
635  // i_t
636  os << "component-node name=i1 component=Wi-xr input=Append("
637  << spliced_input << ", IfDefined(Offset(r_t, -1)))\n";
638  os << "component-node name=i2 component=Wic "
639  << " input=" << c_tminus1 << std::endl;
640  os << "component-node name=i_t component=i input=Sum(i1, i2)\n";
641 
642  // f_t
643  os << "component-node name=f1 component=Wf-xr input=Append("
644  << spliced_input << ", IfDefined(Offset(r_t, -1)))\n";
645  os << "component-node name=f2 component=Wfc "
646  << " input=" << c_tminus1 << std::endl;
647  os << "component-node name=f_t component=f input=Sum(f1, f2)\n";
648 
649  // o_t
650  os << "component-node name=o1 component=Wo-xr input=Append("
651  << spliced_input << ", IfDefined(Offset(r_t, -1)))\n";
652  os << "component-node name=o2 component=Woc input=Sum(c1_t, c2_t)\n";
653  os << "component-node name=o_t component=o input=Sum(o1, o2)\n";
654 
655  // h_t
656  os << "component-node name=h_t component=h input=Sum(c1_t, c2_t)\n";
657 
658  // g_t
659  os << "component-node name=g1 component=Wc-xr input=Append("
660  << spliced_input << ", IfDefined(Offset(r_t, -1)))\n";
661  os << "component-node name=g_t component=g input=g1\n";
662 
663  // parts of c_t
664  os << "component-node name=c1_t component=c1 "
665  << " input=Append(f_t, " << c_tminus1 << ")\n";
666  os << "component-node name=c2_t component=c2 input=Append(i_t, g_t)\n";
667 
668  // m_t
669  os << "component-node name=m_t component=m input=Append(o_t, h_t)\n";
670 
671  // r_t and p_t
672  os << "component-node name=rp_t component=W-m input=m_t\n";
673  // Splitting outputs of Wy- node
674  os << "dim-range-node name=r_t_pretrunc input-node=rp_t dim-offset=0 "
675  << "dim=" << projection_dim << std::endl;
676  os << "component-node name=r_t component=r input=r_t_pretrunc\n";
677 
678  // y_t
679  os << "component-node name=y_t component=Wy- input=rp_t\n";
680 
681  // Final affine transform
682  os << "component-node name=final_affine component=final_affine input=y_t\n";
683  os << "component-node name=posteriors component=logsoftmax input=final_affine\n";
684  os << "output-node name=output input=posteriors\n";
685  configs->push_back(os.str());
686 }
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:100
void kaldi::nnet3::GenerateConfigSequenceRnn ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 210 of file nnet-test-utils.cc.

References rnnlm::i, NnetGenerationOptions::output_dim, kaldi::Rand(), and kaldi::RandInt().

Referenced by GenerateConfigSequence().

212  {
213  std::ostringstream os;
214 
215  std::vector<int32> splice_context;
216  for (int32 i = -5; i < 4; i++)
217  if (Rand() % 3 == 0)
218  splice_context.push_back(i);
219  if (splice_context.empty())
220  splice_context.push_back(0);
221 
222  int32 input_dim = 10 + Rand() % 20,
223  spliced_dim = input_dim * splice_context.size(),
224  output_dim = (opts.output_dim > 0 ?
225  opts.output_dim :
226  100 + Rand() % 200),
227  hidden_dim = 40 + Rand() % 50;
228  os << "component name=affine1 type=NaturalGradientAffineComponent input-dim="
229  << spliced_dim << " output-dim=" << hidden_dim << std::endl;
230  if (RandInt(0, 1) == 0) {
231  os << "component name=nonlin1 type=RectifiedLinearComponent dim="
232  << hidden_dim << std::endl;
233  } else {
234  os << "component name=nonlin1 type=TanhComponent dim="
235  << hidden_dim << std::endl;
236  }
237  os << "component name=recurrent_affine1 type=NaturalGradientAffineComponent input-dim="
238  << hidden_dim << " output-dim=" << hidden_dim << std::endl;
239  os << "component name=affine2 type=NaturalGradientAffineComponent input-dim="
240  << hidden_dim << " output-dim=" << output_dim << std::endl;
241  os << "component name=logsoftmax type=LogSoftmaxComponent dim="
242  << output_dim << std::endl;
243  os << "input-node name=input dim=" << input_dim << std::endl;
244 
245  os << "component-node name=affine1_node component=affine1 input=Append(";
246  for (size_t i = 0; i < splice_context.size(); i++) {
247  int32 offset = splice_context[i];
248  os << "Offset(input, " << offset << ")";
249  if (i + 1 < splice_context.size())
250  os << ", ";
251  }
252  os << ")\n";
253  os << "component-node name=recurrent_affine1 component=recurrent_affine1 "
254  "input=Offset(nonlin1, -1)\n";
255  os << "component-node name=nonlin1 component=nonlin1 "
256  "input=Sum(affine1_node, IfDefined(recurrent_affine1))\n";
257  os << "component-node name=affine2 component=affine2 input=nonlin1\n";
258  os << "component-node name=output_nonlin component=logsoftmax input=affine2\n";
259  os << "output-node name=output input=output_nonlin\n";
260  configs->push_back(os.str());
261 }
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:100
void kaldi::nnet3::GenerateConfigSequenceRnnClockwork ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 269 of file nnet-test-utils.cc.

References rnnlm::i, NnetGenerationOptions::output_dim, and kaldi::Rand().

Referenced by GenerateConfigSequence().

271  {
272  std::ostringstream os;
273 
274  std::vector<int32> splice_context;
275  for (int32 i = -5; i < 4; i++)
276  if (Rand() % 3 == 0)
277  splice_context.push_back(i);
278  if (splice_context.empty())
279  splice_context.push_back(0);
280 
281  int32 input_dim = 10 + Rand() % 20,
282  spliced_dim = input_dim * splice_context.size(),
283  output_dim = (opts.output_dim > 0 ?
284  opts.output_dim :
285  100 + Rand() % 200),
286  hidden_dim = 40 + Rand() % 50;
287  os << "component name=affine1 type=NaturalGradientAffineComponent input-dim="
288  << spliced_dim << " output-dim=" << hidden_dim << std::endl;
289  os << "component name=nonlin1 type=RectifiedLinearComponent dim="
290  << hidden_dim << std::endl;
291  os << "component name=recurrent_affine1 type=NaturalGradientAffineComponent input-dim="
292  << hidden_dim << " output-dim=" << hidden_dim << std::endl;
293  // the suffix _0, _1, _2 equals the index of the output-frame modulo 3; there
294  // are 3 versions of the final affine layer. There was a paper by Vincent
295  // Vanhoucke about something like this.
296  os << "component name=final_affine_0 type=NaturalGradientAffineComponent input-dim="
297  << hidden_dim << " output-dim=" << output_dim << std::endl;
298  os << "component name=final_affine_1 type=NaturalGradientAffineComponent input-dim="
299  << hidden_dim << " output-dim=" << output_dim << std::endl;
300  os << "component name=final_affine_2 type=NaturalGradientAffineComponent input-dim="
301  << hidden_dim << " output-dim=" << output_dim << std::endl;
302  os << "component name=logsoftmax type=LogSoftmaxComponent dim="
303  << output_dim << std::endl;
304  os << "input-node name=input dim=" << input_dim << std::endl;
305 
306  os << "component-node name=affine1_node component=affine1 input=Append(";
307  for (size_t i = 0; i < splice_context.size(); i++) {
308  int32 offset = splice_context[i];
309  os << "Offset(input, " << offset << ")";
310  if (i + 1 < splice_context.size())
311  os << ", ";
312  }
313  os << ")\n";
314  os << "component-node name=recurrent_affine1 component=recurrent_affine1 "
315  "input=Offset(nonlin1, -1)\n";
316  os << "component-node name=nonlin1 component=nonlin1 "
317  "input=Sum(affine1_node, IfDefined(recurrent_affine1))\n";
318  os << "component-node name=final_affine_0 component=final_affine_0 input=nonlin1\n";
319  os << "component-node name=final_affine_1 component=final_affine_1 input=Offset(nonlin1, -1)\n";
320  os << "component-node name=final_affine_2 component=final_affine_2 input=Offset(nonlin1, 1)\n";
321  os << "component-node name=output_nonlin component=logsoftmax input=Switch(final_affine_0, final_affine_1, final_affine_2)\n";
322  os << "output-node name=output input=output_nonlin\n";
323  configs->push_back(os.str());
324 }
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
void kaldi::nnet3::GenerateConfigSequenceSimple ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 94 of file nnet-test-utils.cc.

References NnetGenerationOptions::allow_final_nonlinearity, rnnlm::i, NnetGenerationOptions::output_dim, kaldi::Rand(), and kaldi::RandInt().

Referenced by GenerateConfigSequence().

96  {
97  std::ostringstream os;
98 
99  std::vector<int32> splice_context;
100  for (int32 i = -5; i < 4; i++)
101  if (Rand() % 3 == 0)
102  splice_context.push_back(i);
103  if (splice_context.empty())
104  splice_context.push_back(0);
105 
106  int32 input_dim = 10 + Rand() % 20,
107  spliced_dim = input_dim * splice_context.size(),
108  output_dim = (opts.output_dim > 0 ?
109  opts.output_dim :
110  100 + Rand() % 200),
111  hidden_dim = 40 + Rand() % 50;
112  bool use_final_nonlinearity = (opts.allow_final_nonlinearity &&
113  RandInt(0, 1) == 0);
114  os << "component name=affine1 type=NaturalGradientAffineComponent input-dim="
115  << spliced_dim << " output-dim=" << hidden_dim << std::endl;
116  os << "component name=relu1 type=RectifiedLinearComponent dim="
117  << hidden_dim << std::endl;
118  os << "component name=final_affine type=NaturalGradientAffineComponent input-dim="
119  << hidden_dim << " output-dim=" << output_dim << std::endl;
120  if (use_final_nonlinearity) {
121  if (Rand() % 2 == 0) {
122  os << "component name=logsoftmax type=SoftmaxComponent dim="
123  << output_dim << std::endl;
124  } else {
125  os << "component name=logsoftmax type=LogSoftmaxComponent dim="
126  << output_dim << std::endl;
127  }
128  }
129  os << "input-node name=input dim=" << input_dim << std::endl;
130 
131  os << "component-node name=affine1_node component=affine1 input=Append(";
132  for (size_t i = 0; i < splice_context.size(); i++) {
133  int32 offset = splice_context[i];
134  os << "Offset(input, " << offset << ")";
135  if (i + 1 < splice_context.size())
136  os << ", ";
137  }
138  os << ")\n";
139  os << "component-node name=nonlin1 component=relu1 input=affine1_node\n";
140  os << "component-node name=final_affine component=final_affine input=nonlin1\n";
141  if (use_final_nonlinearity) {
142  os << "component-node name=output_nonlin component=logsoftmax input=final_affine\n";
143  os << "output-node name=output input=output_nonlin\n";
144  } else {
145  os << "output-node name=output input=final_affine\n";
146  }
147  configs->push_back(os.str());
148 
149  if ((Rand() % 2) == 0) {
150  std::ostringstream os2;
151  os2 << "component name=affine2 type=NaturalGradientAffineComponent input-dim="
152  << hidden_dim << " output-dim=" << hidden_dim << std::endl;
153  os2 << "component name=relu2 type=RectifiedLinearComponent dim="
154  << hidden_dim << std::endl;
155  // regenerate the final_affine component when we add the new config.
156  os2 << "component name=final_affine type=NaturalGradientAffineComponent input-dim="
157  << hidden_dim << " output-dim=" << output_dim << std::endl;
158  os2 << "component-node name=affine2 component=affine2 input=nonlin1\n";
159  os2 << "component-node name=relu2 component=relu2 input=affine2\n";
160  os2 << "component-node name=final_affine component=final_affine input=relu2\n";
161  configs->push_back(os2.str());
162  }
163 }
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:100
void kaldi::nnet3::GenerateConfigSequenceSimpleContext ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 54 of file nnet-test-utils.cc.

References rnnlm::i, NnetGenerationOptions::output_dim, and kaldi::Rand().

Referenced by GenerateConfigSequence().

56  {
57  std::ostringstream os;
58 
59  std::vector<int32> splice_context;
60  for (int32 i = -5; i < 4; i++)
61  if (Rand() % 3 == 0)
62  splice_context.push_back(i);
63  if (splice_context.empty())
64  splice_context.push_back(0);
65 
66  int32 input_dim = 10 + Rand() % 20,
67  spliced_dim = input_dim * splice_context.size(),
68  output_dim = (opts.output_dim > 0 ?
69  opts.output_dim :
70  100 + Rand() % 200);
71 
72  os << "component name=affine1 type=AffineComponent input-dim="
73  << spliced_dim << " output-dim=" << output_dim << std::endl;
74 
75  os << "input-node name=input dim=" << input_dim << std::endl;
76 
77  os << "component-node name=affine1_node component=affine1 input=Append(";
78  for (size_t i = 0; i < splice_context.size(); i++) {
79  int32 offset = splice_context[i];
80  os << "Offset(input, " << offset << ")";
81  if (i + 1 < splice_context.size())
82  os << ", ";
83  }
84  os << ")\n";
85  os << "output-node name=output input=affine1_node\n";
86  configs->push_back(os.str());
87 }
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
void kaldi::nnet3::GenerateConfigSequenceSimplest ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 33 of file nnet-test-utils.cc.

References NnetGenerationOptions::output_dim, and kaldi::Rand().

Referenced by GenerateConfigSequence().

35  {
36  std::ostringstream os;
37 
38  int32 input_dim = 10 + Rand() % 20,
39  output_dim = (opts.output_dim > 0 ?
40  opts.output_dim :
41  100 + Rand() % 200);
42 
43 
44  os << "component name=affine1 type=AffineComponent input-dim="
45  << input_dim << " output-dim=" << output_dim << std::endl;
46 
47  os << "input-node name=input dim=" << input_dim << std::endl;
48  os << "component-node name=affine1_node component=affine1 input=input\n";
49  os << "output-node name=output input=affine1_node\n";
50  configs->push_back(os.str());
51 }
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:46
void kaldi::nnet3::GenerateConfigSequenceStatistics ( const NnetGenerationOptions &  opts,
std::vector< std::string > *  configs 
)

Definition at line 166 of file nnet-test-utils.cc.

References kaldi::RandInt().

Referenced by GenerateConfigSequence().

168  {
169  int32 input_dim = RandInt(10, 30),
170  input_period = RandInt(1, 3),
171  stats_period = input_period * RandInt(1, 3),
172  left_context = stats_period * RandInt(1, 10),
173  right_context = stats_period * RandInt(1, 10),
174  log_count_features = RandInt(0, 3);
175  BaseFloat variance_floor = RandInt(1, 10) * 1.0e-10;
176  bool output_stddevs = (RandInt(0, 1) == 0);
177 
178  int32 raw_stats_dim = 1 + input_dim + (output_stddevs ? input_dim : 0),
179  pooled_stats_dim = log_count_features + input_dim +
180  (output_stddevs ? input_dim : 0);
181  std::ostringstream os;
182  os << "input-node name=input dim=" << input_dim << std::endl;
183  os << "component name=statistics-extraction type=StatisticsExtractionComponent "
184  << "input-dim=" << input_dim << " input-period=" << input_period
185  << " output-period=" << stats_period << " include-variance="
186  << std::boolalpha << output_stddevs << "\n";
187 
188  os << "component name=statistics-pooling type=StatisticsPoolingComponent "
189  << "input-dim=" << raw_stats_dim << " input-period=" << stats_period
190  << " left-context=" << left_context << " right-context=" << right_context
191  << " num-log-count-features=" << log_count_features << " output-stddevs="
192  << std::boolalpha << output_stddevs << " variance-floor="
193  << variance_floor << "\n";
194 
195  os << "component name=affine type=AffineComponent "
196  << "input-dim=" << input_dim << " output-dim=" << pooled_stats_dim
197  << "\n";
198 
199  os << "component-node name=statistics-extraction component=statistics-extraction "
200  << "input=input\n";
201  os << "component-node name=statistics-pooling component=statistics-pooling "
202  << "input=statistics-extraction\n";
203  os << "component-node name=affine component=affine input=input\n";
204  os << "output-node name=output input=Sum(affine, Round(statistics-pooling, "
205  << stats_period << "))\n";
206  configs->push_back(os.str());
207 }
float BaseFloat
Definition: kaldi-types.h:29
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:100
static void kaldi::nnet3::GenerateRandomComponentConfig ( std::string *  component_type,
std::string *  config 
)
static

Definition at line 1104 of file nnet-test-utils.cc.

References rnnlm::i, KALDI_ERR, rnnlm::n, kaldi::Rand(), kaldi::RandInt(), and kaldi::RandUniform().

Referenced by GenerateRandomSimpleComponent().

1105  {
1106 
1107  int32 n = RandInt(0, 30);
1108  BaseFloat learning_rate = 0.001 * RandInt(1, 100);
1109 
1110  std::ostringstream os;
1111  switch(n) {
1112  case 0: {
1113  *component_type = "PnormComponent";
1114  int32 output_dim = RandInt(1, 50), group_size = RandInt(1, 15),
1115  input_dim = output_dim * group_size;
1116  os << "input-dim=" << input_dim << " output-dim=" << output_dim;
1117  break;
1118  }
1119  case 1: {
1120  BaseFloat target_rms = (RandInt(1, 200) / 100.0);
1121  std::string add_log_stddev = (Rand() % 2 == 0 ? "True" : "False");
1122  *component_type = "NormalizeComponent";
1123  // avoid dim=1 because the derivatives would be zero, which
1124  // makes them hard to test.
1125  os << "dim=" << RandInt(2, 50)
1126  << " target-rms=" << target_rms
1127  << " add-log-stddev=" << add_log_stddev;
1128  break;
1129  }
1130  case 2: {
1131  *component_type = "SigmoidComponent";
1132  os << "dim=" << RandInt(1, 50);
1133  break;
1134  }
1135  case 3: {
1136  *component_type = "TanhComponent";
1137  os << "dim=" << RandInt(1, 50);
1138  break;
1139  }
1140  case 4: {
1141  *component_type = "RectifiedLinearComponent";
1142  os << "dim=" << RandInt(1, 50);
1143  break;
1144  }
1145  case 5: {
1146  *component_type = "SoftmaxComponent";
1147  os << "dim=" << RandInt(1, 50);
1148  break;
1149  }
1150  case 6: {
1151  *component_type = "LogSoftmaxComponent";
1152  os << "dim=" << RandInt(1, 50);
1153  break;
1154  }
1155  case 7: {
1156  *component_type = "NoOpComponent";
1157  os << "dim=" << RandInt(1, 50);
1158  break;
1159  }
1160  case 8: {
1161  *component_type = "FixedAffineComponent";
1162  int32 input_dim = RandInt(1, 50), output_dim = RandInt(1, 50);
1163  os << "input-dim=" << input_dim << " output-dim=" << output_dim;
1164  break;
1165  }
1166  case 9: {
1167  *component_type = "AffineComponent";
1168  int32 input_dim = RandInt(1, 50), output_dim = RandInt(1, 50);
1169  os << "input-dim=" << input_dim << " output-dim=" << output_dim
1170  << " learning-rate=" << learning_rate;
1171  break;
1172  }
1173  case 10: {
1174  *component_type = "NaturalGradientAffineComponent";
1175  int32 input_dim = RandInt(1, 50), output_dim = RandInt(1, 50);
1176  os << "input-dim=" << input_dim << " output-dim=" << output_dim
1177  << " learning-rate=" << learning_rate;
1178  break;
1179  }
1180  case 11: {
1181  *component_type = "SumGroupComponent";
1182  std::vector<int32> sizes;
1183  int32 num_groups = RandInt(1, 50);
1184  os << "sizes=";
1185  for (int32 i = 0; i < num_groups; i++) {
1186  os << RandInt(1, 5);
1187  if (i + 1 < num_groups)
1188  os << ',';
1189  }
1190  break;
1191  }
1192  case 12: {
1193  *component_type = "FixedScaleComponent";
1194  os << "dim=" << RandInt(1, 100);
1195  break;
1196  }
1197  case 13: {
1198  *component_type = "FixedBiasComponent";
1199  os << "dim=" << RandInt(1, 100);
1200  break;
1201  }
1202  case 14: {
1203  *component_type = "NaturalGradientPerElementScaleComponent";
1204  os << "dim=" << RandInt(1, 100)
1205  << " learning-rate=" << learning_rate;
1206  break;
1207  }
1208  case 15: {
1209  *component_type = "PerElementScaleComponent";