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

Namespaces

 computation_graph
 

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  CachingOptimizingCompilerOptions
 
class  ChainExampleMerger
 This class is responsible for arranging examples in groups that have the same strucure (i.e. More...
 
struct  ChainObjectiveInfo
 
struct  CheckComputationOptions
 
struct  ChunkTimeInfo
 struct ChunkTimeInfo is used by class UtteranceSplitter to output information about how we split an utterance into chunks. More...
 
struct  CindexHasher
 
class  CindexSet
 
struct  CindexVectorHasher
 
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
 
class  ComputationExpander
 
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  ComputationLoopedOptimizer
 
class  ComputationRenumberer
 
struct  ComputationRequest
 
struct  ComputationRequestHasher
 
struct  ComputationRequestPtrEqual
 
class  ComputationStepsComputer
 This class 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...
 
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  ConstantComponent
 
class  ConstantFunctionComponent
 
class  ConvolutionComponent
 ConvolutionalComponent implements 2d-convolution. More...
 
class  DecodableAmNnetLoopedOnline
 
class  DecodableAmNnetSimple
 
class  DecodableAmNnetSimpleLooped
 
class  DecodableAmNnetSimpleParallel
 
class  DecodableNnetLoopedOnline
 
class  DecodableNnetLoopedOnlineBase
 
class  DecodableNnetSimple
 
class  DecodableNnetSimpleLooped
 
class  DecodableNnetSimpleLoopedInfo
 When you instantiate class DecodableNnetSimpleLooped, you should give it a const reference to this class, that has been previously initialized. More...
 
class  DerivativeTimeLimiter
 
class  Descriptor
 
class  DiscriminativeExampleMerger
 This class is responsible for arranging examples in groups that have the same strucure (i.e. More...
 
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  ExampleGenerationConfig
 
class  ExampleMerger
 This class is responsible for arranging examples in groups that have the same strucure (i.e. More...
 
class  ExampleMergingConfig
 
class  ExampleMergingStats
 This class is responsible for storing, and displaying in log messages, statistics about how examples of different sizes (c.f. More...
 
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  IndexVectorHasher
 
struct  IoSpecification
 
struct  IoSpecificationHasher
 
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  NnetChainExampleStructureCompare
 This comparator object compares just the structural aspects of the NnetChainExample without looking at the value of the features. More...
 
struct  NnetChainExampleStructureHasher
 This hashing object hashes just the structural aspects of the NnetExample without looking at the value of the features. 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  NnetDiscriminativeExampleStructureCompare
 This comparator object compares just the structural aspects of the NnetDiscriminativeExample without looking at the value of the features. More...
 
struct  NnetDiscriminativeExampleStructureHasher
 This hashing object hashes just the structural aspects of the NnetExample without looking at the value of the features. 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  NnetExampleStructureCompare
 This comparator object compares just the structural aspects of the NnetExample without looking at the value of the features. More...
 
struct  NnetExampleStructureHasher
 This hashing object hashes just the structural aspects of the NnetExample without looking at the value of the features. More...
 
struct  NnetGenerationOptions
 
struct  NnetIo
 
struct  NnetIoStructureCompare
 This comparison object compares just the structural aspects of the NnetIo object (name, indexes, feature dimension) without looking at the value of features. More...
 
struct  NnetIoStructureHasher
 This hashing object hashes just the structural aspects of the NnetIo object (name, indexes, feature dimension) without looking at the value of features. More...
 
class  NnetLdaStatsAccumulator
 
struct  NnetOptimizeOptions
 
struct  NnetSimpleComputationOptions
 
struct  NnetSimpleLoopedComputationOptions
 
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  UtteranceSplitter
 
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, kAcceptInput, kProvideOutput,
  kNoOperation, kNoOperationMarker, kNoOperationLabel, kGotoLabel
}
 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...
 
static void CheckComputationOnline (const Nnet &nnet, NnetComputation computation, bool check_rewrite)
 
void CheckComputation (const Nnet &nnet, 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...
 
void GetSegmentEnds (const NnetComputation &computation, std::vector< int32 > *command_indexes)
 This utility function works out from a computation, the locations of the 'segment ends'. 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 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...
 
int32 GetNnetChainExampleSize (const NnetChainExample &a)
 
int32 GetChainNnetExampleSize (const NnetChainExample &a)
 This function returns the 'size' of a chain example as defined for purposes of merging egs, which is defined as the largest number of Indexes in any of the inputs or outputs of the example. 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 ModifyNnetIvectorPeriod (int32 ivector_period, Nnet *nnet)
 This function modifies the descriptors in the neural network to change the periodicity with which it expects to read an iVector at its input. More...
 
int32 GetChunkSize (const Nnet &nnet, int32 frame_subsampling_factor, int32 advised_chunk_size)
 
template<class I >
Mod (I m, I n)
 Mod(m, n), defined for integers m and n where n > 0, returns the modulus m % n, defined as the integer 0 <= i < n such that i and m are congruent modulo n; for instance, Mod(13, 10) = 3. More...
 
static void CreateComputationRequestInternal (int32 begin_input_t, int32 end_input_t, int32 begin_output_t, int32 end_output_t, int32 num_sequences, int32 frame_subsampling_factor, const std::set< int32 > &ivector_times, ComputationRequest *request)
 
void CreateLoopedComputationRequestSimple (const Nnet &nnet, int32 chunk_size, int32 frame_subsampling_factor, int32 ivector_period, int32 extra_left_context_begin, int32 extra_right_context, int32 num_sequences, ComputationRequest *request1, ComputationRequest *request2, ComputationRequest *request3)
 This function creates computation request suitable for giving to ComputeLooped(). More...
 
void AddTimeOffsetToComputationRequest (int32 t_offset, ComputationRequest *request)
 
static bool ExtrapolateComputationRequest (const ComputationRequest &request1, const ComputationRequest &request2, ComputationRequest *request3)
 
static bool CompileLoopedInternal (const Nnet &nnet, NnetOptimizeOptions optimize_opts, const ComputationRequest &request1, const ComputationRequest &request2, const ComputationRequest &request3, int32 num_requests, NnetComputation *computation)
 
void CompileLooped (const Nnet &nnet, const NnetOptimizeOptions &optimize_opts, const ComputationRequest &request1, const ComputationRequest &request2, const ComputationRequest &request3, NnetComputation *computation)
 CompileLooped() provides an internal interface for 'looped' computation. More...
 
void UnitTestNnetCompile ()
 
void UnitTestNnetCompileMulti ()
 
void UnitTestNnetCompileLooped ()
 
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 int32 SumVectorSizes (const std::vector< 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< std::vector< int32 > > > *phases_per_segment)
 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...
 
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 (Nnet *nnet)
 
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)
 
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...
 
int32 GetNnetDiscriminativeExampleSize (const NnetDiscriminativeExample &a)
 
void MergeDiscriminativeExamples (std::vector< NnetDiscriminativeExample > *input, bool compress, NnetDiscriminativeExample *output)
 Appends the given vector of examples (which must be non-empty) into a single output example. More...
 
int32 GetDiscriminativeNnetExampleSize (const NnetDiscriminativeExample &a)
 This function returns the 'size' of a discriminative example as defined for purposes of merging egs, which is defined as the largest number of Indexes in any of the inputs or outputs of the example. 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)
 
int32 GetNnetExampleSize (const NnetExample &a)
 This function returns the 'size' of a nnet-example as defined for purposes of merging egs, which is defined as the largest number of Indexes in any of the inputs or outputs of the example. More...
 
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...
 
bool GraphHasCycles (const std::vector< std::vector< int32 > > &graph)
 This function returns 'true' if the graph represented in 'graph' contains cycles (including cycles where a single node has an arc to itself). More...
 
void UnitTestNnetIo ()
 
static bool UnitTestNnetOptimizeWithOptions (int32 srand_seed, NnetOptimizeOptions opt_config, CachingOptimizingCompilerOptions compiler_config)
 
static void UnitTestNnetOptimizeInternal (int32 srand_seed)
 
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 IdentifyMatrixArgsInComputation (NnetComputation *computation, std::vector< int32 * > *matrix_args)
 
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 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 and matrices that are never used (e.g. More...
 
void RemoveNoOps (NnetComputation *computation)
 Removes commands of type kNoOperation in the computation. 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 ConsolidateModelUpdate (const Nnet &nnet, NnetComputation *computation)
 This optimization consolidates 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...
 
void LimitDerivativeTimes (const Nnet &nnet, int32 min_deriv_time, int32 max_deriv_time, NnetComputation *computation)
 
static bool IndexesHaveSpecialStructure (const std::vector< int32 > &indexes, int32 *first_nonnegative_pos, int32 *first_nonnegative_value, int32 *num_nonnegative_indexes)
 
bool ReplaceRowWithMatrixOps (NnetComputation *computation)
 This function detects cases where commands of type kCopyRows, kAddRows or kAddToRows can be converted to commands of type kMatrixCopy or kMatrixAdd, and converts them (this may involve adding submatrices). More...
 
static void FindNumLeadingAndTrailingNegatives (const std::vector< int32 > &vec, int32 *num_leading_negatives, int32 *num_trailing_negatives)
 
static bool SnipSingleRowOp (NnetComputation *computation, int32 command_index)
 
static void FindNumLeadingAndTrailingNegatives (const std::vector< std::pair< int32, int32 > > &vec, int32 *num_leading_negatives, int32 *num_trailing_negatives)
 
static bool SnipMultiRowOp (NnetComputation *computation, int32 command_index)
 
static void FindNumLeadingAndTrailingIdenticals (const std::vector< std::pair< int32, int32 > > &vec, int32 *num_leading_identicals, int32 *num_trailing_identicals)
 
static bool SnipRangesRowOp (NnetComputation *computation, int32 command_index)
 
bool SnipRowOps (NnetComputation *computation)
 This function detects cases where commands of type kCopyRows, kAddRows, kAddRowsMulti, kAddToRowsMulti, kCopyRowsMulti, kCopyToRowsMulti or kAddRowRanges use indexes that start or end with -1's or equivalents, and replace them with similar commands that act on a sub-matrix of the matrices they are currently acting on. More...
 
void ExpandComputation (const Nnet &nnet, const MiscComputationInfo &misc_info, const NnetComputation &computation, bool need_debug_info, int32 num_n_values, NnetComputation *expanded_computation)
 This function is used in 'shortcut' compilation to expand a computation that has been compiled for exactly 2 'n' values, to one that is suitable for some num_n_values > 2. More...
 
static bool IoSpecificationIsDecomposable (const IoSpecification &io_spec, IoSpecification *mini_io_spec, int32 *num_n_values_out)
 
bool RequestIsDecomposable (const ComputationRequest &request, ComputationRequest *mini_request, int32 *num_n_values)
 This function, used in 'shortcut' compilation where we first compile a smaller computation with the same structure but only 2 distinct 'n' values, works out whether a computation is 'decomposable'; if so, it returns true and outputs the 'mini_request' with the same structure, and the number of 'n' values. More...
 
void OptimizeLoopedComputation (const Nnet &nnet, NnetComputation *computation)
 This function tries to optimize computation 'computation' for an 'looped' computation. More...
 
void FixGotoLabel (NnetComputation *computation)
 This function ensures that the arg1 of a final command of type kGotoLabel is the same as the command with type kNoOperationLabel. More...
 
int32 MaxOutputTimeInRequest (const ComputationRequest &request)
 
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, NnetComputation *computation)
 This wraps class VariableMergingOptimizer in a simplified interface. 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, int32 max_output_time_in_request, NnetComputation *computation)
 This is the top-level function for optimizing a computation. More...
 
static void SplitComputationIntoSegments (const NnetComputation &computation, std::vector< std::pair< int32, int32 > > *segments)
 Split the computation up into segments bounded by kNoOperationMarker. More...
 
void FixGotoOutputReordering (const Nnet &nnet, NnetComputation *computation)
 
void ConsolidateIoOperations (const Nnet &nnet, NnetComputation *computation)
 This optimization puts the input operations (kAcceptInput) and output operations (kProvideOutput) at the very beginning or end of segments of computation, respectively. 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 output 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)
 ComputeSimpleNnetContext computes the left-context and right-context of a 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 SetLearningRate (BaseFloat learning_rate, Nnet *nnet)
 Sets the underlying learning rate for all the components in the nnet to this value. More...
 
void SetNnetAsGradient (Nnet *nnet)
 Sets nnet as gradient by Setting is_gradient_ to true and learning_rate_ to 1 for each UpdatableComponent in nnet. 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...
 
bool NnetIsRecurrent (const Nnet &nnet)
 Returns true if 'nnet' has some kind of recurrency. 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, int32 ivector_period, const discriminative::DiscriminativeSupervision &supervision, const std::string &utt_id, bool compress, UtteranceSplitter *utt_splitter, NnetDiscriminativeExampleWriter *example_writer)
 
