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

Namespaces

 computation_graph
 
 time_height_convolution
 

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  BatchNormComponent
 
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  DropoutMaskComponent
 
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  ImageAugmentationConfig
 
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
 
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
 NoOpComponent just duplicates its input. More...
 
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  SumBlockComponent
 SumBlockComponent sums over blocks of its input: for instance, if you create one with the config "input-dim=400 output-dim=100", its output will be the sum over the 4 100-dimensional blocks of the input. More...
 
class  SumDescriptor
 This is an abstract base-class. More...
 
class  SumGroupComponent
 SumGroupComponent is used to sum up groups of posteriors. More...
 
class  SwitchingForwardingDescriptor
 
class  TanhComponent
 
struct  TarjanNode
 
class  TimeHeightConvolutionComponent
 TimeHeightConvolutionComponent implements 2-dimensional convolution where one of the dimensions of convolution (which traditionally would be called the width axis) is identified with time (i.e. More...
 
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, kUsesMemo = 0x4000, kRandomComponent = 0x8000
}
 
enum  CommandType {
  kAllocMatrixUndefined, kAllocMatrixZeroed, kDeallocMatrix, kAllocMatrixFromOther,
  kAllocMatrixFromOtherZeroed, kPropagate, kBackprop, kBackpropNoModelUpdate,
  kMatrixCopy, kMatrixAdd, kCopyRows, kAddRows,
  kCopyRowsMulti, kCopyToRowsMulti, kAddRowsMulti, kAddToRowsMulti,
  kAddRowRanges, kAcceptInput, kProvideOutput, kNoOperation,
  kNoOperationPermanent, 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
}
 
enum  FillMode { kNearest, kReflect }
 

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 GetCommandsOfType (const NnetComputation &computation, CommandType t, std::vector< int32 > *command_indexes)
 This utility function works out from a computation, the command-indexes of the commands of the given type. 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...
 
void RecomputeStats (const std::vector< NnetChainExample > &egs, const chain::ChainTrainingOptions &chain_config, const fst::StdVectorFst &den_fst, Nnet *nnet)
 This function zeros the stored component-level stats in the nnet using ZeroComponentStats(), then recomputes them with the supplied egs. 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)
 
bool CheckStringsApproxEqual (const std::string &a, const std::string &b, int32 tolerance=3)
 
void TestNnetComponentIo (Component *c)
 
void TestNnetComponentCopy (Component *c)
 
void TestNnetComponentAddScale (Component *c)
 
void TestNnetComponentVectorizeUnVectorize (Component *c)
 
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...
 
static int32 FindNStride (const std::vector< Index > &indexes, bool full_check)
 
static int32 FindNStride (const std::vector< Cindex > &cindexes, bool full_check)
 
static void ConvertNumNValues (int32 n_stride, int32 old_N, int32 new_N, const std::vector< Index > &indexes_in, std::vector< Index > *indexes_out)
 
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 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 GenerateConfigSequenceCnnNew (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 components to dropout_proportion value. More...
 
bool HasBatchnorm (const Nnet &nnet)
 Returns true if nnet has at least one component of type BatchNormComponent. More...
 
void RecomputeStats (const std::vector< NnetExample > &egs, Nnet *nnet)
 This function zeros the stored component-level stats in the nnet using ZeroComponentStats(), then recomputes them with the supplied egs. More...
 
void SetBatchnormTestMode (bool test_mode, Nnet *nnet)
 This function affects only components of type BatchNormComponent. More...
 
void SetDropoutTestMode (bool test_mode, Nnet *nnet)
 This function affects components of child-classes of RandomComponent( currently only DropoutComponent and DropoutMaskComponent). 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)
 
void RenameIoNames (const std::string &old_name, const std::string &new_name, NnetExample *eg_modified)
 
void ScaleAndRenameOutput (BaseFloat weight, const std::string &new_output_name, NnetExample *eg)
 
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)
 
void ApplyAffineTransform (MatrixBase< BaseFloat > &transform, int32 num_channels, MatrixBase< BaseFloat > *image, FillMode fill_mode)
 This function applies a geometric transformation 'transform' to the image. More...
 
void PerturbImage (const ImageAugmentationConfig &config, MatrixBase< BaseFloat > *image)
 This function randomly modifies (perturbs) the image by applying different geometric transformations according to the options in 'config'. More...
 
void PerturbImageInNnetExample (const ImageAugmentationConfig &config, NnetExample *eg)
 This function does image perturbation as directed by 'config' The example 'eg' is expected to contain a NnetIo member with the name 'input', representing an image. More...
 
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 GeneralMatrix &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...
 
const int kNoTime = std::numeric_limits<int32>::min()
 

Typedef Documentation

typedef std::pair<int32, Index> Cindex

Definition at line 115 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
    • arg5 is the index of the memo saved from Propagate()'s return value, or 0 if it saves no memo.
    • arg6 is 1 if we need to call StoreStats() after the Propagate, or 0 if we don't. We used to have a separate command for storing the stats, but that has been removed.
  • 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.
    • arg7 is the index of the memo which is generated from the corresponding Propagate() function if the flag kUsesMemo is set; 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, and will be removed by optimization code (sometimes useful during optimization)
  • kNoOperationPermanent: like kNoOperation, but won't be removed by optimization code. This is used to ensure that for 'trivial' computations, which just copy the input to the output, the block of commands for the forward or backward propagation is nonempty (to avoid confusing the computation code).
  • 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 
kBackprop 
kBackpropNoModelUpdate 
kMatrixCopy 
kMatrixAdd 
kCopyRows 
kAddRows 
kCopyRowsMulti 
kCopyToRowsMulti 
kAddRowsMulti 
kAddToRowsMulti 
kAddRowRanges 
kAcceptInput 
kProvideOutput 
kNoOperation 
kNoOperationPermanent 
kNoOperationMarker 
kNoOperationLabel 
kGotoLabel 

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

249  {
257  kGotoLabel };
Enumerator
kSimpleComponent 
kUpdatableComponent 
kLinearInInput 
kLinearInParameters 
kPropagateInPlace 
kPropagateAdds 
kReordersIndexes 
kBackpropAdds 
kBackpropNeedsInput 
kBackpropNeedsOutput 
kBackpropInPlace 
kStoresStats 
kInputContiguous 
kOutputContiguous 
kUsesMemo 
kRandomComponent 

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  kUsesMemo = 0x4000, // true if the component returns a void* pointer from its
88  // Propagate() function that needs to be passed into the
89  // corresponding Backprop function.
90  kRandomComponent = 0x8000 // true if the component has some kind of
91  // randomness, like DropoutComponent (these should
92  // inherit from class RandomComponent.
93 };
enum FillMode
Enumerator
kNearest 
kReflect 

Definition at line 31 of file nnet3-egs-augment-image.cc.

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

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

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

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

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

References rnnlm::i.

Referenced by Compiler::OutputDebugInfo().

1155  {
1156  size_t indexes_size = indexes.size();
1157  if (indexes_size > out->size())
1158  out->reserve(out->size() + indexes_size);
1159  for (size_t i = 0; i < indexes_size; i++)
1160  out->push_back(Cindex(node, indexes[i]));
1161 }
std::pair< int32, Index > Cindex
Definition: nnet-common.h:115
void kaldi::nnet3::ApplyAffineTransform ( MatrixBase< BaseFloat > &  transform,
int32  num_channels,
MatrixBase< BaseFloat > *  image,
FillMode  fill_mode 
)

This function applies a geometric transformation 'transform' to the image.

Reference: Digital Image Processing book by Gonzalez and Woods.