static void ProcessFile (const MatrixBase< BaseFloat > &feats, const MatrixBase< BaseFloat > *ivector_feats, int32 ivector_period, const MatrixBase< BaseFloat > &targets, const std::string &utt_id, bool compress, int32 num_targets, UtteranceSplitter *utt_splitter, NnetExampleWriter *example_writer)
 
static bool ProcessFile (const MatrixBase< BaseFloat > &feats, const MatrixBase< BaseFloat > *ivector_feats, int32 ivector_period, const Posterior &pdf_post, const std::string &utt_id, bool compress, int32 num_pdfs, UtteranceSplitter *utt_splitter, 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 106 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. Note: for operations that naturally need to operate on entire matrices (i.e. allocation commands and input and output commands), we use the submatrix indexes of them, which turns out to be more convenient for optimization; but these submatrix indexes must refer to the whole of a matrix.

  • kAllocMatrixUndefined: Allocate a matrix. arg1 = submatrix index.
  • kAllocMatrixZeroed: Allocate and zero a matrix. arg1 = submatrix index.
  • kDeallocMatrix: Deallocate a matrix. arg1 = submatrix index.
  • kAllocMatrixFromOther: initialize matrix with submatrix index arg1 using memory from matrix with submatrix index arg2 (using shallow swap). Note: the code relating to the 'looped' computation relies on the fact that this is a swap, so kSwapMatrix might be a better name, but we're keeping the old name.
  • kAllocMatrixFromOtherZeroed: initialize matrix with submatrix index arg1 using memory from matrix with submatrix index 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].
  • kAcceptInput: accepts a matrix of input from the user, which may be either features, or derivatives w.r.t. the output. arg1 is the submatrix index of a whole matrix that the input goes to, and arg2 is the index of the network node associated with it (e.g. the node of "input" or "ivector"), for puroses of double checking.
  • kProvideOutput: outputs a matrix to the user: either a network output, or a matrix of derivatives w.r.t. an input. arg1 is the submatrix index of the output (which we expect to be a whole matrix), arg2 is the index of the network node associated with it (e.g. the node for "output").
  • kNoOperation: does nothing (sometimes useful during optimization)
  • kNoOperationMarker: does nothing, but used to mark end of a block of commands (like forward commands).
  • kNoOperationLabel: does nothing, but is the destination for the kGotoLabel command.
  • kGotoLabel: jumps to the kNoOperationLabel command. arg1 must be set to the location of that command. Since there are no conditionals, this should be the last command, as remaining commands will be unreachable.
Enumerator
kAllocMatrixUndefined 
kAllocMatrixZeroed 
kDeallocMatrix 
kAllocMatrixFromOther 
kAllocMatrixFromOtherZeroed 
kPropagate 
kStoreStats 
kBackprop 
kBackpropNoModelUpdate 
kMatrixCopy 
kMatrixAdd 
kCopyRows 
kAddRows 
kCopyRowsMulti 
kCopyToRowsMulti 
kAddRowsMulti 
kAddToRowsMulti 
kAddRowRanges 
kAcceptInput 
kProvideOutput 
kNoOperation 
kNoOperationMarker 
kNoOperationLabel 
kGotoLabel 

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

240  {
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 312 of file nnet-utils.cc.

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

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

312  {
313  if (src.NumComponents() != dest->NumComponents())
314  KALDI_ERR << "Trying to add incompatible nnets.";
315  for (int32 c = 0; c < src.NumComponents(); c++) {
316  const Component *src_comp = src.GetComponent(c);
317  Component *dest_comp = dest->GetComponent(c);
318  dest_comp->Add(alpha, *src_comp);
319  }
320 }
#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 285 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().

286  {
287  if (src.NumComponents() != dest->NumComponents())
288  KALDI_ERR << "Trying to add incompatible nnets.";
289  int32 i = 0;
290  for (int32 c = 0; c < src.NumComponents(); c++) {
291  const Component *src_comp = src.GetComponent(c);
292  Component *dest_comp = dest->GetComponent(c);
293  if (src_comp->Properties() & kUpdatableComponent) {
294  // For now all updatable components inherit from class UpdatableComponent.
295  // If that changes in future, we will change this code.
296  const UpdatableComponent *src_uc =
297  dynamic_cast<const UpdatableComponent*>(src_comp);
298  UpdatableComponent *dest_uc =
299  dynamic_cast<UpdatableComponent*>(dest_comp);
300  if (src_uc == NULL || dest_uc == NULL)
301  KALDI_ERR << "Updatable component does not inherit from class "
302  "UpdatableComponent; change this code.";
303  KALDI_ASSERT(i < alphas.Dim());
304  dest_uc->Add(alphas(i++), *src_uc);
305  } else { // add stored stats
306  dest_comp->Add(scale, *src_comp);
307  }
308  }
309  KALDI_ASSERT(i == alphas.Dim());
310 }
#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:62
void kaldi::nnet3::AddTimeOffsetToComputationRequest ( int32  t_offset,
ComputationRequest *  request 
)

Definition at line 214 of file nnet-compile-looped.cc.

References rnnlm::i, ComputationRequest::inputs, rnnlm::j, and ComputationRequest::outputs.

Referenced by ExtrapolateComputationRequest().

215  {
216  for (size_t i = 0; i < request->inputs.size(); i++) {
217  size_t size = request->inputs[i].indexes.size();
218  for (size_t j = 0; j < size; j++)
219  request->inputs[i].indexes[j].t += t_offset;
220  }
221  for (size_t i = 0; i < request->outputs.size(); i++) {
222  size_t size = request->outputs[i].indexes.size();
223  for (size_t j = 0; j < size; j++)
224  request->outputs[i].indexes[j].t += t_offset;
225  }
226 }
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 1123 of file nnet-compile.cc.

References rnnlm::i.

Referenced by Compiler::OutputDebugInfo().

1124  {
1125  size_t indexes_size = indexes.size();
1126  if (indexes_size > out->size())
1127  out->reserve(out->size() + indexes_size);
1128  for (size_t i = 0; i < indexes_size; i++)
1129  out->push_back(Cindex(node, indexes[i]));
1130 }
std::pair< int32, Index > Cindex
Definition: nnet-common.h:106
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 NnetComputation &  computation,
bool  check_rewrite = false 
)

This is a convenience interface for class ComputationChecker.

Call it with check_rewrite = true only if the computation is pre-optimization. If the computation is an 'online' computation, this function treats it specially.

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

References ComputationChecker::Check(), CheckComputationOptions::check_rewrite, CheckComputationOnline(), NnetComputation::commands, KALDI_ERR, kGotoLabel, and NnetComputation::Print().

Referenced by Optimize().

1000  {
1001  try {
1002  if (!computation.commands.empty() &&
1003  computation.commands.back().command_type == kGotoLabel) {
1004  // Online computations need to be treated specially.
1005  CheckComputationOnline(nnet, computation, check_rewrite);
1006  } else {
1007  CheckComputationOptions opts;
1008  opts.check_rewrite = check_rewrite;
1009  ComputationChecker checker(opts, nnet, computation);
1010  checker.Check();
1011  }
1012  } catch (...) {
1013  computation.Print(std::cerr, nnet);
1014  KALDI_ERR << "Computation check failed for computation printed above "
1015  "(actual error message is above computation)";
1016  }
1017 }
#define KALDI_ERR
Definition: kaldi-error.h:127
static void CheckComputationOnline(const Nnet &nnet, NnetComputation computation, bool check_rewrite)
static void kaldi::nnet3::CheckComputationOnline ( const Nnet &  nnet,
NnetComputation  computation,
bool  check_rewrite 
)
static

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

References ComputationChecker::Check(), CheckComputationOptions::check_rewrite, CheckComputationOptions::check_unused_variables, NnetComputation::commands, KALDI_ASSERT, kAllocMatrixFromOther, kDeallocMatrix, kGotoLabel, and kaldi::swap().

Referenced by CheckComputation().

973  {
974  int32 num_commands = computation.commands.size();
975  KALDI_ASSERT(computation.commands[num_commands-1].command_type == kGotoLabel);
976  for (int32 c = num_commands - 2;
977  c >= 0 && computation.commands[c].command_type == kAllocMatrixFromOther;
978  c--) {
979  // this command can be interpreted as "initialize matrix referred to by
980  // c.arg2 with the matrix referred to by c.arg2".
981  // Because this would be interpreted by the analysis code as initializing a
982  // matrix that has already been initialized, we turn this into a command
983  // that just deallocates the matrix in c.arg2. [note: all these indexes
984  // are actually submatrix indexes].
985  computation.commands[c].command_type = kDeallocMatrix;
986  std::swap(computation.commands[c].arg1, computation.commands[c].arg2);
987  }
988 
989  CheckComputationOptions opts;
990  opts.check_rewrite = check_rewrite;
991  opts.check_unused_variables = false;
992  // We can always do this check with online computations, since they do not
993  // have the RemoveUnnecessaryAllocation() optimization applied.
994  ComputationChecker checker(opts, nnet, computation);
995  checker.Check();
996 }
void swap(basic_filebuf< CharT, Traits > &x, basic_filebuf< CharT, Traits > &y)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void CompileLooped ( const Nnet &  nnet,
const NnetOptimizeOptions &  optimize_opts,
const ComputationRequest &  request1,
const ComputationRequest &  request2,
const ComputationRequest &  request3,
NnetComputation *  computation 
)

CompileLooped() provides an internal interface for 'looped' computation.

It's usable for inference only (not training), meaning that backprop is not supported (for now, at least). CompileLooped() allows you to do the neural net computation for small chunks with increasing 't' values, and naturally cache the intermediate activations (rather than recomputing them every time you see new input data).

This function does both compilation and optimization, so it's like a combination of Compiler::CreateComputation() [nnet-compile.h] and Optimize() [nnet-optimize.h].

You provide 3 computation requests. request1 is the first computation request of an utterance (or other type of segment) that contains any required extra left context in the input. request2 and request3 are the second and third computation request, and must have exactly the same structure, except for a fixed time offset (change in 't' index) between them. This will be extrapolated to an infinite sequence of further requests (request4, request5, etc.). In practice the way it's done is that we extrapolate to a small finite number of requests (like 10), and then attempt to identify a common structure in the computation where, after processing, as an example, the 3nd computation request, the active variables can be identified with those present at, say, the 7th computation request, and we then cut and splice the computation together at this points, like making a tape loop, by adding a goto statement that jumps from the end of the 7th computation request to the end of the 3rd computation request. We also have to identify the variables with each other (merge variables).

That's done in the optimization code.

Definition at line 307 of file nnet-compile-looped.cc.

References CompileLoopedInternal(), Timer::Elapsed(), KALDI_ERR, KALDI_LOG, and KALDI_VLOG.

Referenced by DecodableNnetSimpleLoopedInfo::Init(), and UnitTestNnetCompileLooped().

312  {
313  int32 num_requests1 = 5, factor = 2, max_requests = 100,
314  num_requests;
315 
316  Timer timer;
317 
318  for (num_requests = num_requests1; num_requests <= max_requests;
319  num_requests *= factor) {
320  if (CompileLoopedInternal(nnet, optimize_opts,
321  request1, request2, request3,
322  num_requests, computation)) {
323  KALDI_LOG << "Spent " << timer.Elapsed()
324  << " seconds in looped compilation.";
325  return;
326  } else {
327  KALDI_VLOG(2) << "Looped compilation failed with "
328  << num_requests << " requests, trying "
329  << (num_requests * factor);
330  }
331  }
332  KALDI_ERR << "Looped compilation failed with "
333  << (num_requests/factor) << " requests, which "
334  << "we expect should be enough... something "
335  << "went wrong.";
336 }
static bool CompileLoopedInternal(const Nnet &nnet, NnetOptimizeOptions optimize_opts, const ComputationRequest &request1, const ComputationRequest &request2, const ComputationRequest &request3, int32 num_requests, NnetComputation *computation)
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_VLOG(v)
Definition: kaldi-error.h:136
#define KALDI_LOG
Definition: kaldi-error.h:133
static bool kaldi::nnet3::CompileLoopedInternal ( const Nnet &  nnet,
NnetOptimizeOptions  optimize_opts,
const ComputationRequest &  request1,
const ComputationRequest &  request2,
const ComputationRequest &  request3,
int32  num_requests,
NnetComputation *  computation 
)
static

Definition at line 263 of file nnet-compile-looped.cc.

References NnetComputation::commands, Compiler::CreateComputation(), ExtrapolateComputationRequest(), rnnlm::i, KALDI_ASSERT, KALDI_ERR, KALDI_LOG, kGotoLabel, MaxOutputTimeInRequest(), Optimize(), NnetOptimizeOptions::optimize_looped_computation, and ComputationRequest::Print().

Referenced by CompileLooped().