Parameters
[in]transformThe 3x3 geometric transformation matrix to apply.
[in]num_channelsNumber of channels (i.e. colors) of the image
[in,out]imageThe image matrix to be modified. image->NumRows() is the width (number of x values) in the image; image->NumCols() is the height times number of channels (channel varies the fastest).

Definition at line 100 of file nnet3-egs-augment-image.cc.

References KALDI_ASSERT, kNearest, kReflect, MatrixBase< Real >::NumCols(), and MatrixBase< Real >::NumRows().

Referenced by PerturbImage().

103  {
104  int32 num_rows = image->NumRows(),
105  num_cols = image->NumCols(),
106  height = num_cols / num_channels,
107  width = num_rows;
108  KALDI_ASSERT(num_cols % num_channels == 0);
109  Matrix<BaseFloat> original_image(*image);
110  for (int32 r = 0; r < width; r++) {
111  for (int32 c = 0; c < height; c++) {
112  // (r_old, c_old) is the coordinate of the pixel in the original image
113  // while (r, c) is the coordinate in the new (transformed) image.
114  BaseFloat r_old = transform(0, 0) * r +
115  transform(0, 1) * c + transform(0, 2);
116  BaseFloat c_old = transform(1, 0) * r +
117  transform(1, 1) * c + transform(1, 2);
118  // We are going to do bilinear interpolation between 4 closest points
119  // to the point (r_old, c_old) of the original image. We have:
120  // r1 <= r_old <= r2
121  // c1 <= c_old <= c2
122  int32 r1 = static_cast<int32>(floor(r_old));
123  int32 c1 = static_cast<int32>(floor(c_old));
124  int32 r2 = r1 + 1;
125  int32 c2 = c1 + 1;
126 
127  // These weights determine how much each of the 4 points contributes
128  // to the final interpolated value:
129  BaseFloat weight_11 = (r2 - r_old) * (c2 - c_old),
130  weight_12 = (r2 - r_old) * (c_old - c1),
131  weight_21 = (r_old - r1) * (c2 - c_old),
132  weight_22 = (r_old - r1) * (c_old - c1);
133  // Handle edge conditions:
134  if (fill_mode == kNearest) {
135  if (r1 < 0) {
136  r1 = 0;
137  if (r2 < 0) r2 = 0;
138  }
139  if (r2 >= width) {
140  r2 = width - 1;
141  if (r1 >= width) r1 = width - 1;
142  }
143  if (c1 < 0) {
144  c1 = 0;
145  if (c2 < 0) c2 = 0;
146  }
147  if (c2 >= height) {
148  c2 = height - 1;
149  if (c1 >= height) c1 = height - 1;
150  }
151  } else {
152  KALDI_ASSERT(fill_mode == kReflect);
153  if (r1 < 0) {
154  r1 = - r1;
155  if (r2 < 0) r2 = - r2;
156  }
157  if (r2 >= width) {
158  r2 = 2 * width - 2 - r2;
159  if (r1 >= width) r1 = 2 * width - 2 - r1;
160  }
161  if (c1 < 0) {
162  c1 = - c1;
163  if (c2 < 0) c2 = -c2;
164  }
165  if (c2 >= height) {
166  c2 = 2 * height - 2 - c2;
167  if (c1 >= height) c1 = 2 * height - 2 - c1;
168  }
169  }
170  for (int32 ch = 0; ch < num_channels; ch++) {
171  // find the values at the 4 points
172  BaseFloat p11 = original_image(r1, num_channels * c1 + ch),
173  p12 = original_image(r1, num_channels * c2 + ch),
174  p21 = original_image(r2, num_channels * c1 + ch),
175  p22 = original_image(r2, num_channels * c2 + ch);
176  (*image)(r, num_channels * c + ch) = weight_11 * p11 + weight_12 * p12 +
177  weight_21 * p21 + weight_22 * p22;
178  }
179  }
180  }
181 }
float BaseFloat
Definition: kaldi-types.h:29
MatrixIndexT NumRows() const
Returns number of rows (or zero for emtpy matrix).
Definition: kaldi-matrix.h:58
MatrixIndexT NumCols() const
Returns number of columns (or zero for emtpy matrix).
Definition: kaldi-matrix.h:61
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
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 1011 of file nnet-analyze.cc.

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

Referenced by Optimize().

1013  {
1014  try {
1015  if (!computation.commands.empty() &&
1016  computation.commands.back().command_type == kGotoLabel) {
1017  // Online computations need to be treated specially.
1018  CheckComputationOnline(nnet, computation, check_rewrite);
1019  } else {
1020  CheckComputationOptions opts;
1021  opts.check_rewrite = check_rewrite;
1022  ComputationChecker checker(opts, nnet, computation);
1023  checker.Check();
1024  }
1025  } catch (...) {
1026  computation.Print(std::cerr, nnet);
1027  KALDI_ERR << "Computation check failed for computation printed above "
1028  "(actual error message is above computation)";
1029  }
1030 }
#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 984 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().

986  {
987  int32 num_commands = computation.commands.size();
988  KALDI_ASSERT(computation.commands[num_commands-1].command_type == kGotoLabel);
989  for (int32 c = num_commands - 2;
990  c >= 0 && computation.commands[c].command_type == kAllocMatrixFromOther;
991  c--) {
992  // this command can be interpreted as "initialize matrix referred to by
993  // c.arg2 with the matrix referred to by c.arg2".
994  // Because this would be interpreted by the analysis code as initializing a
995  // matrix that has already been initialized, we turn this into a command
996  // that just deallocates the matrix in c.arg2. [note: all these indexes
997  // are actually submatrix indexes].
998  computation.commands[c].command_type = kDeallocMatrix;
999  std::swap(computation.commands[c].arg1, computation.commands[c].arg2);
1000  }
1001 
1002  CheckComputationOptions opts;
1003  opts.check_rewrite = check_rewrite;
1004  opts.check_unused_variables = false;
1005  // We can always do this check with online computations, since they do not
1006  // have the RemoveUnnecessaryAllocation() optimization applied.
1007  ComputationChecker checker(opts, nnet, computation);
1008  checker.Check();
1009 }
void swap(basic_filebuf< CharT, Traits > &x, basic_filebuf< CharT, Traits > &y)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
bool kaldi::nnet3::CheckStringsApproxEqual ( const std::string &  a,
const std::string &  b,
int32  tolerance = 3 
)

Definition at line 39 of file nnet-component-test.cc.

References KALDI_WARN, and kaldi::StringsApproxEqual().

Referenced by TestNnetComponentAddScale(), TestNnetComponentIo(), TestNnetComponentUpdatable(), and TestNnetComponentVectorizeUnVectorize().

41  {
42  if (!StringsApproxEqual(a, b, tolerance)) {
43  KALDI_WARN << "Strings differ: " << a
44  << "\vs.\n" << b;
45  return false;
46  } else {
47  return true;
48  }
49 }
bool StringsApproxEqual(const std::string &a, const std::string &b, int32 decimal_places_tolerance)
This function returns true when two text strings are approximately equal, and false when they are not...
Definition: text-utils.cc:335
#define KALDI_WARN
Definition: kaldi-error.h:130
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 308 of file nnet-compile-looped.cc.

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

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