270  {
271 
272  KALDI_ASSERT(num_requests >= 3);
273  std::vector<ComputationRequest> extra_requests(num_requests - 3);
274  const ComputationRequest *prev_request = &request2;
275  const ComputationRequest *cur_request = &request3;
276  for (int32 i = 0; i < num_requests - 3; i++) {
277  if (!ExtrapolateComputationRequest(*prev_request, *cur_request,
278  &(extra_requests[i]))) {
279  KALDI_LOG << "prev_request is:";
280  prev_request->Print(std::cerr);
281  KALDI_LOG << "cur_request is:";
282  cur_request->Print(std::cerr);
283  KALDI_ERR << "Computation requests do not have the right relationship";
284  }
285  prev_request = cur_request;
286  cur_request = &(extra_requests[i]);
287  }
288 
289  std::vector<const ComputationRequest*> requests;
290  requests.push_back(&request1);
291  requests.push_back(&request2);
292  requests.push_back(&request3);
293  for (int32 i = 0; i < num_requests - 3; i++)
294  requests.push_back(&(extra_requests[i]));
295  Compiler compiler(requests, nnet);
296  CompilerOptions compiler_opts;
297  compiler.CreateComputation(compiler_opts, computation);
298  optimize_opts.optimize_looped_computation = true;
299 
300  Optimize(optimize_opts, nnet,
301  MaxOutputTimeInRequest(request3), computation);
302 
303  return computation->commands.size() != 0 &&
304  computation->commands.back().command_type == kGotoLabel;
305 }
static bool ExtrapolateComputationRequest(const ComputationRequest &request1, const ComputationRequest &request2, ComputationRequest *request3)
int32 MaxOutputTimeInRequest(const ComputationRequest &request)
#define KALDI_ERR
Definition: kaldi-error.h:127
void Optimize(const NnetOptimizeOptions &config, const Nnet &nnet, int32 max_output_time_in_request, NnetComputation *computation)
This is the top-level function for optimizing a computation.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
#define KALDI_LOG
Definition: kaldi-error.h:133
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 183 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().

185  {
186  KALDI_ASSERT(nnet1.NumComponents() == nnet2.NumComponents());
187  int32 updatable_c = 0;
188  for (int32 c = 0; c < nnet1.NumComponents(); c++) {
189  const Component *comp1 = nnet1.GetComponent(c),
190  *comp2 = nnet2.GetComponent(c);
191  if (comp1->Properties() & kUpdatableComponent) {
192  const UpdatableComponent
193  *u_comp1 = dynamic_cast<const UpdatableComponent*>(comp1),
194  *u_comp2 = dynamic_cast<const UpdatableComponent*>(comp2);
195  KALDI_ASSERT(u_comp1 != NULL && u_comp2 != NULL);
196  dot_prod->Data()[updatable_c] = u_comp1->DotProduct(*u_comp2);
197  updatable_c++;
198  }
199  }
200  KALDI_ASSERT(updatable_c == dot_prod->Dim());
201 }
Real * Data()
Returns a pointer to the start of the vector's data.
Definition: kaldi-vector.h:68
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:62
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:1636
MatrixIndexT NumCols() const
Definition: cu-matrix.h:196
float BaseFloat
Definition: kaldi-types.h:29
MatrixIndexT NumRows() const
Dimensions.
Definition: cu-matrix.h:195
#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 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(), kAcceptInput, kAddRowRanges, kAddRows, kAddRowsMulti, kAddToRowsMulti, KALDI_ERR, kAllocMatrixFromOther, kAllocMatrixFromOtherZeroed, kAllocMatrixUndefined, kAllocMatrixZeroed, kBackprop, kBackpropAdds, kBackpropNoModelUpdate, kCopyRows, kCopyRowsMulti, kCopyToRowsMulti, kDeallocMatrix, kGotoLabel, kMatrixAdd, kMatrixCopy, kNoOperation, kNoOperationLabel, kNoOperationMarker, kPropagate, kPropagateAdds, kProvideOutput, 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.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
282  break;
283  case kAllocMatrixUndefined: // nothing is written here.
284  case kDeallocMatrix: // ditto.
285  case kAllocMatrixFromOther: // ditto.
286  break;
287  case kPropagate:
288  vars.RecordAccessForSubmatrix(c.arg3, kReadAccess, &attr);
289  if (nnet.GetComponent(c.arg1)->Properties() & kPropagateAdds)
290  vars.RecordAccessForSubmatrix(c.arg4, kReadWriteAccess, &attr);
291  else
292  vars.RecordAccessForSubmatrix(c.arg4, kWriteAccess, &attr);
293  break;
294  case kStoreStats:
295  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
296  break;
297  case kBackprop:
299  vars.RecordAccessForSubmatrix(c.arg3, kReadAccess, &attr);
300  vars.RecordAccessForSubmatrix(c.arg4, kReadAccess, &attr);
301  vars.RecordAccessForSubmatrix(c.arg5, kReadAccess, &attr);
302  if (nnet.GetComponent(c.arg1)->Properties() & kBackpropAdds)
303  vars.RecordAccessForSubmatrix(c.arg6, kReadWriteAccess, &attr);
304  else
305  vars.RecordAccessForSubmatrix(c.arg6, kWriteAccess, &attr);
306  if (c.command_type == kBackprop &&
307  nnet.GetComponent(c.arg1)->Properties() & kUpdatableComponent)
308  attr.has_side_effects = true;
309  break;
310  case kMatrixCopy:
311  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
312  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
313  break;
314  case kMatrixAdd:
315  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
316  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
317  break;
318  case kAddRows:
319  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
320  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
321  break;
322  case kCopyRows: {
323  const std::vector<int32> &indexes = computation.indexes[c.arg3];
324  // if there are -1's in "indexes", then the result of the operation
325  // will depend on the initial value of the matrix, so it's
326  // a "rw" operation, not a "write" operation.
327  if (std::count(indexes.begin(), indexes.end(), -1) > 0)
328  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
329  else
330  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
331  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
332  break;
333  }
334  case kAddRowsMulti: {
335  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
336  std::vector<int32> submatrix_indexes;
337  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
338  &submatrix_indexes);
339  for (size_t i = 0; i < submatrix_indexes.size(); i++)
340  vars.RecordAccessForSubmatrix(submatrix_indexes[i],
341  kReadAccess, &attr);
342  break;
343  }
344  case kCopyRowsMulti: {
345  std::vector<int32> submatrix_indexes;
346  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
347  &submatrix_indexes);
348  // note: the CopyRows command assigns zero in cases where
349  // there is no source for some row
350  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
351  for (size_t i = 0; i < submatrix_indexes.size(); i++)
352  vars.RecordAccessForSubmatrix(submatrix_indexes[i],
353  kReadAccess, &attr);
354  break;
355  }
356  case kAddToRowsMulti:
357  case kCopyToRowsMulti: {
358  vars.RecordAccessForSubmatrix(c.arg1, kReadAccess, &attr);
359  // if the submatrixes we're writing to (in kCopyToRowsMulti) had all
360  // rows covered, it would be a pure write operation.
361  std::vector<int32> submatrix_indexes;
362  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
363  &submatrix_indexes);
364  for (size_t i = 0; i < submatrix_indexes.size(); i++)
365  vars.RecordAccessForSubmatrix(submatrix_indexes[i], kReadWriteAccess,
366  &attr);
367  break;
368  }
369  case kAddRowRanges: {
370  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
371  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
372  break;
373  }
374  case kAcceptInput: {
375  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
376  break;
377  }
378  case kProvideOutput: {
379  vars.RecordAccessForSubmatrix(c.arg1, kReadAccess, &attr);
380  break;
381  }
382  case kNoOperation:
383  case kNoOperationMarker:
384  case kNoOperationLabel:
385  case kGotoLabel:
386  break;
387  default:
388  KALDI_ERR << "Unknown command type.";
389  }
390  SortAndUniq(&attr.variables_read);
391  SortAndUniq(&attr.variables_written);
392  SortAndUniq(&attr.submatrices_read);
393  SortAndUniq(&attr.submatrices_written);
394  SortAndUniq(&attr.matrices_read);
395  SortAndUniq(&attr.matrices_written);
396  }
397 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:39
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 254 of file nnet-optimize.cc.

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

Referenced by RemoveUnnecessaryAllocation().

256  {
257  std::vector<int32> d_list = lists.first;
258 
259  std::set<int32> a_set;
260  CopyVectorToSet(lists.second, &a_set);
261 
262  std::vector<int32>::reverse_iterator iter = d_list.rbegin(),
263  end = d_list.rend();
264 
265  // from the latest to the earliest deallocation command...
266  for (; iter != end; ++iter) {
267  int32 d = *iter;
268  std::set<int32>::iterator a_iter = a_set.upper_bound(d);
269  // a_iter is an iterator to the first element a of the set 'a_set' such
270  // that a > d, or a_set.end() if no such element exists.
271  if (a_iter == a_set.end())
272  continue; // we will output no pair for this d.
273  int32 a = *a_iter;
274  KALDI_PARANOID_ASSERT(a > d); // or code error
275  a_set.erase(a_iter); // remove this a from 'a_set' so it doesn't get used
276  // twice
277  pairs->push_back(std::pair<int32,int32>(d, a));
278  }
279 }
void CopyVectorToSet(const std::vector< A > &v, std::set< A > *s)
Copies the contents of a vector to a set.
Definition: stl-utils.h:174
#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 1161 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.