313  {
314  int32 num_requests1 = 5, factor = 2, max_requests = 100,
315  num_requests;
316 
317  Timer timer;
318 
319  for (num_requests = num_requests1; num_requests <= max_requests;
320  num_requests *= factor) {
321  if (CompileLoopedInternal(nnet, optimize_opts,
322  request1, request2, request3,
323  num_requests, computation)) {
324  KALDI_LOG << "Spent " << timer.Elapsed()
325  << " seconds in looped compilation.";
326  return;
327  } else {
328  KALDI_VLOG(2) << "Looped compilation failed with "
329  << num_requests << " requests, trying "
330  << (num_requests * factor);
331  }
332  }
333  KALDI_ERR << "Looped compilation failed with "
334  << (num_requests/factor) << " requests, which "
335  << "we expect should be enough... something "
336  << "went wrong.";
337 }
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  int32 dont_really_care = MaxOutputTimeInRequest(request3);
301  Optimize(optimize_opts, nnet,
302  dont_really_care, computation);
303 
304  return computation->commands.size() != 0 &&
305  computation->commands.back().command_type == kGotoLabel;
306 }
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 185 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().

187  {
188  KALDI_ASSERT(nnet1.NumComponents() == nnet2.NumComponents());
189  int32 updatable_c = 0;
190  for (int32 c = 0; c < nnet1.NumComponents(); c++) {
191  const Component *comp1 = nnet1.GetComponent(c),
192  *comp2 = nnet2.GetComponent(c);
193  if (comp1->Properties() & kUpdatableComponent) {
194  const UpdatableComponent
195  *u_comp1 = dynamic_cast<const UpdatableComponent*>(comp1),
196  *u_comp2 = dynamic_cast<const UpdatableComponent*>(comp2);
197  KALDI_ASSERT(u_comp1 != NULL && u_comp2 != NULL);
198  dot_prod->Data()[updatable_c] = u_comp1->DotProduct(*u_comp2);
199  updatable_c++;
200  }
201  }
202  KALDI_ASSERT(updatable_c == dot_prod->Dim());
203 }
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 175 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().

178  {
179  int32 num_rows = nnet_output.NumRows(),
180  num_cols = nnet_output.NumCols();
181  KALDI_ASSERT(supervision.NumRows() == num_rows &&
182  supervision.NumCols() == num_cols);
183 
184  CuArray<int32> best_index(num_rows);
185  nnet_output.FindRowMaxId(&best_index);
186  std::vector<int32> best_index_cpu;
187  // wasteful copy, but doesn't dominate.
188  best_index.CopyToVec(&best_index_cpu);
189 
190 
191  double tot_weight = 0.0,
192  tot_accuracy = 0.0;
193 
194  // note: we expect that in most cases where this code is called,
195  // supervision.Type() will be kSparseMatrix.
196  switch (supervision.Type()) {
197  case kCompressedMatrix: {
198  Matrix<BaseFloat> mat;
199  supervision.GetMatrix(&mat);
200  for (int32 r = 0; r < num_rows; r++) {
201  SubVector<BaseFloat> vec(mat, r);
202  BaseFloat row_sum = vec.Sum();
203  KALDI_ASSERT(row_sum >= 0.0);
204  int32 best_index;
205  vec.Max(&best_index); // discard max value.
206  tot_weight += row_sum;
207  if (best_index == best_index_cpu[r])
208  tot_accuracy += row_sum;
209  }
210  break;
211 
212  }
213  case kFullMatrix: {
214  const Matrix<BaseFloat> &mat = supervision.GetFullMatrix();
215  for (int32 r = 0; r < num_rows; r++) {
216  SubVector<BaseFloat> vec(mat, r);
217  BaseFloat row_sum = vec.Sum();
218  KALDI_ASSERT(row_sum >= 0.0);
219  int32 best_index;
220  vec.Max(&best_index); // discard max value.
221  tot_weight += row_sum;
222  if (best_index == best_index_cpu[r])
223  tot_accuracy += row_sum;
224  }
225  break;
226  }
227  case kSparseMatrix: {
228  const SparseMatrix<BaseFloat> &smat = supervision.GetSparseMatrix();
229  for (int32 r = 0; r < num_rows; r++) {
230  const SparseVector<BaseFloat> &row = smat.Row(r);
231  BaseFloat row_sum = row.Sum();
232  int32 best_index;
233  row.Max(&best_index);
234  KALDI_ASSERT(best_index < num_cols);
235  tot_weight += row_sum;
236  if (best_index == best_index_cpu[r])
237  tot_accuracy += row_sum;
238  }
239  break;
240  }
241  default: KALDI_ERR << "Bad general-matrix type.";
242  }
243  *tot_weight_out = tot_weight;
244  *tot_accuracy_out = tot_accuracy;
245 }
void FindRowMaxId(CuArray< int32 > *id) const
Find the id of the maximal element for each row.
Definition: cu-matrix.cc:1675
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, kNoOperationPermanent, kPropagate, kPropagateAdds, kProvideOutput, kReadAccess, kReadWriteAccess, 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 kBackprop:
296  vars.RecordAccessForSubmatrix(c.arg3, kReadAccess, &attr);
297  vars.RecordAccessForSubmatrix(c.arg4, kReadAccess, &attr);
298  vars.RecordAccessForSubmatrix(c.arg5, kReadAccess, &attr);
299  if (nnet.GetComponent(c.arg1)->Properties() & kBackpropAdds)
300  vars.RecordAccessForSubmatrix(c.arg6, kReadWriteAccess, &attr);
301  else
302  vars.RecordAccessForSubmatrix(c.arg6, kWriteAccess, &attr);
303  if (c.command_type == kBackprop &&
304  nnet.GetComponent(c.arg1)->Properties() & kUpdatableComponent)
305  attr.has_side_effects = true;
306  break;
307  case kMatrixCopy:
308  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
309  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
310  break;
311  case kMatrixAdd:
312  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
313  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
314  break;
315  case kAddRows:
316  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
317  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
318  break;
319  case kCopyRows: {
320  const std::vector<int32> &indexes = computation.indexes[c.arg3];
321  // if there are -1's in "indexes", then the result of the operation
322  // will depend on the initial value of the matrix, so it's
323  // a "rw" operation, not a "write" operation.
324  if (std::count(indexes.begin(), indexes.end(), -1) > 0)
325  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
326  else
327  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
328  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
329  break;
330  }
331  case kAddRowsMulti: {
332  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
333  std::vector<int32> submatrix_indexes;
334  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
335  &submatrix_indexes);
336  for (size_t i = 0; i < submatrix_indexes.size(); i++)
337  vars.RecordAccessForSubmatrix(submatrix_indexes[i],
338  kReadAccess, &attr);
339  break;
340  }
341  case kCopyRowsMulti: {
342  std::vector<int32> submatrix_indexes;
343  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
344  &submatrix_indexes);
345  // note: the CopyRows command assigns zero in cases where
346  // there is no source for some row
347  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
348  for (size_t i = 0; i < submatrix_indexes.size(); i++)
349  vars.RecordAccessForSubmatrix(submatrix_indexes[i],
350  kReadAccess, &attr);
351  break;
352  }
353  case kAddToRowsMulti:
354  case kCopyToRowsMulti: {
355  vars.RecordAccessForSubmatrix(c.arg1, kReadAccess, &attr);
356  // if the submatrixes we're writing to (in kCopyToRowsMulti) had all
357  // rows covered, it would be a pure write operation.
358  std::vector<int32> submatrix_indexes;
359  IndexesMultiToSubmatrixIndexes(computation.indexes_multi[c.arg2],
360  &submatrix_indexes);
361  for (size_t i = 0; i < submatrix_indexes.size(); i++)
362  vars.RecordAccessForSubmatrix(submatrix_indexes[i], kReadWriteAccess,
363  &attr);
364  break;
365  }
366  case kAddRowRanges: {
367  vars.RecordAccessForSubmatrix(c.arg1, kReadWriteAccess, &attr);
368  vars.RecordAccessForSubmatrix(c.arg2, kReadAccess, &attr);
369  break;
370  }
371  case kAcceptInput: {
372  vars.RecordAccessForSubmatrix(c.arg1, kWriteAccess, &attr);
373  break;
374  }
375  case kProvideOutput: {
376  vars.RecordAccessForSubmatrix(c.arg1, kReadAccess, &attr);
377  break;
378  }
379  case kNoOperation:
381  case kNoOperationMarker:
382  case kNoOperationLabel:
383  case kGotoLabel:
384  break;
385  default:
386  KALDI_ERR << "Unknown command type.";
387  }
388  SortAndUniq(&attr.variables_read);
389  SortAndUniq(&attr.variables_written);
390  SortAndUniq(&attr.submatrices_read);
391  SortAndUniq(&attr.submatrices_written);
392  SortAndUniq(&attr.matrices_read);
393  SortAndUniq(&attr.matrices_written);
394  }
395 }
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 261 of file nnet-optimize.cc.

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

Referenced by RemoveUnnecessaryAllocation().

263  {
264  std::vector<int32> d_list = lists.first;
265 
266  std::set<int32> a_set;
267  CopyVectorToSet(lists.second, &a_set);
268 
269  std::vector<int32>::reverse_iterator iter = d_list.rbegin(),
270  end = d_list.rend();
271 
272  // from the latest to the earliest deallocation command...
273  for (; iter != end; ++iter) {
274  int32 d = *iter;
275  std::set<int32>::iterator a_iter = a_set.upper_bound(d);
276  // a_iter is an iterator to the first element a of the set 'a_set' such
277  // that a > d, or a_set.end() if no such element exists.
278  if (a_iter == a_set.end())
279  continue; // we will output no pair for this d.
280  int32 a = *a_iter;
281  KALDI_PARANOID_ASSERT(a > d); // or code error
282  a_set.erase(a_iter); // remove this a from 'a_set' so it doesn't get used
283  // twice
284  pairs->push_back(std::pair<int32,int32>(d, a));
285  }
286 }
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:115
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 (mainly to stop crashes with statistics-pooling/statistics-extraction components), this function always generates computation-requests where at least 3 successive frames of input are requested.

Definition at line 1226 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().

1229  {
1230  KALDI_ASSERT(IsSimpleNnet(nnet));
1231 
1232  int32 left_context, right_context;
1233  ComputeSimpleNnetContext(nnet, &left_context, &right_context);
1234 
1235  int32 num_output_frames = 1 + Rand() % 10,
1236  output_start_frame = Rand() % 10,
1237  num_examples = 1 + Rand() % 10,
1238  output_end_frame = output_start_frame + num_output_frames,
1239  input_start_frame = output_start_frame - left_context - (Rand() % 3),
1240  input_end_frame = output_end_frame + right_context + (Rand() % 3),
1241  n_offset = Rand() % 2;
1242  bool need_deriv = (Rand() % 2 == 0);
1243  // make sure there are at least 3 frames of input available. this makes a
1244  // difference for our tests of statistics-pooling and statistics-extraction
1245  // component.
1246  if (input_end_frame < input_start_frame + 3)
1247  input_end_frame = input_start_frame + 3;
1248 
1249  request->inputs.clear();
1250  request->outputs.clear();
1251  inputs->clear();
1252 
1253  std::vector<Index> input_indexes, ivector_indexes, output_indexes;
1254  for (int32 n = n_offset; n < n_offset + num_examples; n++) {
1255  for (int32 t = input_start_frame; t < input_end_frame; t++)
1256  input_indexes.push_back(Index(n, t, 0));
1257  for (int32 t = output_start_frame; t < output_end_frame; t++)
1258  output_indexes.push_back(Index(n, t, 0));
1259  ivector_indexes.push_back(Index(n, 0, 0));
1260  }
1261  request->outputs.push_back(IoSpecification("output", output_indexes));
1262  if (need_deriv || (Rand() % 3 == 0))
1263  request->outputs.back().has_deriv = true;
1264  request->inputs.push_back(IoSpecification("input", input_indexes));
1265  if (need_deriv && (Rand() % 2 == 0))
1266  request->inputs.back().has_deriv = true;
1267  int32 input_dim = nnet.InputDim("input");
1268  KALDI_ASSERT(input_dim > 0);
1269  inputs->push_back(
1270  Matrix<BaseFloat>((input_end_frame - input_start_frame) * num_examples,
1271  input_dim));
1272  inputs->back().SetRandn();
1273  int32 ivector_dim = nnet.InputDim("ivector"); // may not exist.
1274  if (ivector_dim != -1) {
1275  request->inputs.push_back(IoSpecification("ivector", ivector_indexes));
1276  inputs->push_back(Matrix<BaseFloat>(num_examples, ivector_dim));
1277  inputs->back().SetRandn();
1278  if (need_deriv && (Rand() % 2 == 0))
1279  request->inputs.back().has_deriv = true;
1280  }
1281  if (Rand() % 2 == 0)
1282  request->need_model_derivative = need_deriv;
1283  if (Rand() % 2 == 0)
1284  request->store_component_stats = true;
1285 }
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:140
struct rnnlm::@11::@12 n
int Rand(struct RandomState *state)
Definition: kaldi-math.cc:44
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:49
#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 443 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().

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

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

Referenced by VariableMergingOptimizer::VariableMergingOptimizer().

1034  {
1035  int32 num_matrices = computation.matrices.size(),
1036  num_submatrices = computation.submatrices.size();
1037  mat_to_submat->clear();
1038  mat_to_submat->resize(num_matrices);
1039  for (int32 submatrix_index = 1;
1040  submatrix_index < num_submatrices;
1041  submatrix_index++) {
1042  int32 matrix_index = computation.submatrices[submatrix_index].matrix_index;
1043  KALDI_ASSERT(matrix_index > 0 && matrix_index < num_matrices);
1044  (*mat_to_submat)[matrix_index].push_back(submatrix_index);
1045  }
1046 }
#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 318 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().

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

142  {
143  KALDI_ASSERT(IsSimpleNnet(nnet));
144  int32 modulus = nnet.Modulus();
145  // modulus >= 1 is a number such that the network ought to be
146  // invariant to time shifts (of both the input and output) that
147  // are a multiple of this number. We need to test all shifts modulo
148  // this number in case the left and right context vary at all within
149  // this range.
150 
151  std::vector<int32> left_contexts(modulus + 1);
152  std::vector<int32> right_contexts(modulus + 1);
153 
154  // This will crash if the total context (left + right) is greater
155  // than window_size.
156  int32 window_size = 100;
157  // by going "<= modulus" instead of "< modulus" we do one more computation
158  // than we really need; it becomes a sanity check.
159  for (int32 input_start = 0; input_start <= modulus; input_start++)
160  ComputeSimpleNnetContextForShift(nnet, input_start, window_size,
161  &(left_contexts[input_start]),
162  &(right_contexts[input_start]));
163  KALDI_ASSERT(left_contexts[0] == left_contexts[modulus] &&
164  "nnet does not have the properties we expect.");
165  KALDI_ASSERT(right_contexts[0] == right_contexts[modulus] &&
166  "nnet does not have the properties we expect.");
167  *left_context =
168  *std::max_element(left_contexts.begin(), left_contexts.end());
169  *right_context =
170  *std::max_element(right_contexts.begin(), right_contexts.end());
171 }
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:49
#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:86
static void kaldi::nnet3::ComputeSimpleNnetContextForShift ( const Nnet &  nnet,
int32  input_start,
int32  window_size,
int32 *  left_context,
int32 *  right_context 
)
static