1163  {
1164  using namespace computation_graph;
1165  // make sure graph is empty at the start.
1166  KALDI_ASSERT(graph->cindexes.empty());
1167 
1168  AddInputToGraph(request, nnet, graph);
1169  AddOutputToGraph(request, nnet, graph);
1170 
1171  // queue of cindex_ids to process.
1172  std::vector<int32> queue(graph->cindexes.size());
1173  for (int32 i = 0; i < graph->cindexes.size(); i++)
1174  queue.push_back(i);
1175 
1176  while (!queue.empty()) {
1177  int32 cindex_id = queue.back();
1178  queue.pop_back();
1179  if (static_cast<int32>(graph->dependencies.size()) <= cindex_id)
1180  graph->dependencies.resize(cindex_id + 1);
1181 
1182  if (graph->is_input[cindex_id])
1183  continue;
1184  Cindex cindex = graph->cindexes[cindex_id];
1185 
1186  // find the dependencies of this cindex.
1187  int32 n = cindex.first;
1188  const Index &index = cindex.second;
1189  const NetworkNode &node = nnet.GetNode(n);
1190 
1191  std::vector<Cindex> input_cindexes;
1192 
1193  // the following switch statement sets up "input_cindexes".
1194  switch (node.node_type) {
1195  case kDescriptor: {
1196  // desc describes how this node obtains its input from other nodes.
1197  const Descriptor &desc = node.descriptor;
1198  desc.GetDependencies(index, &input_cindexes);
1199  break;
1200  }
1201  case kComponent: {
1202  int32 c = node.u.component_index;
1203  const Component *component = nnet.GetComponent(c);
1204  std::vector<Index> input_indexes;
1205  component->GetInputIndexes(request.misc_info, index,
1206  &input_indexes);
1207  // each Component node should be preceded by a node that describes its
1208  // input, of type kDescriptor
1209  KALDI_ASSERT(nnet.GetNode(n-1).node_type ==
1210  kDescriptor);
1211 
1212  input_cindexes.resize(input_indexes.size());
1213  for (size_t i = 0; i < input_indexes.size(); i++) {
1214  input_cindexes[i].first = n - 1; // preceding node.
1215  input_cindexes[i].second = input_indexes[i];
1216  }
1217  break;
1218  }
1219  case kDimRange: {
1220  input_cindexes.resize(1);
1221  input_cindexes[0] = Cindex(node.u.node_index, index);
1222  break;
1223  }
1224  case kInput: default:
1225  // for kInput, you should have hit the "continue" statement above.
1226  KALDI_ERR << "Invalid node type";
1227  }
1228  std::vector<int32> &this_dep = graph->dependencies[cindex_id];
1229 
1230  int32 num_dependencies = input_cindexes.size();
1231  this_dep.resize(num_dependencies);
1232  for (size_t i = 0; i < num_dependencies; i++) {
1233  bool is_input = false, is_new;
1234  int32 dep_cindex_id = graph->GetCindexId(input_cindexes[i],
1235  is_input, &is_new);
1236  this_dep[i] = dep_cindex_id;
1237  if (is_new)
1238  queue.push_back(dep_cindex_id);
1239  }
1240 
1241  // remove duplicates of dependencies.
1242  SortAndUniq(&this_dep);
1243  }
1244 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:39
void AddInputToGraph(const ComputationRequest &request, const Nnet &nnet, ComputationGraph *graph)
std::pair< int32, Index > Cindex
Definition: nnet-common.h:106
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< std::vector< int32 > > > *  phases_per_segment 
)

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]phases_per_segmentThe phases, listed separately for each segment of the computation [there will be just one segment in the normal case, more in the online-recognition case]. Consider just one segment for now. Suppose the computation can be completed in 20 phases, then (*phases)[0].size() will be 20 at exit, and (*phases)[0][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 int32's in 'phases_per_segment' will be disjoint and will cover all elements in [0 .. computation.cindexes.size() - 1].

Note: we assume you have called PruneComputationGraph() before this function. Even so, this function will be crash if the computation cannot actually be computed– there are some mal-formed computations where you can build the computation graph but not the ordering of cindexes because there are dependencies forward and backward in time that intertwine.

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

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

Referenced by Compiler::CreateComputation().

1418  {
1419  using namespace computation_graph;
1420  int32 num_cindex_ids = graph.cindexes.size();
1421 
1422  std::vector<int32> cindex_id_to_segment_and_epoch;
1423  std::vector<std::vector<std::vector<int32 > > > epochs_per_segment;
1424  std::vector<bool> epoch_is_trivial;
1425  ComputeEpochInfo(nnet, graph, &cindex_id_to_segment_and_epoch,
1426  &epochs_per_segment, &epoch_is_trivial);
1427 
1428  KALDI_ASSERT(SumVectorSizes(epochs_per_segment) == num_cindex_ids);
1429 
1430  // dependencies_subset contains just the subset of dependencies
1431  // of each cindex_id, that have the same epoch index as
1432  // cindex_id itself. This will be used to correctly order
1433  // cindexes within a certain epoch (relevant for things like
1434  // LSTMs).
1435  std::vector<std::vector<int32> > dependencies_subset;
1436  ComputeDependenciesSubset(graph, cindex_id_to_segment_and_epoch,
1437  &dependencies_subset);
1438  // destroy cindex_id_to_segment_and_epoch, it's no longer needed.
1439  { std::vector<int32> temp; temp.swap(cindex_id_to_segment_and_epoch); }
1440 
1441  // depend_on_subset is a subset of the normal "depend_on" list (i.e. a list of
1442  // all cindex_ids that depend on the current cindex_id), limited to just those
1443  // cindex_ids that have the same epoch index.
1444  std::vector<std::vector<int32> > depend_on_subset;
1445  ComputeGraphTranspose(dependencies_subset, &depend_on_subset);
1446 
1447  int32 num_epoch_indexes = epoch_is_trivial.size(),
1448  num_segments = graph.segment_ends.size();
1449 
1450  // "phase_indexes" is used inside ComputeComputationPhasesForEpoch.
1451  std::vector<int32> phase_indexes(num_cindex_ids, -1);
1452 
1453  phases_per_segment->clear();
1454  phases_per_segment->resize(num_segments);
1455 
1456  for (int32 segment = 0; segment < num_segments; segment++) {
1457  phases_per_segment->reserve(50); // minimize unnecessary copies. 50 is
1458  // very arbitrarily chosen.
1459  for (int32 epoch = 0; epoch < num_epoch_indexes; epoch++)
1461  epochs_per_segment[segment][epoch],
1462  dependencies_subset,
1463  depend_on_subset,
1464  epoch_is_trivial[epoch],
1465  &phase_indexes,
1466  &((*phases_per_segment)[segment]));
1467  }
1468 
1469 
1470  // make sure everything was computable. If the next assert fails it's likely
1471  // a bug in this function or in PruneComputataionGraph.
1472  KALDI_ASSERT(SumVectorSizes(*phases_per_segment) == num_cindex_ids);
1473 }
static void ComputeEpochInfo(const Nnet &nnet, const ComputationGraph &graph, std::vector< int32 > *cindex_id_to_segment_and_epoch, std::vector< std::vector< std::vector< int32 > > > *epochs_per_segment, std::vector< bool > *epoch_is_trivial)
This function computes certain information about "epochs" of cindex_ids.
static int32 SumVectorSizes(const std::vector< std::vector< std::vector< int32 > > > &vec)
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 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 ComputeDependenciesSubset(const ComputationGraph &graph, const std::vector< int32 > &cindex_id_to_segment_and_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...
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 1316 of file nnet-computation-graph.cc.

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

Referenced by ComputeComputationPhases().

1324  {
1325  std::vector<int32> this_phase, next_phase_candidates;
1326 
1327  if (this_epoch.empty())
1328  return;
1329 
1330  if (epoch_is_trivial) { // an optimization
1331  this_phase = this_epoch;
1332  } else {
1333  // Start out with all elements of this epoch that have no
1334  // dependencies within the same epoch (i.e. those that
1335  // can be computed first).
1336  std::vector<int32>::const_iterator iter = this_epoch.begin(),
1337  end = this_epoch.end();
1338  for (; iter != end; ++iter) {
1339  int32 cindex_id = *iter;
1340  if (dependencies_subset[cindex_id].empty())
1341  this_phase.push_back(cindex_id);
1342  }
1343  }
1344 
1345  // if the next assert fails, the graph at the level of cindex_ids is not acyclic.
1346  KALDI_ASSERT(!this_phase.empty() &&
1347  "Trying to process computation with cycles");
1348 
1349  while (!this_phase.empty()) {
1350  // The next two lines are a more efficient version of:
1351  // phases->push_back(this_phase);
1352  phases->resize(phases->size() + 1);
1353  phases->back().swap(this_phase);
1354  // The next if-statement is an optimization: if for this epoch index
1355  // there is just one node, we can skip the rest of this loop. Note: if
1356  // epoch == 0, even if there is just one node, cindex_ids from
1357  // multiple nodes may be put here because of the rule that cindex_ids which
1358  // are inputs always get epoch 0. But it's still true that they
1359  // will have no dependencies, so we can still skip the code below.
1360  if (epoch_is_trivial)
1361  return;
1362 
1363  int32 cur_phase_index = phases->size() - 1;
1364 
1365  // next_phases_candidates is a list of cindexes that we should check
1366  // whether they are computable now, because one of the things they depend
1367  // on just became computable.
1368  next_phase_candidates.clear();
1369  std::vector<int32>::const_iterator this_phase_iter = phases->back().begin(),
1370  this_phase_end = phases->back().end();
1371 
1372  for (; this_phase_iter != this_phase_end; ++this_phase_iter) {
1373  int32 c = *this_phase_iter; // c is a cindex_id with phase cur_phase_index.
1374  (*phase_indexes)[c] = cur_phase_index;
1375  std::vector<int32>::const_iterator iter = depend_on_subset[c].begin(),
1376  end = depend_on_subset[c].end();
1377  for (; iter != end; ++iter) {
1378  int32 d = *iter; // cindex_id that depends on c.
1379  next_phase_candidates.push_back(d);
1380  }
1381  }
1382  SortAndUniq(&next_phase_candidates);
1383  // note, at this point 'this_phase' will be the empty vector [see the 'swap'
1384  // above].
1385  this_phase.reserve(next_phase_candidates.size());
1386  // now check the candidates that might be in the next phase, and put any
1387  // members that we are currently able to compute into "this_phase".
1388  std::vector<int32>::const_iterator iter = next_phase_candidates.begin(),
1389  end = next_phase_candidates.end();
1390  for (; iter != end; ++iter) {
1391  int32 c = *iter;
1392  std::vector<int32>::const_iterator
1393  dep_iter = dependencies_subset[c].begin(),
1394  dep_end = dependencies_subset[c].end();
1395  for (; dep_iter != dep_end; ++dep_iter) {
1396  int32 d = *dep_iter; // d is cindex_id that c depends on.
1397  if ((*phase_indexes)[d] < 0) // we can't compute c yet because something we depend
1398  break; // on has not yet been computed.
1399  }
1400  if (dep_iter == dep_end) {
1401  // we reached the end and did not break -> all dependencies satisfied
1402  this_phase.push_back(c);
1403  }
1404  }
1405  if (!next_phase_candidates.empty() && this_phase.empty()) {
1406  // this should have been caught earlier so likely a code error rather than
1407  // a problem with user input.
1408  KALDI_ERR << "Your model has a type of recurrence that cannot be computed. "
1409  << "E.g. if x[t] depends on both x[t+1] and x[t-1]... no order "
1410  << "of computation will work.";
1411  }
1412  }
1413 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:39
#define KALDI_ERR
Definition: kaldi-error.h:127
#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 1068 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(), UnitTestNnetCompileMulti(), UnitTestNnetCompute(), UnitTestNnetInputDerivatives(), UnitTestNnetModelDerivatives(), and UnitTestNnetOptimizeWithOptions().

1071  {
1072  KALDI_ASSERT(IsSimpleNnet(nnet));
1073 
1074  int32 left_context, right_context;
1075  ComputeSimpleNnetContext(nnet, &left_context, &right_context);
1076 
1077  int32 num_output_frames = 1 + Rand() % 10,
1078  output_start_frame = Rand() % 10,
1079  num_examples = 1 + Rand() % 10,
1080  output_end_frame = output_start_frame + num_output_frames,
1081  input_start_frame = output_start_frame - left_context - (Rand() % 3),
1082  input_end_frame = output_end_frame + right_context + (Rand() % 3),
1083  n_offset = Rand() % 2;
1084  bool need_deriv = (Rand() % 2 == 0);
1085  // make sure there are at least 3 frames of input available. this makes a
1086  // difference for our tests of statistics-pooling and statistics-extraction
1087  // component.
1088  if (input_end_frame < input_start_frame + 3)
1089  input_end_frame = input_start_frame + 3;
1090 
1091  request->inputs.clear();
1092  request->outputs.clear();
1093  inputs->clear();
1094 
1095  std::vector<Index> input_indexes, ivector_indexes, output_indexes;
1096  for (int32 n = n_offset; n < n_offset + num_examples; n++) {
1097  for (int32 t = input_start_frame; t < input_end_frame; t++)
1098  input_indexes.push_back(Index(n, t, 0));
1099  for (int32 t = output_start_frame; t < output_end_frame; t++)
1100  output_indexes.push_back(Index(n, t, 0));
1101  ivector_indexes.push_back(Index(n, 0, 0));
1102  }
1103  request->outputs.push_back(IoSpecification("output", output_indexes));
1104  if (need_deriv || (Rand() % 3 == 0))
1105  request->outputs.back().has_deriv = true;
1106  request->inputs.push_back(IoSpecification("input", input_indexes));
1107  if (need_deriv && (Rand() % 2 == 0))
1108  request->inputs.back().has_deriv = true;
1109  int32 input_dim = nnet.InputDim("input");
1110  KALDI_ASSERT(input_dim > 0);
1111  inputs->push_back(
1112  Matrix<BaseFloat>((input_end_frame - input_start_frame) * num_examples,
1113  input_dim));
1114  inputs->back().SetRandn();
1115  int32 ivector_dim = nnet.InputDim("ivector"); // may not exist.
1116  if (ivector_dim != -1) {
1117  request->inputs.push_back(IoSpecification("ivector", ivector_indexes));
1118  inputs->push_back(Matrix<BaseFloat>(num_examples, ivector_dim));
1119  inputs->back().SetRandn();
1120  if (need_deriv && (Rand() % 2 == 0))
1121  request->inputs.back().has_deriv = true;
1122  }
1123  if (Rand() % 2 == 0)
1124  request->need_model_derivative = need_deriv;
1125  if (Rand() % 2 == 0)
1126  request->store_component_stats = true;
1127 }
void ComputeSimpleNnetContext(const Nnet &nnet, int32 *left_context, int32 *right_context)
ComputeSimpleNnetContext computes the left-context and right-context of a nnet.
Definition: nnet-utils.cc:138
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 output called "output"...
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 445 of file nnet-analyze.cc.

References NnetComputation::Command::arg1, NnetComputation::Command::arg2, NnetComputation::Command::command_type, NnetComputation::commands, kaldi::IsSortedAndUniq(), NnetComputation::IsWholeMatrix(), kAcceptInput, KALDI_ASSERT, KALDI_ERR, kAllocMatrixFromOther, kAllocMatrixFromOtherZeroed, kAllocMatrixUndefined, kAllocMatrixZeroed, kDeallocMatrix, kProvideOutput, kReadAccess, kReadWriteAccess, kWriteAccess, NnetComputation::matrices, CommandAttributes::matrices_read, CommandAttributes::matrices_written, kaldi::SortAndUniq(), and NnetComputation::submatrices.

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

450  {
451  int32 num_matrices = computation.matrices.size(),
452  num_commands = command_attributes.size();
453  matrix_accesses->clear();
454  matrix_accesses->resize(num_matrices);
455  for (int32 c = 0; c < num_commands; c++) {
456  const CommandAttributes &attr = command_attributes[c];
457  KALDI_ASSERT(IsSortedAndUniq(attr.matrices_read));
458  KALDI_ASSERT(IsSortedAndUniq(attr.matrices_written));
459  std::vector<int32> all_matrices;
460  all_matrices.reserve(attr.matrices_read.size() +
461  attr.matrices_written.size());
462  all_matrices.insert(all_matrices.end(), attr.matrices_read.begin(),
463  attr.matrices_read.end());
464  all_matrices.insert(all_matrices.end(), attr.matrices_written.begin(),
465  attr.matrices_written.end());
466  SortAndUniq(&all_matrices);
467 
468  std::vector<int32>::const_iterator iter = all_matrices.begin(),
469  end = all_matrices.end();
470  for (; iter != end; ++iter) {
471  int32 matrix_index = *iter;
472  bool is_read = std::binary_search(attr.matrices_read.begin(),
473  attr.matrices_read.end(),
474  matrix_index),
475  is_written = (!is_read ? true :
476  std::binary_search(attr.matrices_written.begin(),
477  attr.matrices_written.end(),
478  matrix_index));
479  if (is_read && is_written) {
480  (*matrix_accesses)[matrix_index].accesses.push_back(
481  Access(c, kReadWriteAccess));
482  } else if (is_read) {
483  (*matrix_accesses)[matrix_index].accesses.push_back(
484  Access(c, kReadAccess));
485  } else {
486  (*matrix_accesses)[matrix_index].accesses.push_back(
487  Access(c, kWriteAccess));
488  }
489  }
490  // Now set up allocate_command, deallocate_command,
491  // is_input and is_output.
492  const NnetComputation::Command &command = computation.commands[c];
493  int32 matrix_index1, matrix_index2;
494 
495 
496  switch (command.command_type) {
497  case kAllocMatrixZeroed:
499  if (!computation.IsWholeMatrix(command.arg1))
500  KALDI_ERR << "Command does not operate on whole matrix";
501  matrix_index1 = computation.submatrices[command.arg1].matrix_index;
502  if ((*matrix_accesses)[matrix_index1].allocate_command != -1)
503  KALDI_ERR << "Matrix " << matrix_index1 << " initialized twice.";
504  (*matrix_accesses)[matrix_index1].allocate_command = c;
505  break;
508  if (!computation.IsWholeMatrix(command.arg1))
509  KALDI_ERR << "Command does not operate on whole matrix";
510  matrix_index1 = computation.submatrices[command.arg1].matrix_index;
511  KALDI_ASSERT(computation.IsWholeMatrix(command.arg2));
512  matrix_index2 = computation.submatrices[command.arg2].matrix_index;
513  if ((*matrix_accesses)[matrix_index1].allocate_command != -1)
514  KALDI_ERR << "Matrix " << matrix_index1 << " initialized twice.";
515  (*matrix_accesses)[matrix_index1].allocate_command = c;
516  if ((*matrix_accesses)[matrix_index2].deallocate_command != -1)
517  KALDI_ERR << "Matrix " << matrix_index2 << " destroyed twice.";
518  (*matrix_accesses)[matrix_index2].deallocate_command = c;
519  break;
520  case kDeallocMatrix:
521  if (!computation.IsWholeMatrix(command.arg1))
522  KALDI_ERR << "Command does not operate on whole matrix";
523  matrix_index1 = computation.submatrices[command.arg1].matrix_index;
524  if ((*matrix_accesses)[matrix_index1].deallocate_command != -1)
525  KALDI_ERR << "Matrix " << matrix_index1 << " destroyed twice.";
526  (*matrix_accesses)[matrix_index1].deallocate_command = c;
527  break;
528  case kAcceptInput:
529  if (!computation.IsWholeMatrix(command.arg1))
530  KALDI_ERR << "Command does not operate on whole matrix";
531  matrix_index1 = computation.submatrices[command.arg1].matrix_index;
532  (*matrix_accesses)[matrix_index1].is_input = true;
533  // If a certain matrix is accepted as input multiple times, we
534  // count the first one as allocating it (the second will just
535  // allocate it again, which is harmless).
536  if ((*matrix_accesses)[matrix_index1].allocate_command == -1)
537  (*matrix_accesses)[matrix_index1].allocate_command = c;
538  break;
539  case kProvideOutput:
540  if (!computation.IsWholeMatrix(command.arg1))
541  KALDI_ERR << "Command does not operate on whole matrix";
542  matrix_index1 = computation.submatrices[command.arg1].matrix_index;
543  (*matrix_accesses)[matrix_index1].is_output = true;
544  break;
545  default:
546  ;
547  }
548  }
549 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:39
#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:63
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 1019 of file nnet-analyze.cc.

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

Referenced by VariableMergingOptimizer::VariableMergingOptimizer().

1021  {
1022  int32 num_matrices = computation.matrices.size(),
1023  num_submatrices = computation.submatrices.size();
1024  mat_to_submat->clear();
1025  mat_to_submat->resize(num_matrices);
1026  for (int32 submatrix_index = 1;
1027  submatrix_index < num_submatrices;
1028  submatrix_index++) {
1029  int32 matrix_index = computation.submatrices[submatrix_index].matrix_index;
1030  KALDI_ASSERT(matrix_index > 0 && matrix_index < num_matrices);
1031  (*mat_to_submat)[matrix_index].push_back(submatrix_index);
1032  }
1033 }
#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 295 of file nnet-training.cc.

References NnetComputer::AcceptInput(), 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().

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

ComputeSimpleNnetContext 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 138 of file nnet-utils.cc.

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

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

140  {
141  KALDI_ASSERT(IsSimpleNnet(nnet));
142  int32 modulus = nnet.Modulus();
143  // modulus >= 1 is a number such that the network ought to be
144  // invariant to time shifts (of both the input and output) that
145  // are a multiple of this number. We need to test all shifts modulo
146  // this number in case the left and right context vary at all within
147  // this range.
148 
149  std::vector<int32> left_contexts(modulus + 1);
150  std::vector<int32> right_contexts(modulus + 1);
151 
152  // This will crash if the total context (left + right) is greater
153  // than window_size.
154  int32 window_size = 100;
155  // by going "<= modulus" instead of "< modulus" we do one more computation
156  // than we really need; it becomes a sanity check.
157  for (int32 input_start = 0; input_start <= modulus; input_start++)
158  ComputeSimpleNnetContextForShift(nnet, input_start, window_size,
159  &(left_contexts[input_start]),
160  &(right_contexts[input_start]));
161  KALDI_ASSERT(left_contexts[0] == left_contexts[modulus] &&
162  "nnet does not have the properties we expect.");
163  KALDI_ASSERT(right_contexts[0] == right_contexts[modulus] &&
164  "nnet does not have the properties we expect.");
165  *left_context =
166  *std::max_element(left_contexts.begin(), left_contexts.end());
167  *right_context =
168  *std::max_element(right_contexts.begin(), right_contexts.end());
169 }
bool IsSimpleNnet(const Nnet &nnet)
This function returns true if the nnet has the following properties: It has an output called "output"...
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, Nnet::Modulus(), 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 
107  // most networks will just require the ivector at time t = 0,
108  // but this might not always be the case, and some might use rounding
109  // descriptors with the iVector which might require it at an earlier
110  // frame than the regular input, so we provide the iVector in as wide a range
111  // as it might possibly be needed.
112  for (int32 t = input_start - nnet.Modulus(); t < input_end; t++) {
113  ivector.indexes.push_back(Index(n, t));
114  }
115 
116 
117  ComputationRequest request;
118  request.inputs.push_back(input);
119  request.outputs.push_back(output);
120  if (nnet.GetNodeIndex("ivector") != -1)
121  request.inputs.push_back(ivector);
122  std::vector<std::vector<bool> > computable;
123  EvaluateComputationRequest(nnet, request, &computable);
124 
125  KALDI_ASSERT(computable.size() == 1);
126  std::vector<bool> &output_ok = computable[0];
127  std::vector<bool>::iterator iter =
128  std::find(output_ok.begin(), output_ok.end(), true);
129  int32 first_ok = iter - output_ok.begin();
130  int32 first_not_ok = std::find(iter, output_ok.end(), false) -
131  output_ok.begin();
132  if (first_ok == window_size || first_not_ok <= first_ok)
133  KALDI_ERR << "No outputs were computable (perhaps not a simple nnet?)";
134  *left_context = first_ok;
135  *right_context = window_size - first_not_ok;
136 }
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 399 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().

402  {
403  int32 num_variables = variables.NumVariables(),
404  num_commands = command_attributes.size();
405  variable_accesses->clear();
406  variable_accesses->resize(num_variables);
407  for (int32 c = 0; c < num_commands; c++) {
408  const CommandAttributes &attr = command_attributes[c];
409  KALDI_ASSERT(IsSortedAndUniq(attr.variables_read));
410  KALDI_ASSERT(IsSortedAndUniq(attr.variables_written));
411  std::vector<int32> all_variables;
412  all_variables.reserve(attr.variables_read.size() +
413  attr.variables_written.size());
414  all_variables.insert(all_variables.end(), attr.variables_read.begin(),
415  attr.variables_read.end());
416  all_variables.insert(all_variables.end(), attr.variables_written.begin(),
417  attr.variables_written.end());
418  SortAndUniq(&all_variables);
419 
420  std::vector<int32>::const_iterator iter = all_variables.begin(),
421  end = all_variables.end();
422  for (; iter != end; ++iter) {
423  int32 variable_index = *iter;
424  bool is_read = std::binary_search(attr.variables_read.begin(),
425  attr.variables_read.end(),
426  variable_index),
427  is_written = (!is_read ? true :
428  std::binary_search(attr.variables_written.begin(),
429  attr.variables_written.end(),
430  variable_index));
431  if (is_read && is_written) {
432  (*variable_accesses)[variable_index].push_back(
433  Access(c, kReadWriteAccess));
434  } else if (is_read) {
435  (*variable_accesses)[variable_index].push_back(
436  Access(c, kReadAccess));
437  } else {
438  (*variable_accesses)[variable_index].push_back(
439  Access(c, kWriteAccess));
440  }
441  }
442  }
443 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:39
#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:63
void ConsolidateIoOperations ( const Nnet &  nnet,
NnetComputation *  computation 
)

This optimization puts the input operations (kAcceptInput) and output operations (kProvideOutput) at the very beginning or end of segments of computation, respectively.

This is actually necessary for computations to be run easily, because if these commands were interspersed with the regular commands, you'd have to call computer.Run() between the individual AcceptInput() and GetOutput() function calls.

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

References NnetComputation::commands, FixGotoOutputReordering(), kAcceptInput, KALDI_ASSERT, kGotoLabel, kNoOperationMarker, kProvideOutput, and SplitComputationIntoSegments().

Referenced by Compiler::CreateComputation(), and Optimize().

915  {
916  bool ends_with_goto =
917  (!computation->commands.empty() &&
918  computation->commands.back().command_type == kGotoLabel);
919 
920  // These segments, represented as (start-index, end-index),
921  // are segments of the computation separated by kNoOperationMarker.
922  std::vector<std::pair<int32, int32> > segments;
923  SplitComputationIntoSegments(*computation, &segments);
924 
925  int32 num_commands = computation->commands.size();
926  std::vector<NnetComputation::Command> reordered_commands(num_commands);
927  // put kNoOperationMarker between all segments in the reordered commands.
928  for (size_t s = 0; s + 1 < segments.size(); s++)
929  reordered_commands[segments[s].second].command_type = kNoOperationMarker;
930 
931  // for each segment we'll divide the commands up into those that must appear
932  // at the left of the segment (kAcceptInput for inputs and output-derivs), those
933  // that must appear in the middle (most commands), those that must appear
934  // on the right (kProvideOutput for output nodes and input derivatives).
935  std::vector<int32> left_commands, middle_commands, right_commands;
936 
937  for (size_t s = 0; s < segments.size(); s++) {
938  int32 segment_start = segments[s].first,
939  segment_end = segments[s].second;
940  left_commands.clear();
941  middle_commands.clear();
942  right_commands.clear();
943  for (int32 c = segment_start; c < segment_end; c++) {
944  if (computation->commands[c].command_type == kProvideOutput) {
945  right_commands.push_back(c);
946  } else if (computation->commands[c].command_type == kAcceptInput) {
947  left_commands.push_back(c);
948  } else {
949  middle_commands.push_back(c);
950  }
951  }
952  std::vector<int32>::const_iterator iter = left_commands.begin(),
953  end = left_commands.end();
954  int32 c = segment_start;
955  for (; iter != end; ++iter, ++c)
956  reordered_commands[c] = computation->commands[*iter];
957  iter = middle_commands.begin();
958  end = middle_commands.end();
959  for (; iter != end; ++iter, ++c)
960  reordered_commands[c] = computation->commands[*iter];
961  iter = right_commands.begin();
962  end = right_commands.end();
963  for (; iter != end; ++iter, ++c)
964  reordered_commands[c] = computation->commands[*iter];
965  KALDI_ASSERT(c == segment_end);
966  }
967  computation->commands.swap(reordered_commands);
968 
969  if (ends_with_goto)
970  FixGotoOutputReordering(nnet, computation);
971 }
void FixGotoOutputReordering(const Nnet &nnet, NnetComputation *computation)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void SplitComputationIntoSegments(const NnetComputation &computation, std::vector< std::pair< int32, int32 > > *segments)
Split the computation up into segments bounded by kNoOperationMarker.
void ConsolidateModelUpdate ( const Nnet &  nnet,
NnetComputation *  computation 
)

This optimization consolidates 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.

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

This is useful for recurrent networks. The resulting computation separates the backprop for data-derivatives from the model-update part of backprop.

Will fail if called a second time.

Definition at line 1220 of file nnet-optimize-utils.cc.

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

Referenced by Optimize().

1221  {
1222  // This following if-statement is an optimization: if the computation
1223  // request(s) had need_model_derivative == false, there would be nothing to
1224  // optimize, so don't bother trying.
1225  if (!computation->need_model_derivative)
1226  return;
1227  ModelUpdateConsolidator consolidator(nnet, computation);
1228  consolidator.ConsolidateModelUpdate();
1229 }
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:103
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 365 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().

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

395  {
396  for(int32 i = 0; i < c_component->NumComponents(); i++) {
397  const Component *c = c_component->GetComponent(i);
398  KALDI_ASSERT(c->Type() != "CompositeComponent" &&
399  "Nesting CompositeComponent within CompositeComponent is not allowed.\n"
400  "(We may change this as more complicated components are introduced.)");
401 
402  if(c->Type() == "RepeatedAffineComponent" ||
403  c->Type() == "NaturalGradientRepeatedAffineComponent") {
404  // N.B.: NaturalGradientRepeatedAffineComponent is a subclass of
405  // RepeatedAffineComponent.
406  const RepeatedAffineComponent *rac =
407  dynamic_cast<const RepeatedAffineComponent*>(c);
408  KALDI_ASSERT(rac != NULL);
409  BlockAffineComponent *bac = new BlockAffineComponent(*rac);
410  // following call deletes rac
411  c_component->SetComponent(i, bac);
412  }
413  }
414 }
#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 416 of file nnet-utils.cc.

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

416  {
417  for(int32 i = 0; i < nnet->NumComponents(); i++) {
418  const Component *const_c = nnet->GetComponent(i);
419  if(const_c->Type() == "RepeatedAffineComponent" ||
420  const_c->Type() == "NaturalGradientRepeatedAffineComponent") {
421  // N.B.: NaturalGradientRepeatedAffineComponent is a subclass of
422  // RepeatedAffineComponent.
423  const RepeatedAffineComponent *rac =
424  dynamic_cast<const RepeatedAffineComponent*>(const_c);
425  KALDI_ASSERT(rac != NULL);
426  BlockAffineComponent *bac = new BlockAffineComponent(*rac);
427  // following call deletes rac
428  nnet->SetComponent(i, bac);
429  } else if (const_c->Type() == "CompositeComponent") {
430  // We must modify the composite component, so we use the
431  // non-const GetComponent() call here.
432  Component *c = nnet->GetComponent(i);
433  CompositeComponent *cc = dynamic_cast<CompositeComponent*>(c);
434  KALDI_ASSERT(cc != NULL);
436  }
437  }
438 }
void ConvertRepeatedToBlockAffine(Nnet *nnet)
Convert all components of type RepeatedAffineComponent or NaturalGradientRepeatedAffineComponent to B...
Definition: nnet-utils.cc:416
#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
static void kaldi::nnet3::CreateComputationRequestInternal ( int32  begin_input_t,
int32  end_input_t,
int32  begin_output_t,
int32  end_output_t,
int32  num_sequences,
int32  frame_subsampling_factor,
const std::set< int32 > &  ivector_times,
ComputationRequest *  request 
)
static

Definition at line 90 of file nnet-compile-looped.cc.

References ComputationRequest::inputs, rnnlm::n, and ComputationRequest::outputs.

Referenced by CreateLoopedComputationRequestSimple().

96  {
97  request->inputs.reserve(2);
98  request->inputs.clear();
99  request->inputs.resize(1 + (ivector_times.empty() ? 0 : 1));
100  request->inputs[0].name = "input";
101  request->inputs[0].has_deriv = false;
102  request->outputs.clear();
103  request->outputs.resize(1);
104  request->outputs[0].name = "output";
105  request->outputs[0].has_deriv = false;
106  if (!ivector_times.empty()) {
107  request->inputs[1].name = "ivector";
108  request->inputs[1].has_deriv = false;
109  }
110 
111  // in the computation request the 'n' indexes (the sequence/utterance indexes)
112  // have the larger stride than 't', although this is opposite to the way it's
113  // done inside the computation. This is for user convenience where it may be
114  // easier to deal with submatrixes per sequence.
115  for (int32 n = 0; n < num_sequences; n++) {
116  int32 x = 0;
117  for (int32 t = begin_input_t; t < end_input_t; t++) {
118  request->inputs[0].indexes.push_back(Index(n, t, x));
119  }
120  for (int32 t = begin_output_t;
121  t < end_output_t;
122  t += frame_subsampling_factor)
123  request->outputs[0].indexes.push_back(Index(n, t, x));
124  }
125  if (!ivector_times.empty()) {
126  request->inputs.resize(2);
127  request->inputs[1].name = "ivector";
128  request->inputs[1].has_deriv = false;
129  for (int32 n = 0; n < num_sequences; n++) {
130  // note: std::sets store things in sorted order.
131  for (std::set<int32>::const_iterator iter = ivector_times.begin();
132  iter != ivector_times.end(); ++iter) {
133  int32 t = *iter, x = 0;
134  request->inputs[1].indexes.push_back(Index(n, t, x));
135  }
136  }
137  }
138 }
struct rnnlm::@11::@12 n
void CreateLoopedComputationRequestSimple ( const Nnet &  nnet,
int32  chunk_size,
int32  frame_subsampling_factor,
int32  ivector_period,
int32  extra_left_context_begin,
int32  extra_right_context,
int32  num_sequences,
ComputationRequest *  request1,
ComputationRequest *  request2,
ComputationRequest *  request3 
)

This function creates computation request suitable for giving to ComputeLooped().

It's intended for use with a 'simple' nnet (one satisfying IsSimpleNnet()), and this basically means that the inputs must be named "input" and possibly "ivector", and that there is an output named "output", and that those are the ones you care about (it won't generate any other outputs or use any other inputs).

If you want to use looped computation for different types of neural net, you should use the deeper interface, CompileLooped().

Parameters
[in]nnetThe neural net this computation request is to be used with. This is used to check whether the neural net accepts iVectors, and to work out the left-context and right-context required by the network.
[in]chunk_sizeThe number of frames of output that will be generated for each chunk (note: this is the shift in the t-index, which will not equal the number of output frames if frame_subsampling_factor != 1). Note: it is required that chunk_size be a multiple of ivector_period, frame_subsampling_factor, and nnet.Modulus(). You should use GetChunkSize() to compute the chunk size, giving it an advisory/ minimum chunksize, to make sure it satisfies these properties.
[in]frame_subsampling_factorThis will normally be 1, but may be more than 1 (e.g. 3) in chain systems; it determines the frame-skipping on the output, so we evaluate the output with 't' at multiples of this value.
[in]ivector_periodThe period with which iVectors are to be supplied to the network (if you're using iVectors). Not necessarily the same as the period with which the ivectors are extracted or stored on disk (–online-ivector-period). You will normally set this to the chunk size. It must divide the chunk size (if you're using iVectors) Note: you should call ModifyNnetIvectorPeriod on 'nnet' before calling this function; otherwise the neural net will most likely not actually be able to consume the iVector with this frequency.
[in]extra_left_context_beginThe additional left-context that should be supplied to the network on top of the minimum that the network requires. We call this extra_left_context_begin because this only relates to the start of the utterance (t=0).
[in]num_sequencesThe number of separate 'n' values to put in the computation; normally this will be just 1, but it can be increased to allow simultaneous operation on multiple streams of input.
[out]request1The first of the 3 requests that this function generates, that the user should then supply to CompileLooped(). Note: this will tend to be the largest computation request in terms of input, because we have to provide enough left and right context that it can evaluate the first chunk. Note: as elsewhere, the job of duplicating first and last frames enough to provide the required left/right context to the network, is left to the caller (at runtime, not during compilation).
[out]request2The second of the 3 requests that this function generates. Caution: none of the inputs and outputs should overlap.
[out]request3The third of the 3 requests that this function generates. It will be the same as request2, except for a time offset.

Definition at line 141 of file nnet-compile-looped.cc.

References ComputeSimpleNnetContext(), CreateComputationRequestInternal(), Nnet::InputDim(), KALDI_ASSERT, Mod(), and Nnet::Modulus().

Referenced by DecodableNnetSimpleLoopedInfo::Init(), and UnitTestNnetCompileLooped().

150  {
151  bool has_ivector = (nnet.InputDim("ivector") > 0);
152  int32 left_context, right_context;
153  ComputeSimpleNnetContext(nnet, &left_context, &right_context);
154  KALDI_ASSERT(chunk_size % frame_subsampling_factor == 0 &&
155  chunk_size % nnet.Modulus() == 0 &&
156  chunk_size % ivector_period == 0);
157  KALDI_ASSERT(extra_left_context_begin >= 0 && extra_right_context >= 0);
158  // note, 'end' is one past the last one.
159  int32 chunk1_input_begin_t = - left_context - extra_left_context_begin,
160  chunk1_input_end_t = chunk_size + right_context + extra_right_context,
161  chunk2_input_begin_t = chunk1_input_end_t,
162  chunk2_input_end_t = chunk2_input_begin_t + chunk_size,
163  chunk3_input_begin_t = chunk2_input_end_t,
164  chunk3_input_end_t = chunk3_input_begin_t + chunk_size;
165 
166 
167  // work out the times at which i-vectors are required.
168  std::set<int32> ivector_times1, ivector_times2, ivector_times3;
169  if (has_ivector) {
170  for (int32 t = chunk1_input_begin_t; t < chunk1_input_end_t; t++) {
171  int32 ivector_t = t - Mod(t, ivector_period);
172  ivector_times1.insert(ivector_t);
173  }
174  for (int32 t = chunk2_input_begin_t; t < chunk2_input_end_t; t++) {
175  int32 ivector_t = t - Mod(t, ivector_period);
176  if (ivector_times2.count(ivector_t) == 0 &&
177  ivector_times1.count(ivector_t) == 0)
178  ivector_times2.insert(ivector_t);
179  }
180  for (int32 t = chunk3_input_begin_t; t < chunk3_input_end_t; t++) {
181  int32 ivector_t = t - Mod(t, ivector_period);
182  if (ivector_times3.count(ivector_t) == 0 &&
183  ivector_times2.count(ivector_t) == 0 &&
184  ivector_times1.count(ivector_t) == 0)
185  ivector_times3.insert(ivector_t);
186  }
187  }
188 
190  chunk1_input_begin_t, chunk1_input_end_t,
191  0, chunk_size,
192  num_sequences, frame_subsampling_factor,
193  ivector_times1,
194  request1);
195 
197  chunk2_input_begin_t, chunk2_input_end_t,
198  chunk_size, chunk_size * 2,
199  num_sequences, frame_subsampling_factor,
200  ivector_times2,
201  request2);
202 
204  chunk3_input_begin_t, chunk3_input_end_t,
205  chunk_size * 2, chunk_size * 3,
206  num_sequences, frame_subsampling_factor,
207  ivector_times3,
208  request3);
209 
210 }
static void CreateComputationRequestInternal(int32 begin_input_t, int32 end_input_t, int32 begin_output_t, int32 end_output_t, int32 num_sequences, int32 frame_subsampling_factor, const std::set< int32 > &ivector_times, ComputationRequest *request)
void ComputeSimpleNnetContext(const Nnet &nnet, int32 *left_context, int32 *right_context)
ComputeSimpleNnetContext computes the left-context and right-context of a nnet.
Definition: nnet-utils.cc:138
I Mod(I m, I n)
Mod(m, n), defined for integers m and n where n > 0, returns the modulus m % n, defined as the intege...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
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 222 of file nnet-utils.cc.

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

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