Definition at line 86 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().

91  {
92 
93  int32 input_end = input_start + window_size;
94  IoSpecification input;
95  input.name = "input";
96  IoSpecification output;
97  output.name = "output";
98  IoSpecification ivector; // we might or might not use this.
99  ivector.name = "ivector";
100 
101  int32 n = rand() % 10;
102  // in the IoSpecification for now we we will request all the same indexes at
103  // output that we requested at input.
104  for (int32 t = input_start; t < input_end; t++) {
105  input.indexes.push_back(Index(n, t));
106  output.indexes.push_back(Index(n, t));
107  }
108 
109  // most networks will just require the ivector at time t = 0,
110  // but this might not always be the case, and some might use rounding
111  // descriptors with the iVector which might require it at an earlier
112  // frame than the regular input, so we provide the iVector in as wide a range
113  // as it might possibly be needed.
114  for (int32 t = input_start - nnet.Modulus(); t < input_end; t++) {
115  ivector.indexes.push_back(Index(n, t));
116  }
117 
118 
119  ComputationRequest request;
120  request.inputs.push_back(input);
121  request.outputs.push_back(output);
122  if (nnet.GetNodeIndex("ivector") != -1)
123  request.inputs.push_back(ivector);
124  std::vector<std::vector<bool> > computable;
125  EvaluateComputationRequest(nnet, request, &computable);
126 
127  KALDI_ASSERT(computable.size() == 1);
128  std::vector<bool> &output_ok = computable[0];
129  std::vector<bool>::iterator iter =
130  std::find(output_ok.begin(), output_ok.end(), true);
131  int32 first_ok = iter - output_ok.begin();
132  int32 first_not_ok = std::find(iter, output_ok.end(), false) -
133  output_ok.begin();
134  if (first_ok == window_size || first_not_ok <= first_ok)
135  KALDI_ERR << "No outputs were computable (perhaps not a simple nnet?)";
136  *left_context = first_ok;
137  *right_context = window_size - first_not_ok;
138 }
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:68
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 397 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().

400  {
401  int32 num_variables = variables.NumVariables(),
402  num_commands = command_attributes.size();
403  variable_accesses->clear();
404  variable_accesses->resize(num_variables);
405  for (int32 c = 0; c < num_commands; c++) {
406  const CommandAttributes &attr = command_attributes[c];
407  KALDI_ASSERT(IsSortedAndUniq(attr.variables_read));
408  KALDI_ASSERT(IsSortedAndUniq(attr.variables_written));
409  std::vector<int32> all_variables;
410  all_variables.reserve(attr.variables_read.size() +
411  attr.variables_written.size());
412  all_variables.insert(all_variables.end(), attr.variables_read.begin(),
413  attr.variables_read.end());
414  all_variables.insert(all_variables.end(), attr.variables_written.begin(),
415  attr.variables_written.end());
416  SortAndUniq(&all_variables);
417 
418  std::vector<int32>::const_iterator iter = all_variables.begin(),
419  end = all_variables.end();
420  for (; iter != end; ++iter) {
421  int32 variable_index = *iter;
422  bool is_read = std::binary_search(attr.variables_read.begin(),
423  attr.variables_read.end(),
424  variable_index),
425  is_written = (!is_read ? true :
426  std::binary_search(attr.variables_written.begin(),
427  attr.variables_written.end(),
428  variable_index));
429  if (is_read && is_written) {
430  (*variable_accesses)[variable_index].push_back(
431  Access(c, kReadWriteAccess));
432  } else if (is_read) {
433  (*variable_accesses)[variable_index].push_back(
434  Access(c, kReadAccess));
435  } else {
436  (*variable_accesses)[variable_index].push_back(
437  Access(c, kWriteAccess));
438  }
439  }
440  }
441 }
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 841 of file nnet-optimize.cc.

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

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

842  {
843  // These segments, represented as (start-index, end-index),
844  // are segments of the computation separated by kNoOperationMarker.
845  std::vector<std::pair<int32, int32> > segments;
846  SplitComputationIntoSegments(*computation, &segments);
847 
848  int32 num_commands = computation->commands.size();
849  std::vector<NnetComputation::Command> reordered_commands(num_commands);
850  // put kNoOperationMarker between all segments in the reordered commands.
851  for (size_t s = 0; s + 1 < segments.size(); s++)
852  reordered_commands[segments[s].second].command_type = kNoOperationMarker;
853 
854  // for each segment we'll divide the commands up into those that must appear
855  // at the left of the segment (kAcceptInput for inputs and output-derivs), those
856  // that must appear in the middle (most commands), those that must appear
857  // on the right (kProvideOutput for output nodes and input derivatives).
858  std::vector<int32> left_commands, middle_commands, right_commands;
859 
860  for (size_t s = 0; s < segments.size(); s++) {
861  int32 segment_start = segments[s].first,
862  segment_end = segments[s].second;
863  left_commands.clear();
864  middle_commands.clear();
865  right_commands.clear();
866  for (int32 c = segment_start; c < segment_end; c++) {
867  if (computation->commands[c].command_type == kProvideOutput) {
868  right_commands.push_back(c);
869  } else if (computation->commands[c].command_type == kAcceptInput) {
870  left_commands.push_back(c);
871  } else {
872  middle_commands.push_back(c);
873  }
874  }
875  std::vector<int32>::const_iterator iter = left_commands.begin(),
876  end = left_commands.end();
877  int32 c = segment_start;
878  for (; iter != end; ++iter, ++c)
879  reordered_commands[c] = computation->commands[*iter];
880  iter = middle_commands.begin();
881  end = middle_commands.end();
882  for (; iter != end; ++iter, ++c)
883  reordered_commands[c] = computation->commands[*iter];
884  iter = right_commands.begin();
885  end = right_commands.end();
886  for (; iter != end; ++iter, ++c)
887  reordered_commands[c] = computation->commands[*iter];
888  KALDI_ASSERT(c == segment_end);
889  }
890  computation->commands.swap(reordered_commands);
891 }
#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 1267 of file nnet-optimize-utils.cc.

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

Referenced by Optimize().

1268  {
1269  // This following if-statement is an optimization: if the computation
1270  // request(s) had need_model_derivative == false, there would be nothing to
1271  // optimize, so don't bother trying.
1272  if (!computation->need_model_derivative)
1273  return;
1274  ModelUpdateConsolidator consolidator(nnet, computation);
1275  consolidator.ConsolidateModelUpdate();
1276 }
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 82 of file nnet3-copy-egs.cc.

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

Referenced by SelectFromExample().

86  {
87  bool done_input = false, done_output = false;
88  int32 num_indexes = eg.io.size();
89  for (int32 i = 0; i < num_indexes; i++) {
90  const NnetIo &io = eg.io[i];
91  std::vector<Index>::const_iterator iter = io.indexes.begin(),
92  end = io.indexes.end();
93  // Should not have an empty input/output type.
94  KALDI_ASSERT(!io.indexes.empty());
95  if (io.name == "input" || io.name == "output") {
96  int32 min_t = iter->t, max_t = iter->t;
97  for (; iter != end; ++iter) {
98  int32 this_t = iter->t;
99  min_t = std::min(min_t, this_t);
100  max_t = std::max(max_t, this_t);
101  if (iter->n != 0) {
102  KALDI_WARN << "Example does not contain just a single example; "
103  << "too late to do frame selection or reduce context.";
104  return false;
105  }
106  }
107  if (io.name == "input") {
108  done_input = true;
109  *min_input_t = min_t;
110  *max_input_t = max_t;
111  } else {
112  KALDI_ASSERT(io.name == "output");
113  done_output = true;
114  *min_output_t = min_t;
115  *max_output_t = max_t;
116  }
117  } else {
118  for (; iter != end; ++iter) {
119  if (iter->n != 0) {
120  KALDI_WARN << "Example does not contain just a single example; "
121  << "too late to do frame selection or reduce context.";
122  return false;
123  }
124  }
125  }
126  }
127  if (!done_input) {
128  KALDI_WARN << "Example does not have any input named 'input'";
129  return false;
130  }
131  if (!done_output) {
132  KALDI_WARN << "Example does not have any output named 'output'";
133  return false;
134  }
135  return true;
136 }
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:110
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 372 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().

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

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

References KALDI_ASSERT, Index::n, and rnnlm::n.

Referenced by ComputationExpander::ExpandIndexes(), and IoSpecificationIsDecomposable().

2514  {
2515  int32 size_in = indexes_in.size();
2516  KALDI_ASSERT(size_in > 0 && indexes_in[size_in - 1].n == old_N - 1);
2517  int32 block_size_in = n_stride * old_N,
2518  block_size_out = n_stride * new_N;
2519 
2520  indexes_out->resize((size_in / old_N) * new_N);
2521  for (int32 i_in = 0; i_in < size_in; i_in++) {
2522  if (indexes_in[i_in].n != 0)
2523  continue;
2524  Index index(indexes_in[i_in]);
2525  int32 block_index = i_in / block_size_in,
2526  offset_within_block = i_in % block_size_in;
2527 
2528 
2529  int32 i_out = block_index * block_size_out +
2530  offset_within_block;
2531  for (int32 n = 0; n < new_N; n++, i_out += n_stride) {
2532  index.n = n;
2533  (*indexes_out)[i_out] = index;
2534  }
2535  }
2536 }
struct rnnlm::@11::@12 n
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::ConvertRepeatedToBlockAffine ( CompositeComponent *  c_component)

Definition at line 397 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().

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

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

418  {
419  for(int32 i = 0; i < nnet->NumComponents(); i++) {
420  const Component *const_c = nnet->GetComponent(i);
421  if(const_c->Type() == "RepeatedAffineComponent" ||
422  const_c->Type() == "NaturalGradientRepeatedAffineComponent") {
423  // N.B.: NaturalGradientRepeatedAffineComponent is a subclass of
424  // RepeatedAffineComponent.
425  const RepeatedAffineComponent *rac =
426  dynamic_cast<const RepeatedAffineComponent*>(const_c);
427  KALDI_ASSERT(rac != NULL);
428  BlockAffineComponent *bac = new BlockAffineComponent(*rac);
429  // following call deletes rac
430  nnet->SetComponent(i, bac);
431  } else if (const_c->Type() == "CompositeComponent") {
432  // We must modify the composite component, so we use the
433  // non-const GetComponent() call here.
434  Component *c = nnet->GetComponent(i);
435  CompositeComponent *cc = dynamic_cast<CompositeComponent*>(c);
436  KALDI_ASSERT(cc != NULL);
438  }
439  }
440 }
void ConvertRepeatedToBlockAffine(Nnet *nnet)
Convert all components of type RepeatedAffineComponent or NaturalGradientRepeatedAffineComponent to B...
Definition: nnet-utils.cc:418
#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:140
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:118
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 224 of file nnet-utils.cc.

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

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

225  {
226  KALDI_ASSERT(nnet1.NumComponents() == nnet2.NumComponents());
227  BaseFloat ans = 0.0;
228  for (int32 c = 0; c < nnet1.NumComponents(); c++) {
229  const Component *comp1 = nnet1.GetComponent(c),
230  *comp2 = nnet2.GetComponent(c);
231  if (comp1->Properties() & kUpdatableComponent) {
232  const UpdatableComponent
233  *u_comp1 = dynamic_cast<const UpdatableComponent*>(comp1),
234  *u_comp2 = dynamic_cast<const UpdatableComponent*>(comp2);
235  KALDI_ASSERT(u_comp1 != NULL && u_comp2 != NULL);
236  ans += u_comp1->DotProduct(*u_comp2);
237  }
238  }
239  return ans;
240 }
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 68 of file nnet-utils.cc.

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

Referenced by ComputeSimpleNnetContextForShift().

71  {
72  ComputationGraph graph;
73  ComputationGraphBuilder builder(nnet, &graph);
74  builder.Compute(request);
75  builder.GetComputableInfo(is_computable);
76  if (GetVerboseLevel() >= 4) {
77  std::ostringstream graph_pretty;
78  graph.Print(graph_pretty, nnet.GetNodeNames());
79  KALDI_VLOG(4) << "Graph is " << graph_pretty.str();
80  }
81 }
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 1718 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().

1720  {
1721  if (eg1.io.size() != eg2.io.size())
1722  return false;
1723  for (size_t i = 0; i < eg1.io.size(); i++) {
1724  NnetIo io1 = eg1.io[i], io2 = eg2.io[i];
1725  if (io1.name != io2.name || io1.indexes != io2.indexes)
1726  return false;
1727  Matrix<BaseFloat> feat1, feat2;
1728  io1.features.GetMatrix(&feat1);
1729  io2.features.GetMatrix(&feat2);
1730  if (!ApproxEqual(feat1, feat2, delta))
1731  return false;
1732  }
1733  return true;
1734 }
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 3208 of file nnet-optimize-utils.cc.

References ComputationExpander::Expand().

Referenced by CachingOptimizingCompiler::CompileViaShortcut().

3213  {
3214  ComputationExpander expander(nnet, misc_info, computation,
3215  need_debug_info, num_n_values,
3216  expanded_computation);
3217  expander.Expand();
3218 }
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(), ConvolutionModel::Read(), TimeHeightConvolutionComponent::PrecomputedIndexes::Read(), StatisticsExtractionComponentPrecomputedIndexes::Read(), ConvolutionComputation::Read(), StatisticsPoolingComponent::Read(), StatisticsPoolingComponentPrecomputedIndexes::Read(), BackpropTruncationComponent::Read(), NonlinearComponent::Read(), BackpropTruncationComponentPrecomputedIndexes::Read(), DropoutMaskComponent::Read(), FixedAffineComponent::Read(), SumGroupComponent::Read(), FixedScaleComponent::Read(), FixedBiasComponent::Read(), SumBlockComponent::Read(), ClipGradientComponent::Read(), PermuteComponent::Read(), MaxpoolingComponent::Read(), and BatchNormComponent::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(), PnormComponent::Read(), Index::Read(), NnetIo::Read(), DistributeComponent::Read(), NnetDiscriminativeSupervision::Read(), IoSpecification::Read(), NnetChainSupervision::Read(), NnetExample::Read(), DropoutComponent::Read(), NnetDiscriminativeExample::Read(), NnetChainExample::Read(), NnetOptimizeOptions::Read(), DistributeComponentPrecomputedIndexes::Read(), ComputationRequest::Read(), ElementwiseProductComponent::Read(), Nnet::Read(), NormalizeComponent::Read(), StatisticsExtractionComponent::Read(), ConvolutionModel::Read(), TimeHeightConvolutionComponent::Read(), NnetComputation::MatrixInfo::Read(), NnetComputation::MatrixDebugInfo::Read(), TimeHeightConvolutionComponent::PrecomputedIndexes::Read(), NnetComputation::SubMatrixInfo::Read(), StatisticsExtractionComponentPrecomputedIndexes::Read(), NnetComputation::Command::Read(), ConvolutionComputation::Read(), StatisticsPoolingComponent::Read(), NnetComputation::Read(), StatisticsPoolingComponentPrecomputedIndexes::Read(), AffineComponent::Read(), BackpropTruncationComponent::Read(), NonlinearComponent::Read(), BlockAffineComponent::Read(), BackpropTruncationComponentPrecomputedIndexes::Read(), ConstantComponent::Read(), RepeatedAffineComponent::Read(), DropoutMaskComponent::Read(), NaturalGradientAffineComponent::Read(), FixedAffineComponent::Read(), FixedScaleComponent::Read(), FixedBiasComponent::Read(), SumBlockComponent::Read(), ClipGradientComponent::Read(), PermuteComponent::Read(), PerElementScaleComponent::Read(), PerElementOffsetComponent::Read(), ConstantFunctionComponent::Read(), NaturalGradientPerElementScaleComponent::Read(), ConvolutionComponent::Read(), LstmNonlinearityComponent::Read(), MaxpoolingComponent::Read(), BatchNormComponent::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 145 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().