223  {
224  KALDI_ASSERT(nnet1.NumComponents() == nnet2.NumComponents());
225  BaseFloat ans = 0.0;
226  for (int32 c = 0; c < nnet1.NumComponents(); c++) {
227  const Component *comp1 = nnet1.GetComponent(c),
228  *comp2 = nnet2.GetComponent(c);
229  if (comp1->Properties() & kUpdatableComponent) {
230  const UpdatableComponent
231  *u_comp1 = dynamic_cast<const UpdatableComponent*>(comp1),
232  *u_comp2 = dynamic_cast<const UpdatableComponent*>(comp2);
233  KALDI_ASSERT(u_comp1 != NULL && u_comp2 != NULL);
234  ans += u_comp1->DotProduct(*u_comp2);
235  }
236  }
237  return ans;
238 }
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, &graph);
72  builder.Compute(request);
73  builder.GetComputableInfo(is_computable);
74  if (GetVerboseLevel() >= 4) {
75  std::ostringstream graph_pretty;
76  graph.Print(graph_pretty, nnet.GetNodeNames());
77  KALDI_VLOG(4) << "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 1543 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().

1545  {
1546  if (eg1.io.size() != eg2.io.size())
1547  return false;
1548  for (size_t i = 0; i < eg1.io.size(); i++) {
1549  NnetIo io1 = eg1.io[i], io2 = eg2.io[i];
1550  if (io1.name != io2.name || io1.indexes != io2.indexes)
1551  return false;
1552  Matrix<BaseFloat> feat1, feat2;
1553  io1.features.GetMatrix(&feat1);
1554  io2.features.GetMatrix(&feat2);
1555  if (!ApproxEqual(feat1, feat2, delta))
1556  return false;
1557  }
1558  return true;
1559 }
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 ExpandComputation ( const Nnet &  nnet,
const MiscComputationInfo &  misc_info,
const NnetComputation &  computation,
bool  need_debug_info,
int32  num_n_values,
NnetComputation *  expanded_computation 
)

This function is used in 'shortcut' compilation to expand a computation that has been compiled for exactly 2 'n' values, to one that is suitable for some num_n_values > 2.

Parameters
[in]nnetThe neural network for which this computation is being built.
[in]misc_infoThe same MiscComputationInfo object that was present in the ComputationRequests that were originally used to generate the computation (required to generated the PrecomputedIndexes)
[in]computationThe computation that was compiled for exactly 2 'n' values (n=0 and n=1)
[in]need_debug_infoTrue if we want to retain the 'debug_info' in the output 'expanded_computation'. In any case, the 'debug_info' is required in the input computation.
[in]num_n_valuesThe number of 'n' values we want in the output computation
[out]expanded_computationThe expanded computation.

Definition at line 2998 of file nnet-optimize-utils.cc.

References ComputationExpander::Expand().

Referenced by CachingOptimizingCompiler::CompileViaShortcut().

3003  {
3004  ComputationExpander expander(nnet, misc_info, computation,
3005  need_debug_info, num_n_values,
3006  expanded_computation);
3007  expander.Expand();
3008 }
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(), DistributeComponentPrecomputedIndexes::Read(), ElementwiseProductComponent::Read(), StatisticsExtractionComponent::Read(), StatisticsExtractionComponentPrecomputedIndexes::Read(), StatisticsPoolingComponent::Read(), SumReduceComponent::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(), NnetIo::Read(), PnormComponent::Read(), Index::Read(), DistributeComponent::Read(), NnetDiscriminativeSupervision::Read(), IoSpecification::Read(), NnetChainSupervision::Read(), NnetExample::Read(), NnetDiscriminativeExample::Read(), NnetChainExample::Read(), NnetOptimizeOptions::Read(), DistributeComponentPrecomputedIndexes::Read(), ComputationRequest::Read(), ElementwiseProductComponent::Read(), Nnet::Read(), NormalizeComponent::Read(), StatisticsExtractionComponent::Read(), NnetComputation::MatrixInfo::Read(), NnetComputation::MatrixDebugInfo::Read(), NnetComputation::SubMatrixInfo::Read(), StatisticsExtractionComponentPrecomputedIndexes::Read(), NnetComputation::Command::Read(), StatisticsPoolingComponent::Read(), SumReduceComponent::Read(), NnetComputation::Read(), AffineComponent::Read(), StatisticsPoolingComponentPrecomputedIndexes::Read(), NonlinearComponent::Read(), BackpropTruncationComponent::Read(), BlockAffineComponent::Read(), BackpropTruncationComponentPrecomputedIndexes::Read(), RepeatedAffineComponent::Read(), ConstantComponent::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 }
static bool kaldi::nnet3::ExtrapolateComputationRequest ( const ComputationRequest &  request1,
const ComputationRequest &  request2,
ComputationRequest *  request3 
)
static