150  {
151  eg_out->io.clear();
152  eg_out->io.resize(eg.io.size());
153  for (size_t i = 0; i < eg.io.size(); i++) {
154  bool is_input_or_output;
155  int32 min_t, max_t;
156  const NnetIo &io_in = eg.io[i];
157  NnetIo &io_out = eg_out->io[i];
158  const std::string &name = io_in.name;
159  io_out.name = name;
160  if (name == "input") {
161  min_t = min_input_t;
162  max_t = max_input_t;
163  is_input_or_output = true;
164  } else if (name == "output") {
165  min_t = min_output_t;
166  max_t = max_output_t;
167  is_input_or_output = true;
168  } else {
169  is_input_or_output = false;
170  }
171  if (!is_input_or_output) { // Just copy everything.
172  io_out.indexes = io_in.indexes;
173  io_out.features = io_in.features;
174  } else {
175  const std::vector<Index> &indexes_in = io_in.indexes;
176  std::vector<Index> &indexes_out = io_out.indexes;
177  indexes_out.reserve(indexes_in.size());
178  int32 num_indexes = indexes_in.size(), num_kept = 0;
179  KALDI_ASSERT(io_in.features.NumRows() == num_indexes);
180  std::vector<bool> keep(num_indexes, false);
181  std::vector<Index>::const_iterator iter_in = indexes_in.begin(),
182  end_in = indexes_in.end();
183  std::vector<bool>::iterator iter_out = keep.begin();
184  for (; iter_in != end_in; ++iter_in,++iter_out) {
185  int32 t = iter_in->t;
186  bool is_within_range = (t >= min_t && t <= max_t);
187  *iter_out = is_within_range;
188  if (is_within_range) {
189  indexes_out.push_back(*iter_in);
190  num_kept++;
191  }
192  }
193  KALDI_ASSERT(iter_out == keep.end());
194  if (num_kept == 0)
195  KALDI_ERR << "FilterExample removed all indexes for '" << name << "'";
196 
197  FilterGeneralMatrixRows(io_in.features, keep,
198  &io_out.features);
199  KALDI_ASSERT(io_out.features.NumRows() == num_kept &&
200  indexes_out.size() == static_cast<size_t>(num_kept));
201  }
202  }
203 }
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:110
static int32 kaldi::nnet3::FindNStride ( const std::vector< Index > &  indexes,
bool  full_check 
)
static

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

References rnnlm::i, rnnlm::j, KALDI_ASSERT, Index::n, rnnlm::n, kaldi::RandInt(), and kaldi::SortAndUniq().

Referenced by ComputationExpander::ExpandIndexes(), ComputationExpander::InitStrideInfo(), and IoSpecificationIsDecomposable().

2349  {
2350  // First find candidate stride. Later we'll check for consistency.
2351  int32 size = indexes.size();
2352  KALDI_ASSERT(size > 0);
2353  int32 N = indexes[size-1].n + 1,
2354  n_stride;
2355  if (N <= 1) {
2356  // we wouldn't be able to determine the stride if N <= 1.
2357  return 0;
2358  }
2359  Index index(indexes[0]);
2360  if (index.n != 0 || size % N != 0) {
2361  // for the n stride to be positive, we must start with an index with n == 0.
2362  // if indexes.size() is not divisible by N, we have no hope of finding the
2363  // regular structure.
2364  return 0;
2365  }
2366  index.n = 1;
2367  // First check the two most common strides, which are 1
2368  // and size / N.
2369  if (indexes[1] == index) {
2370  n_stride = 1;
2371  } else if (indexes[size / N] == index) {
2372  n_stride = size / N;
2373  } else {
2374  int32 stride;
2375  // try the other possible strides one by one (for subsampling
2376  // layers of convnets, we might see strides of 2, for instance).
2377  for (stride = 2; stride < size / N; stride++) {
2378  if (size % stride == 0 && indexes[stride] == index) {
2379  n_stride = stride;
2380  break;
2381  }
2382  }
2383  if (stride == size / N) {
2384  // if we fell off the loop then we found no candidates, which is strange
2385  // and means we did not find the expected structure; we'll return 0 as we
2386  // failed.
2387  return 0;
2388  }
2389  }
2390  // Now is the checking phase.
2391 
2392  // to understand block_size, see the comment above this functcion.
2393  int32 block_size = n_stride * N;
2394 
2395  std::vector<int32> indexes_to_check;
2396  if (full_check) {
2397  indexes_to_check.resize(size);
2398  for (int32 i = 0; i < size; i++)
2399  indexes_to_check[i] = i;
2400  } else {
2401  int32 num_to_check = std::min<int32>(5, size);
2402  indexes_to_check.resize(num_to_check);
2403  for (int32 j = 0; j < num_to_check; j++)
2404  indexes_to_check[j] = RandInt(0, size - 1);
2405  SortAndUniq(&indexes_to_check);
2406  }
2407  for (std::vector<int32>::iterator iter = indexes_to_check.begin();
2408  iter != indexes_to_check.end(); ++iter) {
2409  int32 i = *iter;
2410  Index index = indexes[i];
2411  int32 n = index.n;
2412  if (n < N - 1) {
2413  index.n = n + 1;
2414  if (i + n_stride >= size || indexes[i + n_stride] != index)
2415  return 0;
2416  }
2417  if (n == 0) {
2418  if (i / block_size != (i + n_stride * (N-1)) / block_size) {
2419  // this is a check that the input divides into blocks of size n_stride *
2420  // N and the N different versions of the same Index are always within a
2421  // block (i.e. that the n stride never crosses over the block; having
2422  // the same Index repeated within different blocks actually would not
2423  // matter).
2424  return 0;
2425  }
2426  } else { // n > 0
2427  index.n = n - 1;
2428  if (i - n_stride < 0 || indexes[i - n_stride] != index)
2429  return 0;
2430  }
2431  }
2432  return n_stride;
2433 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:39
struct rnnlm::@11::@12 n
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:94
static int32 kaldi::nnet3::FindNStride ( const std::vector< Cindex > &  cindexes,
bool  full_check 
)
static

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

References rnnlm::i, rnnlm::j, KALDI_ASSERT, rnnlm::n, kaldi::RandInt(), and kaldi::SortAndUniq().

2440  {
2441  int32 size = cindexes.size();
2442  KALDI_ASSERT(size > 0);
2443  int32 N = cindexes[size-1].second.n + 1,
2444  n_stride;
2445  if (N <= 1)
2446  return 0;
2447  Cindex cindex(cindexes[0]);
2448  if (cindex.second.n != 0 || size % N != 0)
2449  return 0;
2450  cindex.second.n = 1;
2451  if (cindexes[1] == cindex) {
2452  n_stride = 1;
2453  } else if (cindexes[size / N] == cindex) {
2454  n_stride = size / N;
2455  } else {
2456  int32 stride;
2457  for (stride = 2; stride < size / N; stride++) {
2458  if (size % stride == 0 && cindexes[stride] == cindex) {
2459  n_stride = stride;
2460  break;
2461  }
2462  }
2463  if (stride == size / N)
2464  return 0;
2465  }
2466  int32 block_size = n_stride * N;
2467  std::vector<int32> indexes_to_check;
2468  if (full_check) {
2469  indexes_to_check.resize(size);
2470  for (int32 i = 0; i < size; i++)
2471  indexes_to_check[i] = i;
2472  } else {
2473  int32 num_to_check = std::min<int32>(5, size);
2474  indexes_to_check.resize(num_to_check);
2475  for (int32 j = 0; j < num_to_check; j++)
2476  indexes_to_check[j] = RandInt(0, size - 1);
2477  SortAndUniq(&indexes_to_check);
2478  }
2479  for (std::vector<int32>::iterator iter = indexes_to_check.begin();
2480  iter != indexes_to_check.end(); ++iter) {
2481  int32 i = *iter;
2482  Cindex cindex = cindexes[i];
2483  int32 n = cindex.second.n;
2484  if (n < N - 1) {
2485  cindex.second.n = n + 1;
2486  if (i + n_stride >= size || cindexes[i + n_stride] != cindex)
2487  return 0;
2488  }
2489  if (n == 0) {
2490  if (i / block_size != (i + n_stride * (N-1)) / block_size)
2491  return 0;
2492  } else {
2493  cindex.second.n = n - 1;
2494  if (i - n_stride < 0 || cindexes[i - n_stride] != cindex)
2495  return 0;
2496  }
2497  }
2498  return n_stride;
2499 }
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector.
Definition: stl-utils.h:39
std::pair< int32, Index > Cindex
Definition: nnet-common.h:115
struct rnnlm::@11::@12 n
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 RandInt(int32 min_val, int32 max_val, struct RandomState *state)
Definition: kaldi-math.cc:94
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 2205 of file nnet-optimize-utils.cc.

References KALDI_ASSERT.

Referenced by SnipRangesRowOp().

2208  {
2209  KALDI_ASSERT(!vec.empty());
2210  const std::pair<int32, int32> *begin = &(vec[0]), *ptr = begin,
2211  *end = ptr + vec.size();
2212  while (ptr != end && ptr->first == ptr->second)
2213  ptr++;
2214  // note regarding error message: we assume all pairs of identical numbers are
2215  // -1, due to the way this is called, but it only affects how we describe the
2216  // error.
2217  KALDI_ASSERT(ptr != end && "Vector consists entirely of -1's.");
2218  *num_leading_identicals = ptr - begin;
2219  const std::pair<int32, int32> *ptr2 = end - 1;
2220  // the following while loop should terminate before falling off the vector,
2221  // because we've established above (in the assertion) that the vector contains
2222  // at least one nonnegative number.
2223  while (ptr2->first == ptr2->second)
2224  ptr2--;
2225  KALDI_ASSERT(ptr2 >= begin); // would be code error.
2226  *num_trailing_identicals = end - 1 - ptr2;
2227 }
#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 2067 of file nnet-optimize-utils.cc.

References KALDI_ASSERT.

Referenced by SnipMultiRowOp(), and SnipSingleRowOp().

2069  {
2070  KALDI_ASSERT(!vec.empty());
2071  const int32 *begin = &(vec[0]), *ptr = begin, *end = ptr + vec.size();
2072  while (ptr != end && *ptr < 0)
2073  ptr++;
2074  // note regarding error message: we assume all negative numbers are -1, due to
2075  // the way this is called, but it only affects how we describe the error.
2076  KALDI_ASSERT(ptr != end && "Vector consists entirely of -1's.");
2077  *num_leading_negatives = ptr - begin;
2078  const int32 *ptr2 = end - 1;
2079  // the following while loop should terminate before falling off the vector,
2080  // because we've established above (in the assertion) that the vector contains
2081  // at least one nonnegative number.
2082  while (*ptr2 < 0)
2083  ptr2--;
2084  KALDI_ASSERT(ptr2 >= begin); // or would be code error.
2085  *num_trailing_negatives = end - 1 - ptr2;
2086 }
#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 2134 of file nnet-optimize-utils.cc.

References KALDI_ASSERT.

2137  {
2138  KALDI_ASSERT(!vec.empty());
2139  const std::pair<int32, int32> *begin = &(vec[0]), *ptr = begin,
2140  *end = ptr + vec.size();
2141  while (ptr != end && ptr->first < 0)
2142  ptr++;
2143  // note regarding error message: we assume all negative numbers are -1, due to
2144  // the way this is called, but it only affects how we describe the error.
2145  KALDI_ASSERT(ptr != end && "Vector consists entirely of -1's.");
2146  *num_leading_negatives = ptr - begin;
2147  const std::pair<int32, int32> *ptr2 = end - 1;
2148  // the following while loop should terminate before falling off the vector,
2149  // because we've established above (in the assertion) that the vector contains
2150  // at least one nonnegative number.
2151  while (ptr2->first < 0)
2152  ptr2--;
2153  KALDI_ASSERT(ptr2 >= begin); // would be code error.
2154  *num_trailing_negatives = end - 1 - ptr2;
2155 }
#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 516 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().

516  {
517  int32 num_components = nnet.NumComponents(), num_nodes = nnet.NumNodes();
518  std::vector<bool> is_used(num_components, false);
519  for (int32 i = 0; i < num_nodes; i++) {
520  if (nnet.IsComponentNode(i)) {
521  int32 c = nnet.GetNode(i).u.component_index;
522  KALDI_ASSERT(c >= 0 && c < num_components);
523  is_used[c] = true;
524  }
525  }
526  components->clear();
527  for (int32 i = 0; i < num_components; i++)
528  if (!is_used[i])
529  components->push_back(i);
530 }
#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 532 of file nnet-utils.cc.

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

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

532  {
533 
534  std::vector<std::vector<int32> > depend_on_graph, dependency_graph;
535  NnetToDirectedGraph(nnet, &depend_on_graph);
536  // depend_on_graph[i] is a list of all the nodes that depend on i.
537  ComputeGraphTranspose(depend_on_graph, &dependency_graph);
538  // dependency_graph[i] is a list of all the nodes that i depends on,
539  // to be computed.
540 
541  // Find all nodes required to produce the outputs.
542  int32 num_nodes = nnet.NumNodes();
543  assert(num_nodes == static_cast<int32>(dependency_graph.size()));
544  std::vector<bool> node_is_required(num_nodes, false);
545  std::vector<int32> queue;
546  for (int32 i = 0; i < num_nodes; i++) {
547  if (nnet.IsOutputNode(i))
548  queue.push_back(i);
549  }
550  while (!queue.empty()) {
551  int32 i = queue.back();
552  queue.pop_back();
553  if (!node_is_required[i]) {
554  node_is_required[i] = true;
555  for (size_t j = 0; j < dependency_graph[i].size(); j++)
556  queue.push_back(dependency_graph[i][j]);
557  }
558  }
559  nodes->clear();
560  for (int32 i = 0; i < num_nodes; i++) {
561  if (!node_is_required[i])
562  nodes->push_back(i);
563  }
564 }
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];