Definition at line 230 of file nnet-compile-looped.cc.

References AddTimeOffsetToComputationRequest(), ComputationRequest::inputs, and KALDI_ASSERT.

Referenced by CompileLoopedInternal().

233  {
234  // accepts two computation requests 'request1' and 'request2' that
235  // must be identical except for a time offset, and creates 'request3'
236  // that is the extrapolation of the next term in sequence.
237  *request3 = request2;
238  KALDI_ASSERT(!request1.inputs.empty() && !request1.inputs[0].indexes.empty() &&
239  !request2.inputs.empty() && !request2.inputs[0].indexes.empty());
240  int32 t_offset = request2.inputs[0].indexes[0].t -
241  request1.inputs[0].indexes[0].t;
242  // the following is just to make sure that the inputs are structurally
243  // equivalent.
244  AddTimeOffsetToComputationRequest(-t_offset, request3);
245  if (!(*request3 == request1))
246  return false; // there is somse structural difference, or
247  // the time offset is not consistent.
248  // the following reverses the last call to AddTimeOffsetToComputationRequest,
249  // then adds the offset we want.
250  AddTimeOffsetToComputationRequest(2 * t_offset, request3);
251  return true;
252 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void AddTimeOffsetToComputationRequest(int32 t_offset, ComputationRequest *request)
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:103
static void kaldi::nnet3::FindNumLeadingAndTrailingIdenticals ( const std::vector< std::pair< int32, int32 > > &  vec,
int32 *  num_leading_identicals,
int32 *  num_trailing_identicals 
)
static

Definition at line 2112 of file nnet-optimize-utils.cc.

References KALDI_ASSERT.

Referenced by SnipRangesRowOp().

2115  {
2116  KALDI_ASSERT(!vec.empty());
2117  const std::pair<int32, int32> *begin = &(vec[0]), *ptr = begin,
2118  *end = ptr + vec.size();
2119  while (ptr != end && ptr->first == ptr->second)
2120  ptr++;
2121  // note regarding error message: we assume all negative numbers are -1, due to
2122  // the way this is called, but it only affects how we describe the error.
2123  KALDI_ASSERT(ptr != end && "Vector consists entirely of -1's.");
2124  *num_leading_identicals = ptr - begin;
2125  const std::pair<int32, int32> *ptr2 = end - 1;
2126  // the following while loop should terminate before falling off the vector,
2127  // because we've established above (in the assertion) that the vector contains
2128  // at least one nonnegative number.
2129  while (ptr2->first == ptr2->second)
2130  ptr2--;
2131  KALDI_ASSERT(ptr2 != begin); // would be code error.
2132  *num_trailing_identicals = end - 1 - ptr2;
2133 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void kaldi::nnet3::FindNumLeadingAndTrailingNegatives ( const std::vector< int32 > &  vec,
int32 *  num_leading_negatives,
int32 *  num_trailing_negatives 
)
static

Definition at line 1970 of file nnet-optimize-utils.cc.

References KALDI_ASSERT.

Referenced by SnipMultiRowOp(), and SnipSingleRowOp().

1972  {
1973  KALDI_ASSERT(!vec.empty());
1974  const int32 *begin = &(vec[0]), *ptr = begin, *end = ptr + vec.size();
1975  while (ptr != end && *ptr < 0)
1976  ptr++;
1977  // note regarding error message: we assume all negative numbers are -1, due to
1978  // the way this is called, but it only affects how we describe the error.
1979  KALDI_ASSERT(ptr != end && "Vector consists entirely of -1's.");
1980  *num_leading_negatives = ptr - begin;
1981  const int32 *ptr2 = end - 1;
1982  // the following while loop should terminate before falling off the vector,
1983  // because we've established above (in the assertion) that the vector contains
1984  // at least one nonnegative number.
1985  while (*ptr2 < 0)
1986  ptr2--;
1987  KALDI_ASSERT(ptr2 >= begin); // or would be code error.
1988  *num_trailing_negatives = end - 1 - ptr2;
1989 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void kaldi::nnet3::FindNumLeadingAndTrailingNegatives ( const std::vector< std::pair< int32, int32 > > &  vec,
int32 *  num_leading_negatives,
int32 *  num_trailing_negatives 
)
static

Definition at line 2041 of file nnet-optimize-utils.cc.

References KALDI_ASSERT.

2044  {
2045  KALDI_ASSERT(!vec.empty());
2046  const std::pair<int32, int32> *begin = &(vec[0]), *ptr = begin,
2047  *end = ptr + vec.size();
2048  while (ptr != end && ptr->first < 0)
2049  ptr++;
2050  // note regarding error message: we assume all negative numbers are -1, due to
2051  // the way this is called, but it only affects how we describe the error.
2052  KALDI_ASSERT(ptr != end && "Vector consists entirely of -1's.");
2053  *num_leading_negatives = ptr - begin;
2054  const std::pair<int32, int32> *ptr2 = end - 1;
2055  // the following while loop should terminate before falling off the vector,
2056  // because we've established above (in the assertion) that the vector contains
2057  // at least one nonnegative number.
2058  while (ptr2->first < 0)
2059  ptr2--;
2060  KALDI_ASSERT(ptr2 != begin); // would be code error.
2061  *num_trailing_negatives = end - 1 - ptr2;
2062 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
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 467 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().

467  {
468  int32 num_components = nnet.NumComponents(), num_nodes = nnet.NumNodes();
469  std::vector<bool> is_used(num_components, false);
470  for (int32 i = 0; i < num_nodes; i++) {
471  if (nnet.IsComponentNode(i)) {
472  int32 c = nnet.GetNode(i).u.component_index;
473  KALDI_ASSERT(c >= 0 && c < num_components);
474  is_used[c] = true;
475  }
476  }
477  components->clear();
478  for (int32 i = 0; i < num_components; i++)
479  if (!is_used[i])
480  components->push_back(i);
481 }
#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 483 of file nnet-utils.cc.

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

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

483  {
484 
485  std::vector<std::vector<int32> > depend_on_graph, dependency_graph;
486  NnetToDirectedGraph(nnet, &depend_on_graph);
487  // depend_on_graph[i] is a list of all the nodes that depend on i.
488  ComputeGraphTranspose(depend_on_graph, &dependency_graph);
489  // dependency_graph[i] is a list of all the nodes that i depends on,
490  // to be computed.
491 
492  // Find all nodes required to produce the outputs.
493  int32 num_nodes = nnet.NumNodes();
494  assert(num_nodes == static_cast<int32>(dependency_graph.size()));
495  std::vector<bool> node_is_required(num_nodes, false);
496  std::vector<int32> queue;
497  for (int32 i = 0; i < num_nodes; i++) {
498  if (nnet.IsOutputNode(i))
499  queue.push_back(i);
500  }
501  while (!queue.empty()) {
502  int32 i = queue.back();
503  queue.pop_back();
504  if (!node_is_required[i]) {
505  node_is_required[i] = true;
506  for (size_t j = 0; j < dependency_graph[i].size(); j++)
507  queue.push_back(dependency_graph[i][j]);
508  }
509  }
510  nodes->clear();
511  for (int32 i = 0; i < num_nodes; i++) {
512  if (!node_is_required[i])
513  nodes->push_back(i);
514  }
515 }
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). Each element of 'sccs' is a list of node indexes that are in that scc.

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

References FindSccsTarjan(), and KALDI_ASSERT.

Referenced by ComputeNnetComputationEpochs(), GraphHasCycles(), 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 FixGotoLabel ( NnetComputation *  computation)

This function ensures that the arg1 of a final command of type kGotoLabel is the same as the command with type kNoOperationLabel.

This is necessary if you do any other type of optimization after 'OptimizeLoopedComputation()'.

Definition at line 3765 of file nnet-optimize-utils.cc.

References NnetComputation::commands, rnnlm::d, KALDI_ERR, kGotoLabel, kNoOperationLabel, and kProvideOutput.

Referenced by FixGotoOutputReordering(), Optimize(), ComputationLoopedOptimizer::Optimize(), and RemoveUnnecessaryAllocation().

3765  {
3766  int32 num_commands = computation->commands.size();
3767  if (num_commands == 0)
3768  return;
3769  for (int32 c = num_commands - 1; c >= 0; c--) {
3770  if (computation->commands[c].command_type == kGotoLabel) {
3771  int32 dest_command = computation->commands[c].arg1;
3772  if (static_cast<size_t>(dest_command) < computation->commands.size() &&
3773  computation->commands[dest_command].command_type == kNoOperationLabel)
3774  return; // nothing to fix.
3775  for (int32 d = 0; d + 1 < num_commands; d++) {
3776  if (computation->commands[d].command_type == kNoOperationLabel) {
3777  computation->commands[c].arg1 = d;
3778  return;
3779  }
3780  }
3781  KALDI_ERR << "Label not found.";
3782  } else if (computation->commands[c].command_type == kProvideOutput) {
3783  // sometimes kProvideOutput commands are temporarily ordered after
3784  // the kGotoLabel command, and we need to work in that case.
3785  continue;
3786  } else {
3787  // it loks like there is no 'goto' command in this computation-
3788  // if there were, it would be right at the end, possibly followed by
3789  // kProvideOutput commands.
3790  break;
3791  }
3792  }
3793 }
#define KALDI_ERR
Definition: kaldi-error.h:127
void kaldi::nnet3::FixGotoOutputReordering ( const Nnet &  nnet,
NnetComputation *  computation 
)

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

References NnetComputation::commands, FixGotoLabel(), rnnlm::i, kAcceptInput, KALDI_ASSERT, KALDI_ERR, kAllocMatrixFromOther, kGotoLabel, kNoOperationMarker, kProvideOutput, and NnetComputation::Print().

Referenced by ConsolidateIoOperations().

861  {
862  FixGotoLabel(computation); // make sure the destination label of the goto statement was
863  // correct.
864  int32 goto_command_index = -1;
865  for (int32 c = computation->commands.size(); c >= 0; c--)
866  if (computation->commands[c].command_type == kGotoLabel)
867  goto_command_index = c;
868  KALDI_ASSERT(goto_command_index > 0);
869  int32 goto_label_index = computation->commands[goto_command_index].arg1;
870 
871  std::vector<int32> output_commands_after_goto,
872  output_commands_after_label;
873  for (int32 c = goto_command_index + 1;
874  c < static_cast<int32>(computation->commands.size()); c++) {
875  KALDI_ASSERT(computation->commands[c].command_type == kProvideOutput);
876  output_commands_after_goto.push_back(c);
877  }
878  for (int32 c = goto_label_index + 1;
879  c < goto_command_index; c++) { // note: we break from this loop.
880  CommandType t = computation->commands[c].command_type;
881  if (t == kProvideOutput)
882  output_commands_after_label.push_back(c);
883  else if (t != kNoOperationMarker && t != kAcceptInput)
884  break;
885  }
886  if (output_commands_after_goto.size() != output_commands_after_label.size()) {
887  computation->Print(std::cerr, nnet);
888  KALDI_ERR << "Could not fix goto/output reordering, size mismatch.";
889  }
890  NnetComputation::Command goto_command = computation->commands[goto_command_index];
891  // be we'll be replacing the final kProvideOutput commands with
892  // kAllocMatrixFromOther [i.e. swap commands], and moving them one command
893  // backward; later we'll put the goto command at the end.
894  for (size_t i = 0; i < output_commands_after_goto.size(); i++) {
895  int32 c1 = output_commands_after_label[i],
896  c2 = output_commands_after_goto[i],
897  new_c2 = c2 - 1;
898  int32 s1 = computation->commands[c1].arg1,
899  s2 = computation->commands[c2].arg1;
900  // The following assert checks that the network node-index is the same...
901  // the idea is that the outputs should have been provided in the same order.
902  // I can think of no reason why the order might be different.
903  KALDI_ASSERT(computation->commands[c1].arg2 ==
904  computation->commands[c1].arg2);
905  computation->commands[new_c2].command_type = kAllocMatrixFromOther;
906  computation->commands[new_c2].arg1 = s1;
907  computation->commands[new_c2].arg2 = s2;
908  }
909  // ... and move the goto command to the end.
910  computation->commands.back() = goto_command;
911 }
CommandType
CommandType is an enum that describes the category of the command used in the NnetComputation.
#define KALDI_ERR
Definition: kaldi-error.h:127
void FixGotoLabel(NnetComputation *computation)
This function ensures that the arg1 of a final command of type kGotoLabel is the same as the command ...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
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 995 of file nnet-test-utils.cc.

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

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

997  {
998 start:
999  int32 network_type = RandInt(0, 11);
1000  switch(network_type) {
1001  case 0:
1002  GenerateConfigSequenceSimplest(opts, configs);
1003  break;
1004  case 1:
1005  if (!opts.allow_context)
1006  goto start;
1007  GenerateConfigSequenceSimpleContext(opts, configs);
1008  break;
1009  case 2:
1010  if (!opts.allow_context || !opts.allow_nonlinearity)
1011  goto start;
1012  GenerateConfigSequenceSimple(opts, configs);
1013  break;
1014  case 3:
1015  if (!opts.allow_recursion || !opts.allow_context ||
1016  !opts.allow_nonlinearity)
1017  goto start;
1018  GenerateConfigSequenceRnn(opts, configs);
1019  break;
1020  case 4:
1021  if (!opts.allow_recursion || !opts.allow_context ||
1022  !opts.allow_nonlinearity)
1023  goto start;
1024  GenerateConfigSequenceRnnClockwork(opts, configs);
1025  break;
1026  case 5:
1027  if (!opts.allow_recursion || !opts.allow_context ||
1028  !opts.allow_nonlinearity)
1029  goto start;
1030  GenerateConfigSequenceLstm(opts, configs);
1031  break;
1032  case 6:
1033  if (!opts.allow_recursion || !opts.allow_context ||
1034  !opts.allow_nonlinearity)
1035  goto start;
1036  GenerateConfigSequenceLstm(opts, configs);
1037  break;
1038  case 7:
1039  if (!opts.allow_nonlinearity)
1040  goto start;
1041  GenerateConfigSequenceCnn(opts, configs);
1042  break;
1043  case 8:
1044  if (!opts.allow_use_of_x_dim)
1045  goto start;
1046  GenerateConfigSequenceDistribute(opts, configs);
1047  break;
1048  case 9:
1049  GenerateConfigSequenceCompositeBlock(opts, configs);
1050  break;
1051  case 10:
1052  if (!opts.allow_statistics_pooling)
1053  goto start;
1054  GenerateConfigSequenceStatistics(opts, configs);
1055  break;
1056  case 11:
1057  if (!opts.allow_recursion || !opts.allow_context ||
1058  !opts.allow_nonlinearity)
1059  goto start;
1061  break;
1062  default:
1063  KALDI_ERR << "Error generating config sequence.";
1064  }
1065  KALDI_ASSERT(!configs->empty());
1066 }
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 850 of file nnet-test-utils.cc.

References kaldi::Rand().

Referenced by GenerateConfigSequence().

852  {
853  std::ostringstream os;
854 
855 
856  int32 input_x_dim = 10 + Rand() % 20,
857  input_y_dim = 10 + Rand() % 20,
858  input_z_dim = 3 + Rand() % 10,
859  filt_x_dim = 1 + Rand() % input_x_dim,
860  filt_y_dim = 1 + Rand() % input_y_dim,
861  num_filters = 10 + Rand() % 20,
862  filt_x_step = (1 + Rand() % filt_x_dim),
863  filt_y_step = (1 + Rand() % filt_y_dim);
864  int32 remainder = (input_x_dim - filt_x_dim) % filt_x_step;
865  // adjusting input_x_dim to ensure divisibility
866  input_x_dim = input_x_dim - remainder;
867  remainder = (input_y_dim - filt_y_dim) % filt_y_step;
868  // adjusting input_x_dim to ensure divisibility
869  input_y_dim = input_y_dim - remainder;
870 
871  int32 input_vectorization = Rand() % 2;
872  std::string vectorization;
873  if (input_vectorization == 0) {
874  vectorization = "yzx";
875  } else {
876  vectorization = "zyx";
877  }
878 
879  os << "component name=conv type=ConvolutionComponent "
880  << " input-x-dim=" << input_x_dim
881  << " input-y-dim=" << input_y_dim
882  << " input-z-dim=" << input_z_dim
883  << " filt-x-dim=" << filt_x_dim
884  << " filt-y-dim=" << filt_y_dim
885  << " filt-x-step=" << filt_x_step
886  << " filt-y-step=" << filt_y_step
887  << " num-filters=" << num_filters
888  << " input-vectorization-order=" << vectorization
889  << std::endl;
890 
891  int32 conv_output_x_dim = (1 + (input_x_dim - filt_x_dim) / filt_x_step);
892  int32 conv_output_y_dim = (1 + (input_y_dim - filt_y_dim) / filt_y_step);
893  int32 conv_output_z_dim = num_filters;
894  int32 pool_x_size = 1 + Rand() % conv_output_x_dim;
895  int32 pool_y_size = 1 + Rand() % conv_output_y_dim;
896  int32 pool_z_size = 1 + Rand() % conv_output_z_dim;
897  int32 pool_x_step = 1;
898  int32 pool_y_step = 1;
899  int32 pool_z_step = 1;
900  do {
901  pool_x_step = (1 + Rand() % pool_x_size);
902  } while((conv_output_x_dim - pool_x_size) % pool_x_step);
903  do {
904  pool_y_step = (1 + Rand() % pool_y_size);
905  } while((conv_output_y_dim - pool_y_size) % pool_y_step);
906  do {
907  pool_z_step = (1 + Rand() % pool_z_size);
908  } while((conv_output_z_dim - pool_z_size) % pool_z_step);
909 
910  os << "component name=maxpooling type=MaxpoolingComponent "
911  << " input-x-dim=" << conv_output_x_dim
912  << " input-y-dim=" << conv_output_y_dim
913  << " input-z-dim=" << conv_output_z_dim
914  << " pool-x-size=" << pool_x_size
915  << " pool-y-size=" << pool_y_size
916  << " pool-z-size=" << pool_z_size
917  << " pool-x-step=" << pool_x_step
918  << " pool-y-step=" << pool_y_step
919  << " pool-z-step=" << pool_z_step
920  << std::endl;
921 
922  os << "input-node name=input dim=" << (input_x_dim * input_y_dim * input_z_dim) << std::endl;
923  os << "component-node name=conv_node component=conv input=input\n";
924  os << "component-node name=maxpooling_node component=maxpooling input=conv_node\n";
925  os << "output-node name=output input=conv_node\n";
926  configs->push_back(os.str());
927 }
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 956 of file nnet-test-utils.cc.

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

Referenced by GenerateConfigSequence(), and UnitTestConvertRepeatedToBlockAffineComposite().

957  {
958  int32 num_components = RandInt(1,5);
959  int32 input_dim = 10 * RandInt(1,10);
960  if (opts.output_dim > 0) {
961  KALDI_WARN << "This function doesn't take a requested output_dim due to "
962  "implementation complications.";
963  }
964  int32 max_rows_process = 512 + 512 * RandInt(1,3);
965  std::ostringstream os;
966  os << "component name=composite1 type=CompositeComponent max-rows-process="
967  << max_rows_process << " num-components=" << num_components;
968 
969  int32 types_length = 3;
970  std::string types[] = {"BlockAffineComponent",
971  "RepeatedAffineComponent",
972  "NaturalGradientRepeatedAffineComponent"};
973  int32 last_output_dim = input_dim;
974  // components within a composite component are indexed from 1.
975  for(int32 i = 1; i <= num_components; i++) {
976  os << " component" << i << "=";
977  int32 rand_index = RandInt(0, types_length - 1);
978  std::string rand_type = types[rand_index];
979  os << "'type=" << rand_type << " input-dim=" << last_output_dim;
980  int32 current_output_dim = 10 * RandInt(1,10);
981  // must be a divisor or current_output_dim and last_output_dim
982  int32 num_repeats = 10;
983  os << " output-dim=" << current_output_dim;
984  std::string repeats_string = (rand_type == "BlockAffineComponent") ? "num-blocks": "num-repeats";
985  os << " " << repeats_string << "=" << num_repeats << "'";
986  last_output_dim = current_output_dim;
987  }
988  os << std::endl << std::endl;
989  os << "input-node name=input dim=" << input_dim << std::endl;
990  os << "component-node name=composite1 component=composite1 input=input\n";
991  os << "output-node name=output input=composite1\n";
992  configs->push_back(os.str());
993 }
#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 930 of file nnet-test-utils.cc.

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

Referenced by GenerateConfigSequence().

932  {
933  int32 output_dim = (opts.output_dim > 0 ? opts.output_dim : 100);
934  int32 x_expand = RandInt(1, 5), after_expand_dim = RandInt(10, 20),
935  input_dim = x_expand * after_expand_dim;
936  std::ostringstream os;
937  os << "input-node name=input dim=" << input_dim << std::endl;
938  os << "component name=distribute type=DistributeComponent input-dim="
939  << input_dim << " output-dim=" << after_expand_dim << std::endl;
940  os << "component-node name=distribute component=distribute input=input\n";
941  os << "component name=affine type=AffineComponent input-dim="
942  << after_expand_dim << " output-dim=" << output_dim << std::endl;
943  os << "component-node name=affine component=affine input=distribute\n";
944  os << "output-node name=output input=Sum(";
945  for (int32 i = 0; i < x_expand;