kaldi :: nnet2命名空间参考

text-utils.h File Reference

#include <errno.h>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <limits>
#include "base/kaldi-common.h"

Include dependency graph for text-utils.h:

 

This graph shows which files directly or indirectly include this file:

命名空间

 kaldi
 使用读取的pdf-id对齐重新分析神经网络egs。 
 

功能

void 	SplitStringToVector (const std::string &full, const char *delim, bool omit_empty_strings, std::vector< std::string > *out)
、、使用任何单个字符分隔符拆分字符串。 更多...
void 	JoinVectorToString (const std::vector< std::string > &vec_in, const char *delim, bool omit_empty_strings, std::string *str_out)
 	Joins the elements of a vector of strings into a single string using "delim" as the delimiter. More...
 
template<class I >
bool 	SplitStringToIntegers (const std::string &full, const char *delim, bool omit_empty_strings, std::vector< I > *out)
 	Split a string (e.g. More...
 
template<class F >
bool 	SplitStringToFloats (const std::string &full, const char *delim, bool omit_empty_strings, std::vector< F > *out)
 
template<class Int >
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.e. More...
 
template<typename T >
bool 	ConvertStringToReal (const std::string &str, T *out)
 	ConvertStringToReal converts a string into either float or double and returns false if there was any kind of problem (i.e. More...
 
void 	Trim (std::string *str)
 	Removes the beginning and trailing whitespaces from a string. More...
 
void 	SplitStringOnFirstSpace (const std::string &line, std::string *first, std::string *rest)
 	Removes leading and trailing white space from the string, then splits on the first section of whitespace found (if present), putting the part before the whitespace in "first" and the rest in "rest". More...
 
bool 	IsToken (const std::string &token)
 	Returns true if "token" is nonempty, and all characters are printable and whitespace-free. More...
 
bool 	IsLine (const std::string &line)
 	Returns true if "line" is free of 
characters and unprintable characters, and does not contain leading or trailing whitespace. More...
 
bool 	StringsApproxEqual (const std::string &a, const std::string &b, int32 decimal_places_check=2)
 	This function returns true when two text strings are approximately equal, and false when they are not. More...

 

kaldi :: nnet2命名空间参考
类
类  	AdditiveNoiseComponent
 	这有点类似于丢失但是在给定的标准偏差下添加(不是乘以)高斯噪声。 更多...
 
类  	AffineComponent
 
类  	AffineComponentPreconditioned
 
类  	AffineComponentPreconditionedOnline
 	关键词:自然梯度下降,NG-SGD,自然梯度。 更多...
 
类  	AmNnet
 
类  	BlockAffineComponent
 
类  	BlockAffineComponentPreconditioned
 
类  	ChunkInfo
 	ChunkInfo是一个类,其目的是描述保持特征的矩阵的结构。 更多...
 
类  	零件
 	抽象类,网络的基本元素,它是一个具有定义的输入,输出和转换函数接口的框。 更多...
 
类  	Convolutional1dComponent
 	Convolutional1dComponent在频率轴上实现卷积。 更多...
 
类  	DctComponent
 	离散余弦变换。 更多...
 
类  	DecodableAmNnet
 	DecodableAmNnet是一个可解码的对象,使用AmNnet类型的神经网络声学模型进行解码。 更多...
 
类  	DecodableAmNnetParallel
 	此版本的DecodableAmNnet适用于处理具有多个线程的不同话语的解码器版本。 更多...
 
类  	DecodableNnet2Online
 	类nnet2 :: AmNnet的这个Decodable对象接受来自类MobileFeatureInterface的特征输入,不像是类DecodableAmNnet,它从矩阵中获取特征输入。 更多...
 
结构  	DecodableNnet2OnlineOptions
 
类  	DiscriminativeExampleSplitter
 	对于每一帧,判断: 更多......
 
类  	DiscriminativeExamplesRepository
 	该结构存储用于多线程训练的神经网络训练示例。 更多...
 
结构  	DiscriminativeNnetExample
 	该结构用于存储判别性训练(MMI或MPE)所需的信息。 更多...
 
类  	DiscTrainParallelClass
 
类  	DoBackpropParallelClass
 
类  	DropoutComponent
 	该组件(如果存在)随机将输入的一半归零,并将另一半乘以2。 更多...
 
类  	ExamplesRepository
 	该类存储用于多线程训练的神经网络训练示例。 更多...
 
类  	FastNnetCombiner
 
类  	FisherComputationClass
 
类  	FixedAffineComponent
 	FixedAffineComponent是一个仿射变换,在网络初始化时提供,不可训练。 更多...
 
类  	FixedBiasComponent
 	FixedBiasComponent应用固定的每元素偏差; 它类似于nnet1设置中的AddShift组件(仅用于nnet1模型转换。 更多...
 
类  	FixedLinearComponent
 	FixedLinearComponent是一个线性变换,在网络初始化时提供,不可训练。 更多...
 
类  	FixedScaleComponent
 	FixedScaleComponent应用固定的每元素比例; 它类似于nnet1设置中的Rescale组件(仅用于nnet1模型转换)。 更多...
 
类  	LimitRankClass
 
类  	LogSoftmaxComponent
 
类  	MaxoutComponent
 
类  	MaxpoolingComponent
 	MaxPoolingComponent:Maxpooling组件首先在ConvNet中用于选择区域中的代表性激活。 更多...
 
类  	NNET
 
结构  	NnetCombineAconfig
 
结构  	NnetCombineConfig
 	控制神经网络组合的配置类,其中我们组合了许多神经网络,试图为每个层找到不同神经网络参数的最佳加权组合。 更多...
 
结构  	NnetCombineFastConfig
 	控制神经网络组合的配置类,其中我们组合了许多神经网络,试图为每个层找到不同神经网络参数的最佳加权组合。 更多...
 
类  	NnetComputer
 
结构  	NnetDiscriminativeStats
 
结构  	NnetDiscriminativeUpdateOptions
 
类  	NnetDiscriminativeUpdater
 
类  	NnetEnsembleTrainer
 
结构  	NnetEnsembleTrainerConfig
 
结构  	NnetExample
 	NnetExample是输入数据和一个或多个输入帧的相应标签(或多个标签),用于神经网络的标准交叉熵训练(可能还用于其他目标函数)。 更多...
 
类  	NnetExampleBackgroundReader
 
结构  	NnetFixConfig
 
结构  	NnetLimitRankOpts
 
结构  	NnetMixupConfig
 
类  	NnetOnlineComputer
 
结构  	NnetRescaleConfig
 
类  	NnetRescaler
 
结构  	NnetShrinkConfig
 	控制神经网络“收缩”的配置类,实际上是对每个可更新层的参数进行缩放。 更多...
 
结构  	NnetSimpleTrainerConfig
 
类  	NnetStats
 
结构  	NnetStatsConfig
 
类  	NnetUpdater
 
结构  	NnetWidenConfig
 	控制神经网络“扩展”的配置类,这意味着增加已经训练的神经网络的隐藏层的维度。 更多...
 
类  	NonlinearComponent
 	这种组件是sigmoid和softmax之类的基类。 更多...
 
类  	NormalizeComponent
 
类  	OnlinePreconditioner
 	搜索关键词:自然梯度,自然梯度,NG-SGD。 更多...
 
类  	OnlinePreconditionerSimple
 
类  	PermuteComponent
 	PermuteComponent执行维度的排列(默认情况下,固定随机排列,但可以指定)。 更多...
 
类  	PnormComponent
 
类  	PowerComponent
 	将输入向量的绝对值取为幂。 更多...
 
类  	RandomComponent
 
类  	RectifiedLinearComponent
 
类  	ScaleComponent
 
类  	SigmoidComponent
 
类  	SoftHingeComponent
 
类  	SoftmaxComponent
 
类  	SpliceComponent
 	随着时间的推移拼接帧的上下文窗口。 更多...
 
类  	SpliceMaxComponent
 	这与SpliceComponent一样,但输出任何输入的最大值(在时间上取最大值)。 更多...
 
结构  	SplitDiscriminativeExampleConfig
 	SplitExample的配置结构,用于拆分判别训练示例。 更多...
 
结构  	SplitExampleStats
 	此结构仅用于诊断目的。 更多...
 
类  	SumGroupComponent
 
类  	TanhComponent
 
类  	UpdatableComponent
 	类UpdatableComponent是一个具有可训练参数的组件,包含一些随机梯度下降的全局参数(学习速率,L2正则化常数)。 更多...
 
类型定义
typedef TableWriter < KaldiObjectHolder < NnetExample >> 	NnetExampleWriter
 
typedef SequentialTableReader < KaldiObjectHolder < NnetExample >> 	SequentialNnetExampleReader
 
typedef RandomAccessTableReader < KaldiObjectHolder < NnetExample >> 	RandomAccessNnetExampleReader
 
typedef TableWriter < KaldiObjectHolder < DiscriminativeNnetExample >> 	DiscriminativeNnetExampleWriter
 
typedef SequentialTableReader < KaldiObjectHolder < DiscriminativeNnetExample >> 	SequentialDiscriminativeNnetExampleReader
 
typedef RandomAccessTableReader < KaldiObjectHolder < DiscriminativeNnetExample >> 	RandomAccessDiscriminativeNnetExampleReader
 
功能

 


功能
空虚 	UnitTestAmNnet()
 
静态无效 	GetUpdateDirection(const std :: vector < Nnet >&nnets,Nnet * direction)
 
静态无效 	AddDirection(const Nnet&orig_nnet,const Nnet&direction,const VectorBase < BaseFloat >&scales,Nnet * dest)
 	将“dest”设置为orig_nnet加“方向”,每个可更新的“方向”组件首先按适当的比例缩放。 更多...
 
静态BaseFloat 	ComputeObjfAndGradient(const std :: vector < NnetExample >&validation_set,const Vector <double>&scale_params,const Nnet&orig_nnet,const Nnet&direction,Vector <double> * gradient)
 
空虚 	CombineNnetsA(const NnetCombineAconfig&config,const std :: vector < NnetExample >&validation_set,const std :: vector < Nnet >&nnets,Nnet * nnet_out)
 
空虚 	CombineNnetsFast(const NnetCombineFastConfig&combine_config,const std :: vector < NnetExample >&validation_set,const std :: vector < Nnet >&nnets_in,Nnet * nnet_out)
 
静态无效 	CombineNnets(const Vector < BaseFloat >&scale_params,const std :: vector < Nnet >&nnets,Nnet * dest)
 
static int32 	GetInitialModel(const std :: vector < NnetExample >&validation_set,const std :: vector < Nnet >&nnets)
 	返回一个整数,说明要使用的模型:0 ... 更多...
 
静态无效 	GetInitialScaleParams(const NnetCombineConfig&combine_config,const std :: vector < NnetExample >&validation_set,const std :: vector < Nnet >&nnets,Vector <double> * scale_params)
 
静态双 	ComputeObjfAndGradient(const std :: vector < NnetExample >&validation_set,const Vector <double>&scale_params,const std :: vector < Nnet >&nnets,bool debug,Vector <double> * gradient)
 
空虚 	CombineNnets(const NnetCombineConfig&combine_config,const std :: vector < NnetExample >&validation_set,const std :: vector < Nnet >&nnets,Nnet * nnet_out)
 
静态无效 	GiveNnetCorrectTopology(Nnet * nnet,AffineComponent ** affine_component,SoftmaxComponent ** softmax_component,SumGroupComponent ** sum_group_component)
 	此函数确保神经网络以SumGroupComponent结束。 更多...
 
空虚 	MixupNnet(const NnetMixupConfig&mixup_config,Nnet * nnet)
 	此功能的工作原理如下。 更多...
 
空虚 	UnitTestGenericComponentInternal(const 组件和组件,const ChunkInfo in_info,const ChunkInfo out_info)
 
空虚 	UnitTestGenericComponentInternal(const 组件和组件)
 
空虚 	UnitTestSigmoidComponent()
 
模板<class T>
空虚 	UnitTestGenericComponent(std :: string extra_str =“”)
 
空虚 	UnitTestMaxoutComponent()
 
空虚 	UnitTestPnormComponent()
 
空虚 	UnitTestMaxpoolingComponent()
 
空虚 	UnitTestAffineComponent()
 
空虚 	UnitTestConvolutional1dComponent()
 
空虚 	UnitTestDropoutComponent()
 
空虚 	UnitTestAdditiveNoiseComponent()
 
空虚 	UnitTestScaleComponent()
 
空虚 	UnitTestAffineComponentPreconditioned()
 
空虚 	UnitTestAffineComponentPreconditionedOnline()
 
空虚 	UnitTestBlockAffineComponent()
 
空虚 	UnitTestBlockAffineComponentPreconditioned()
 
空虚 	UnitTestSumGroupComponent()
 
空虚 	UnitTestDctComponent()
 
空虚 	UnitTestFixedLinearComponent()
 
空虚 	UnitTestFixedAffineComponent()
 
空虚 	UnitTestFixedScaleComponent()
 
空虚 	UnitTestFixedBiasComponent()
 
空虚 	UnitTestParsing()
 
空虚 	UnitTestSpliceComponent()
 
空虚 	BasicDebugTestForSpliceMax(bool output = false)
 
静态无效 	ExpectOneOrTwoTokens(std :: istream&is,bool binary,const std :: string&token1,const std :: string&token2)
 
布尔 	ParseFromString(const std :: string&name,std :: string * string,int32 * param)
 	Init例程中使用的函数。 更多...
 
布尔 	ParseFromString(const std :: string&name,std :: string * string,bool * param)
 	此版本适用于bool类型的参数,它可以显示为以f,F,t或T开头的任何字符串。 更多...
 
布尔 	ParseFromString(const std :: string&name,std :: string * string,BaseFloat * param)
 	此版本适用于BaseFloat类型的参数。 更多...
 
布尔 	ParseFromString(const std :: string&name,std :: string * string,std :: string * param)
 
布尔 	ParseFromString(const std :: string&name,std :: string * string,std :: vector <int32> * param)
 	此版本适用于std :: vector <int32>类型的参数; 它希望它们是一个以冒号分隔的列表,没有空格。 更多...
 
空虚 	NnetDiscriminativeUpdateParallel(const AmNnet&am_nnet,const TransitionModel&tmodel,const NnetDiscriminativeUpdateOptions&opts,int32 num_threads,SequentialDiscriminativeNnetExampleReader * example_reader,Nnet * nnet_to_update,NnetDiscriminativeStats * stats)
 
空虚 	NnetDiscriminativeUpdate(const AmNnet&am_nnet,const TransitionModel&tmodel,const NnetDiscriminativeUpdateOptions&opts,const DiscriminativeNnetExample&eg Nnet * nnet_to_update,NnetDiscriminativeStats * stats)
 	对于MMI,MPFE或SMBR目标函数,神经网络计算,网格前向后向和后向推进。 更多...
 
空虚 	UnitTestNnetCompute()
 
空虚 	UnitTestNnetComputeChunked()
 
空虚 	NnetComputation(const Nnet&nnet,const CuMatrixBase < BaseFloat >&input,bool pad_input,CuMatrixBase < BaseFloat > * output)
 	对数据序列进行基本的神经网络计算(例如 更多...
 
空虚 	NnetComputationChunked(const Nnet&nnet,const Matrix < BaseFloat >&input,int32 chunk_size,Matrix < BaseFloat > * output)
 	对数据序列进行基本的神经网络计算(例如 更多...
 
BaseFloat 	NnetGradientComputation(const Nnet&nnet,const CuMatrixBase < BaseFloat >&input,bool pad_input,const Posterior&pdf_post,Nnet * nnet_to_update)
 
BaseFloat 	NnetGradientComputation(const Nnet&nnet,const MatrixBase < BaseFloat >&input,bool pad_input,BaseFloat utterance_weight,const std :: vector <int32>&labels,Nnet * nnet_to_update)
 	神经网络计算和backprop,给定输入和标签。 更多...
 
空虚 	UnitTestSolvePackingProblem()
 
布尔 	LatticeToDiscriminativeExample(const std :: vector <int32>&alignment,const Matrix < BaseFloat >&feats,const CompactLattice&clat,BaseFloat weight,int32 left_context,int32 right_context,DiscriminativeNnetExample * eg)
 	将格子转换为判别训练的例子。 更多...
 
空虚 	SplitDiscriminativeExample(const SplitDiscriminativeExampleConfig&config,const TransitionModel&tmodel,const DiscriminativeNnetExample&eg std :: vector < DiscriminativeNnetExample > * egs_out,SplitExampleStats * stats_out)
 	将“判别性示例”分成多个部分,分裂格子具有“夹点”的位置。 更多...
 
空虚 	ExciseDiscriminativeExample(const SplitDiscriminativeExampleConfig&config,const TransitionModel&tmodel,const DiscriminativeNnetExample&eg std :: vector < DiscriminativeNnetExample > * egs_out,SplitExampleStats * stats_out)
 	从歧视性训练示例中删除不必要的帧。 更多...
 
空虚 	UpdateHash(const TransitionModel&tmodel,const DiscriminativeNnetExample&eg std :: string criteria,bool drop_frames,bool one_silence_class,Matrix <double> * hash,double * num_weight,double * den_weight,double * tot_t)
 	此函数用于测试我们在此提供的功能的代码,关于拆分和删除nnet示例。 更多...
 
空虚 	ExampleToPdfPost(常量TransitionModel&的tModel,常量性病::矢量<INT32>&silence_phones,的std :: string准则,布尔 drop_frames,布尔 one_silence_class,常量DiscriminativeNnetExample&例如,后路 *柱)
 	鉴于一个有辨别力的训练范例,这个功能可以在pdf级别找出后代(注意:这些是“区别对待 - 训练后期”,可能是正面的还是负面的。 更多......
 
空虚 	SolvePackingProblem(BaseFloat max_cost,const std :: vector < BaseFloat >&costs,std :: vector <std :: vector < size_t >> * groups)
 	该功能使用“首次拟合”算法解决了“打包问题”。 更多...
 
空虚 	AppendDiscriminativeExamples(const std :: vector <const DiscriminativeNnetExample *>&input,DiscriminativeNnetExample * output)
 	将给定的示例向量(必须为非空)附加到单个输出示例中(由CombineExamples调用,这可能是更方便的接口)。 更多...
 
空虚 	CombineDiscriminativeExamples(int32 max_length,const std :: vector < DiscriminativeNnetExample >&input,std :: vector < DiscriminativeNnetExample > * output)
 	该函数用于将多个判别训练示例(每个对应于一个格子的片段)组合成一个。 更多...
 
布尔 	HasSimpleLabels(const NnetExample&eg,std :: vector <int32> * simple_labels)
 
空虚 	FixNnet(const NnetFixConfig&config,Nnet * nnet)
 
INT32 	IndexOfSoftmaxLayer(const Nnet&nnet)
 	如果“nnet”只有一个softmax图层,则此函数将返回其索引; 否则它将返回-1。 更多...
 
空虚 	InsertComponents(const Nnet&src_nnet,int32 c,Nnet * dest_nnet)
 	将一个神经网络的组件插入另一个神经网络的特定位置。 更多...
 
空虚 	ReplaceLastComponents(const Nnet&src_nnet,int32 num_to_remove,Nnet * dest_nnet)
 	删除最后一个“num_to_remove”组件并添加“src_nnet”中的组件。 更多...
 
空虚 	LimitRankParallel(const NnetLimitRankOpts&opts,Nnet * nnet)
 	该函数通过将最小的奇异值归零来限制神经网络中每个仿射变换的等级。 更多...
 
空虚 	UnitTestNnet()
 
Nnet * 	GenRandomNnet(INT32 input_dim,INT32 output_dim)
 	该函数生成随机神经网络,用于测试目的。 更多...
 
空虚 	UnitTestPreconditionDirectionsOnline()
 
空虚 	UnitTestPreconditionDirections()
 
空虚 	PreconditionDirections(const CuMatrixBase < BaseFloat >&R,double lambda,CuMatrixBase < BaseFloat > * P)
 	请参阅下面的评论。 更多...
 
空虚 	PreconditionDirectionsAlpha(const CuMatrixBase < BaseFloat >&R,double alpha,CuMatrixBase < BaseFloat > * P)
 	PreconditionDirections的这个包装器使用= /(ND)trace(R ^ T,R)计算lambda,并调用PreconditionDirections。 更多...
 
空虚 	PreconditionDirectionsAlphaRescaled(const CuMatrixBase < BaseFloat >&R,double alpha,CuMatrixBase < BaseFloat > * P)
 	PreconditionDirections的这个包装器使用= /(ND)trace(R ^ T,R)计算lambda,并调用PreconditionDirections。 更多...
 
空虚 	GetNnetStats(const NnetStatsConfig&config,const Nnet&nnet,std :: vector < NnetStats > * stats)
 
双 	DoBackpropParallel(const Nnet&nnet,int32 minibatch_size,SequentialNnetExampleReader * example_reader,double * tot_weight,Nnet * nnet_to_update)
 	此函数类似于nnet-update.h中的 “DoBackprop”。此函数计算目标函数,并更新模型或计算参数渐变。 更多...
 
双 	DoBackpropSingleThreaded(const Nnet&nnet,int32 minibatch_size,const std :: vector < NnetExample >&egs,double * tot_weight,Nnet * nnet_to_update)
 
双 	DoBackpropParallel(const Nnet&nnet,int32 minibatch_size,int32 num_threads,const std :: vector < NnetExample >&examples,double * num_frames,Nnet * nnet_to_update)
 	此版本的DoBackpropParallel采用示例矢量,通常用于计算精确梯度。 更多...
 
双 	ComputeNnetObjfParallel(const Nnet&nnet,int32 minibatch_size,int32 num_threads,const std :: vector < NnetExample >&examples,double * num_frames)
 	这基本上是为了澄清DoBackpropParallel也将与nnet_to_update == NULL一起使用,并将计算objf。 更多...
 
空虚 	FormatNnetInput(const Nnet&nnet,const std :: vector < NnetExample >&data,Matrix < BaseFloat > * mat)
 	获取nnet的输入以获取示例的小批量,并将其格式化为单个矩阵。 更多...
 
BaseFloat 	TotalNnetTrainingWeight(const std :: vector < NnetExample >&egs)
 	返回所有示例中总和的总权重... 更多...
 
双 	ComputeNnetObjf(const Nnet&nnet,const std :: vector < NnetExample >&examples,double * tot_accuracy = NULL)
 	计算小批量的目标函数。 更多...
 
双 	DoBackprop(const Nnet&nnet,const std :: vector < NnetExample >&examples,Nnet * nnet_to_update,double * tot_accuracy = NULL)
 	此函数计算目标函数,并更新模型或添加参数渐变。 更多...
 
双 	DoBackprop(const Nnet&nnet,const std :: vector < NnetExample >&examples,Matrix < BaseFloat > * examples_formatted,Nnet * nnet_to_update,double * tot_accuracy = NULL)
 	此版本的DoBackprop允许您单独调用FormatNnetInput并将结果提供给DoBackprop; 这在使用GPU时非常有用,因为对FormatNnetInput的调用可以与使用GPU的线程分开。 更多...
 
双 	ComputeNnetGradient(const Nnet&nnet,const std :: vector < NnetExample >&examples,int32 batch_size,Nnet * gradient)
 	ComputeNnetGradient主要用于计算验证集的渐变; 它将示例分成批处理并在每个上调用DoBackprop()。 更多...
 
双 	ComputeNnetObjf(const Nnet&nnet,const std :: vector < NnetExample >&examples,int32 minibatch_size,double * tot_accuracy = NULL)
 	此版本的ComputeNnetObjf将示例分解为多个小批量来进行计算。 更多...
 
空虚 	UnitTestNnetDecodable()
 
空虚 	RescaleNnet(const NnetRescaleConfig&rescale_config,const std :: vector < NnetExample >&examples,Nnet * nnet)
 
静态BaseFloat 	ComputeObjfAndGradient(const std :: vector < NnetExample >&validation_set,const Vector <double>&log_scale_params,const Nnet&nnet,Vector <double> * gradient)
 
空虚 	ShrinkNnet(const NnetShrinkConfig&shrink_config,const std :: vector < NnetExample >&validation_set,Nnet * nnet)
 
静态Int32Pair 	MakePair(int32 first,int32 second)
 
Int64的 	TrainNnetSimple(const NnetSimpleTrainerConfig&config,Nnet * nnet,SequentialNnetExampleReader * reader,double * tot_weight = NULL,double * tot_logprob = NULL)
 	培训它可以从阅读器中读取的所有示例。 更多...
 
空虚 	WidenNnet(const NnetWidenConfig&widen_config,Nnet * nnet)
 	此功能通过增加目标的隐藏层尺寸来扩展神经网络。 更多...
 
BaseFloat 	KlDivergence(const Vector < BaseFloat >&p,const Vector < BaseFloat >&q)
 
空虚 	PrintPriorDiagnostics(const Vector < BaseFloat >&old_priors,const Vector < BaseFloat >&new_priors)
 
INT32 	GetCount(double expected_count)
 
空虚 	AverageConstPart(int32 const_feat_dim,DiscriminativeNnetExample * eg)
 
静态无效 	ProcessFile(const MatrixBase < BaseFloat >&feats,const Posterior&pdf_post,const std :: string&utt_id,int32 left_context,int32 right_context,int32 num_frames,int32 const_feat_dim,int64 * num_frames_written,int64 * num_egs_written,NnetExampleWriter * example_writer)
 
静态无效 	ProcessFile(const MatrixBase < BaseFloat >&feats,const Posterior&pdf_post,const std :: string&utt_id,const Vector < BaseFloat >&weights,int32 left_context,int32 right_context,int32 const_feat_dim,BaseFloat keep_proportion,BaseFloat weight_threshold,bool use_frame_selection,bool use_frame_weights,int64 * num_frames_written,int64 * num_frames_skipped,NnetExampleWriter * example_writer)
 
空虚 	SetMaxChange(BaseFloat max_change,Nnet * nnet)
 
空虚 	SetPriors(const TransitionModel&tmodel,const Vector <double>&transition_accs,double prior_floor,AmNnet * am_nnet)

变量
静态布尔 	nnet_example_warned_left = false
 
静态布尔 	nnet_example_warned_right = false
 
Typedef文档
◆  DiscriminativeNnetExampleWriter
typedef TableWriter < KaldiObjectHolder < DiscriminativeNnetExample >> DiscriminativeNnetExampleWriter
在文件nnet-example.h的第181行定义。

◆  NnetExampleWriter
typedef TableWriter < KaldiObjectHolder < NnetExample >> NnetExampleWriter
在文件nnet-example.h的第92行定义。

◆  RandomAccessDiscriminativeNnetExampleReader
typedef RandomAccessTableReader < KaldiObjectHolder < DiscriminativeNnetExample >> RandomAccessDiscriminativeNnetExampleReader
在文件nnet-example.h的第185行定义。

◆  RandomAccessNnetExampleReader
typedef RandomAccessTableReader < KaldiObjectHolder < NnetExample >> RandomAccessNnetExampleReader
在文件nnet-example.h的第94行定义。

◆  SequentialDiscriminativeNnetExampleReader
typedef SequentialTableReader < KaldiObjectHolder < DiscriminativeNnetExample >> SequentialDiscriminativeNnetExampleReader
在文件nnet-example.h的第183行定义。

◆  SequentialNnetExampleReader
typedef SequentialTableReader < KaldiObjectHolder < NnetExample >> SequentialNnetExampleReader
在文件nnet-example.h的第93行定义。

功能文档
◆  AddDirection()
static void kaldi :: nnet2 :: AddDirection	(	const Nnet& 	orig_nnet,
const Nnet& 	方向,
const VectorBase < BaseFloat >& 	尺度,
Nnet * 	DEST 
)		
静态的
将“dest”设置为orig_nnet加“方向”,每个可更新的“方向”组件首先按适当的比例缩放。

在文件combine-nnet-a.cc的第52行定义。

引用Nnet :: AddNnet()。

由CombineNnetsA()和ComputeObjfAndGradient()引用。

                                       {
    * dest = orig_nnet;
    dest-> AddNnet(scale,direction);
  }
◆  AppendDiscriminativeExamples()
void AppendDiscriminativeExamples	(	const std :: vector <const DiscriminativeNnetExample *>& 	输入,
DiscriminativeNnetExample * 	产量 
)		
将给定的示例向量(必须为非空)附加到单个输出示例中(由CombineExamples调用,这可能是更方便的接口)。

在组合示例时,它会直接附加要素,然后在网格中添加“假”段并在其间进行对齐,使用全部为1的transition-id填充。这在网络需要声学上下文的情况下是必要的,并且仅仅是因为nnet训练代码中的一种限制不支持在小批量内变化的“块”大小。

如果所有输入示例都没有相同的权重(无论如何通常为1.0),或者如果示例之间的要素维度(即基本要素维度加上spk_info维度)不同,则会失败。

在文件nnet-example-functions.cc的第891行定义。

参考文献DiscriminativeNnetExample :: den_lat,rnnlm :: i,DiscriminativeNnetExample :: input_frames,KALDI_ASSERT,kaldi :: kUndefined,DiscriminativeNnetExample :: left_context,DiscriminativeNnetExample :: num_ali,MatrixBase <Real> :: NumCols(),MatrixBase <Real> :: NumRows (),CompactLatticeWeightTpl <WeightType,IntType> :: One(),MatrixBase <Real> :: Range(),Matrix <Real> :: Resize(),DiscriminativeNnetExample :: spk_info和DiscriminativeNnetExample :: weight。

由CombineDiscriminativeExamples()和SplitExampleStats :: SplitExampleStats()引用。

                                         {
   KALDI_ASSERT(!input.empty());
   const DiscriminativeNnetExample&eg0 = *(input [0]);
   
    int32 dim = eg0.input_frames.NumCols()+ eg0.spk_info.Dim(),
        left_context = eg0.left_context,
        num_frames = eg0.num_ali.size(),
        right_context = eg0.input_frames.NumRows() -  num_frames  -  left_context;
 
    int32 tot_frames = eg0.input_frames.NumRows();  //总帧数(追加,
                                                   //带上下文)
   for(size_t  i = 1; i <input.size(); i ++)
      tot_frames + = input [ i ]  - > input_frames.NumRows();
 
    int32 arbitrary_tid = 1;  //我们用来填充的任意transition-id
                             //段之间的num_ali和den_lat成员
                             //(因为它们都是相同的,而且它们在中间
                             //这些部分是线性的,它们没有贡献
                             //导致培训)。
   
    output-> den_lat = eg0.den_lat;
    output-> num_ali = eg0.num_ali;
    output-> input_frames.Resize(tot_frames,dim,kUndefined);
    output-> input_frames.Range(0,eg0.input_frames.NumRows(),
                               0,eg0.input_frames.NumCols())。CopyFromMat(eg0.input_frames);
   if(eg0.spk_info.Dim()!= 0){
      output-> input_frames.Range(0,eg0.input_frames.NumRows(),
                                 eg0.input_frames.NumCols(),eg0.spk_info.Dim())。
          CopyRowsFromVec(eg0.spk_info);
    }
   
    output-> num_ali.reserve(tot_frames  -  left_context  -  right_context);
    输出 - >重量= eg0.weight;
    output-> left_context = eg0.left_context;
    output-> spk_info.Resize(0);
 
   CompactLattice inter_segment_clat;
    int32 initial = inter_segment_clat.AddState(); //状态0。
    inter_segment_clat.SetStart(初始);
   
    std :: vector <int32> inter_segment_ali(left_context + right_context);
    std :: fill(inter_segment_ali.begin(),inter_segment_ali.end(),arbitrary_tid);
 
   CompactLatticeWeight final_weight = CompactLatticeWeight :: One();
    final_weight.SetString(inter_segment_ali);
    inter_segment_clat.SetFinal(initial,final_weight);
   
    int32 feat_offset = eg0.input_frames.NumRows();
   
   for(size_t  i = 1; i <input.size(); i ++){
     const DiscriminativeNnetExample&eg_i = *(input [ i ]);
         
      output-> input_frames.Range(feat_offset,eg_i.input_frames.NumRows(),
                                 0,eg_i.input_frames.NumCols())。CopyFromMat(
                                     eg_i.input_frames);
     if(eg_i.spk_info.Dim()!= 0){
        output-> input_frames.Range(feat_offset,eg_i.input_frames.NumRows(),
                                   eg_i.input_frames.NumCols(),
                                   eg_i.spk_info.Dim())。CopyRowsFromVec(
                                       eg_i.spk_info);
       KALDI_ASSERT(eg_i.input_frames.NumCols()+
                     eg_i.spk_info.Dim()== dim);
      }
     
      output-> num_ali.insert(output-> num_ali.end(),
                             inter_segment_ali.begin(),inter_segment_ali.end());
      output-> num_ali.insert(output-> num_ali.end(),
                             eg_i.num_ali.begin(),eg_i.num_ali.end());
      Concat(&(output-> den_lat),inter_segment_clat);
      Concat(&(output-> den_lat),eg_i.den_lat);
     KALDI_ASSERT(输出 - >重量== eg_i.weight);
     KALDI_ASSERT(output-> left_context == eg_i.left_context);
      feat_offset + = eg_i.input_frames.NumRows();
    }
   KALDI_ASSERT(feat_offset == tot_frames);
  }
◆  AverageConstPart()
void kaldi :: nnet2 :: AverageConstPart	(	INT32 	const_feat_dim,
DiscriminativeNnetExample * 	例如 
)		
在文件nnet-copy-egs-discriminative.cc的第42行定义。

引用DiscriminativeNnetExample :: input_frames,KALDI_ASSERT,MatrixBase <Real> :: NumCols(),MatrixBase <Real> :: Range()和DiscriminativeNnetExample :: spk_info。

由main()引用。

                                                       {
   if(eg- > spk_info .Dim()!= 0){   //已经有const部分。
     KALDI_ASSERT(例如 - > spk_info .Dim()== const_feat_dim);
     //没什么可做的
    } else {
      int32 dim = eg- > input_frames。NumCols(),
          basic_dim = dim  -  const_feat_dim;
     KALDI_ASSERT(const_feat_dim <eg-> input_frames.NumCols());
     Matrix <BaseFloat> mat(eg- > input_frames);  //复制到非压缩矩阵
eg-      > input_frames = mat。范围(0,mat.NumRows(),0,basic_dim);
eg-      > spk_info .Resize(const_feat_dim);
eg-      > spk_info .AddRowSumMat(1.0 / mat.NumRows(),
                                mat.Range(0,mat.NumRows(),
                                          basic_dim,const_feat_dim),
                                0.0);
    }
  }
◆  BasicDebugTestForSpliceMax()
void kaldi :: nnet2 :: BasicDebugTestForSpliceMax	(	布尔 	输出 =false	)	
在文件nnet-component-test.cc的第811行定义。

引用SpliceMaxComponent :: Backprop(),rnnlm :: i,SpliceMaxComponent :: Init(),KALDI_LOG,SpliceMaxComponent :: OutputDim()和SpliceMaxComponent :: Propagate()。

由main()引用。

                                                     {
    int32 C = 5,
          context_len = 2,
          R = 3 + 2 * context_len;
 
   SpliceMaxComponent * c = new  SpliceMaxComponent();
    std :: vector <int32> context(2 * context_len + 1);
   for(int32 i = -1 * context_len; i <= context_len; i ++)
      context [ i + context_len] = i ;
    c-> Init(C,context);
   CuMatrix <BaseFloat> in(R,C),in_deriv(R,C);
   CuMatrix <BaseFloat> out(R,c-> OutputDim());
   ChunkInfo in_info = ChunkInfo(C,1,0,R-1),
              out_info = ChunkInfo(C,1,context_len,R-1-context_len);
 
    in.SetRandn();
   if(输出)
     KALDI_LOG << in;
 
    c-> Propagate(in_info,out_info,in和out);
 
   if(输出)
     KALDI_LOG << out;
 
    out.Set(5.0);
 
   if(输出)
     KALDI_LOG << out;
 
    C-> Backprop(in_info,out_info,在,IN,OUT,C,&in_deriv);
 
   if(输出)
     KALDI_LOG << in_deriv;
 
   删除 c;
  }
◆  CombineDiscriminativeExamples()
void CombineDiscriminativeExamples	(	INT32 	max_length,
const std :: vector < DiscriminativeNnetExample >& 	输入,
std :: vector < DiscriminativeNnetExample > * 	产量 
)		
该函数用于将多个判别训练示例(每个对应于一个格子的片段)组合成一个。

它将示例组合成组,使得每个组将具有小于或等于max_length的总长度(特征矩阵的行数)。但是,如果单个示例的长度超过max_length,则仍会处理它们; 他们将获得自己的团队。

另请参阅AppendDiscriminativeExamples()的文档,其中提供了有关我们如何附加示例的更多详细信息。

如果所有输入示例都没有相同的权重,则会失败(无论如何通常为1.0)。

如果spk_info变量非空,它将把它们移动到输出的特征中,因此输出的spk_info将为空,但相应的扬声器矢量将附加到特征的每一行。

在文件nnet-example-functions.cc的第970行定义。

引用AppendDiscriminativeExamples(),rnnlm :: i,rnnlm :: j和SolvePackingProblem()。

由main()和SplitExampleStats :: SplitExampleStats()引用。

                                                    {
   
    std :: vector <BaseFloat> cost(input.size());
   for(size_t  i = 0; i <input.size(); i ++)
      cost [ i ] = static_cast <BaseFloat>(input [ i ] .input_frames.NumRows());
    std :: vector <std :: vector <size_t >>组;
   SolvePackingProblem(max_length,
                        成本,
                        &groups);
    输出 - >清除();
    output-> resize(groups.size());
   for(size_t  i = 0; i <groups.size(); i ++){
      std :: vector <const DiscriminativeNnetExample *> group_egs;
     for(size_t  j = 0; j <groups [ i ] .size(); j ++){
       size_t index = groups [ i ] [ j ];
        group_egs.push_back(&(input [index]));
      }
     AppendDiscriminativeExamples(group_egs,&((* output)[ i ]));
    }
  }
◆  CombineNnets() [1/2]
static void kaldi :: nnet2 :: CombineNnets	(	const Vector < BaseFloat >& 	scale_params,
const std :: vector < Nnet >& 	nnets,
Nnet * 	DEST 
)		
静态的
在文件combine-nnet.cc的第28行定义。

引用Nnet :: AddNnet(),KALDI_ASSERT,rnnlm :: n,kaldi :: nnet3 :: NumUpdatableComponents()和Nnet :: ScaleComponents()。

由CombineNnets(),FastNnetCombiner :: ComputeCurrentNne​​t(),ComputeObjfAndGradient(),FastNnetCombiner :: FastNnetCombiner(),GetInitialModel(),FastNnetCombiner :: GetInitialModel(),main()和NnetCombineConfig :: Register()引用。

                                       {
    int32 num_nnets = nnets.size();
   KALDI_ASSERT(num_nnets> = 1);
    int32 num_uc = nnets [0] .NumUpdatableComponents();
   KALDI_ASSERT(num_nnets * nnets [0] .NumUpdatableComponents());
   
   
    * dest = nnets [0];
    SubVector <BaseFloat> scale_params0(scale_params,0,num_uc);
    dest-> ScaleComponents(scale_params0);
   for(int32 n = 1; n <num_nnets; n ++){
      SubVector <BaseFloat> scale_params_n(scale_params,n * num_uc,num_uc);
      dest-> AddNnet(scale_params_n,nnets [ n ]);
    }
  }
◆  CombineNnets() [2/2]
void CombineNnets	(	const NnetCombineConfig& 	combine_config,
const std :: vector < NnetExample >& 	validation_set,
const std :: vector < Nnet >& 	nnets,
Nnet * 	nnet_out 
)		
在文件combine-nnet.cc的第193行定义。

引用CombineNnets(),ComputeObjfAndGradient(),VectorBase <Real> :: CopyFromVec(),MatrixBase <Real> :: CopyRowsFromVec(),VectorBase <Real> :: Dim(),OptimizeLbfgs <Real> :: DoStep(),LbfgsOptions :: first_step_impr,GetInitialScaleParams(),OptimizeLbfgs <Real> :: GetProposedValue(),OptimizeLbfgs <Real> :: GetValue(),rnnlm :: i,NnetCombineConfig :: initial_impr,KALDI_ASSERT,KALDI_LOG,KALDI_VLOG,LbfgsOptions :: m,LbfgsOptions :: minimize,NnetCombineConfig :: num_bfgs_iters和NnetCombineConfig :: test_gradient。

                                    {
 
    Vector <double> scale_params;
 
   GetInitialScaleParams(combine_config,
                          validation_set,
                          nnets,
                          &scale_params);
 
    int32 dim = scale_params.Dim();
   KALDI_ASSERT(dim> 0);
    矢量<double> gradient(dim);
   
   double objf,initial_objf;
 
    LbfgsOptions lbfgs_options;
    lbfgs_options.minimize = false ; //我们正在最大化
    lbfgs_options.m =昏暗; //存储与维度相同数量的向量
   //本身,所以这是BFGS。
    lbfgs_options.first_step_impr = combine_config.initial_impr;
   
    OptimizeLbfgs <double> lbfgs(scale_params,
                                lbfgs_options);
   
   for(int32 i = 0; i <combine_config.num_bfgs_iters; i ++){    
      scale_params.CopyFromVec(lbfgs.GetProposedValue());
      objf = ComputeObjfAndGradient(validation_set,
                                    scale_params,
                                    nnets,
                                    combine_config.test_gradient,
                                    &gradient);
 
     KALDI_VLOG(2)<< “迭代” << i << “scale-params =” << scale_params
                    << “,objf =” << objf << “,gradient =” << gradient;
     
     if(i == 0)initial_objf = objf;
     
      lbfgs.DoStep(objf,gradient);
    }
 
    scale_params.CopyFromVec(lbfgs.GetValue(&objf));
 
    Vector <BaseFloat> scale_params_float(scale_params);
 
   KALDI_LOG << “组合nnets,每帧验证objf改变自”
              << initial_objf << “to” << objf;
 
    Matrix <BaseFloat> scale_params_mat(nnets.size(),
                                       nnets [0] .NumUpdatableComponents());
    scale_params_mat.CopyRowsFromVec(scale_params_float);
   KALDI_LOG << “最终比例因子是” << scale_params_mat;
   
   CombineNnets(scale_params_float,nnets,nnet_out);
  }
◆  CombineNnetsA()
void CombineNnetsA	(	const NnetCombineAconfig& 	配置,
const std :: vector < NnetExample >& 	validation_set,
const std :: vector < Nnet >& 	nnets,
Nnet * 	nnet_out 
)		
在文件combine-nnet-a.cc的第102行定义。

引用AddDirection(),ComputeObjfAndGradient(),VectorBase <Real> :: CopyFromVec(),VectorBase <Real> :: Dim(),OptimizeLbfgs <Real> :: DoStep(),LbfgsOptions :: first_step_length,Nnet :: GetComponent(),OptimizeLbfgs <Real> :: GetProposedValue(),GetUpdateDirection(),OptimizeLbfgs <Real> :: GetValue(),rnnlm :: i,NnetCombineAconfig :: initial_step,rnnlm :: j,KALDI_ASSERT,KALDI_LOG,KALDI_VLOG,KALDI_WARN,UpdatableComponent :: LearningRate() ,LbfgsOptions ::米,NnetCombineAconfig :: max_learning_rate_factor,NnetCombineAconfig :: min_learning_rate,NnetCombineAconfig :: min_learning_rate_factor,LbfgsOptions ::最小化,NnetCombineAconfig :: num_bfgs_iters,NNET :: NumComponents() ,kaldi :: nnet3: :NumUpdatableComponents(),NnetCombineAconfig :: overshoot,VectorBase <Real> :: Set(),UpdatableComponent :: SetLearningRate()和NnetCombineAconfig :: valid_impr_thresh。

由NnetCombineAconfig :: Register()引用。

                                     {
 
    Nnet方向; //更新方向= avg(nnets [1 ... N]) -  nnets [0]。
   GetUpdateDirection(nnets,&direction);
   
    Vector <double> scale_params(nnets [0] .NumUpdatableComponents()); //初始
   //在“方向”上缩放。
 
    int32 dim = scale_params.Dim();
   KALDI_ASSERT(dim> 0);
    矢量<double> gradient(dim);
   
   double objf,initial_objf,zero_objf;
 
   //将objf计算为零; 我们实际上并不需要这个渐变。
    zero_objf = ComputeObjfAndGradient(validation_set,
                                       scale_params,
                                       网[0],
                                       方向,
                                       &gradient);
   KALDI_LOG << “旧参数的目标函数是”
              << zero_objf;
   
    scale_params.Set(1.0); //从参数的平均值开始优化。
 
    LbfgsOptions lbfgs_options;
    lbfgs_options.minimize = false ; //我们正在最大化
    lbfgs_options.m =昏暗; //存储与维度相同数量的向量
   //本身,所以这是BFGS。
    lbfgs_options.first_step_length = config.initial_step;
   
    OptimizeLbfgs <double> lbfgs(scale_params,
                                lbfgs_options);
   
   for(int32 i = 0; i <config.num_bfgs_iters; i ++){    
      scale_params.CopyFromVec(lbfgs.GetProposedValue());
      objf = ComputeObjfAndGradient(validation_set,
                                    scale_params,
                                    网[0],
                                    方向,
                                    &gradient);
 
     KALDI_VLOG(2)<< “迭代” << i << “scale-params =” << scale_params
                    << “,objf =” << objf << “,gradient =” << gradient;
     
     if(i == 0)initial_objf = objf;    
      lbfgs.DoStep(objf,gradient);
    }
 
    scale_params.CopyFromVec(lbfgs.GetValue(&objf));
 
   KALDI_LOG << “结合nnets,在BFGS之后,每帧的验证objf从”
              << zero_objf << “(无变化),或” << initial_objf << “(默认变更),”
              << “to” << objf << “;更新方向的比例因子是”
              << scale_params;
 
   BaseFloat objf_change = objf  -  zero_objf;
   KALDI_ASSERT(objf_change> = 0.0); //这是由L-BFGS代码保证的。
 
   if(objf_change <config.valid_impr_thresh){
     //我们会超调。要在两个政权之间平稳过渡,如果
     // objf_change接近valid_impr_thresh我们没有超出目标。
     BaseFloat overhoot = config.overshoot,
          overshoot_max = config.valid_impr_thresh / objf_change; //> = 1.0。
     if(overshoot_max <overshoot){
       KALDI_LOG << “限制超调从” << overshoot << “到” << overshoot_max
                  << “因为objf-impr” << objf_change << “接近于”
                  << “ -  valid-impr-thresh =” << config.valid_impr_thresh;
        overshoot = overshoot_max;
      }
     KALDI_ASSERT(过冲<2.0 && “ -  valid-impr-thresh必须<2.0或”
                  “这将导致不稳定。” );
      scale_params.Scale(overshoot);
 
     BaseFloat optimized_objf = objf;
      objf = ComputeObjfAndGradient(validation_set,
                                    scale_params,
                                    网[0],
                                    方向,
                                    &gradient);
 
     KALDI_LOG << “结合nnets,过冲后,验证objf改变了”
                << “to” << objf << “。注意:(零,开始,优化)objfs是”
                << zero_objf << “,” << initial_objf << “,” << optimized_objf;
     if(objf <zero_objf){
       //注意:根据二次近似,这不应该发生,我们
       //如果有的话,期望这个分支很少被采用。
       KALDI_WARN << “在超调之后,objf比不更新更糟糕;不做”
                   << “过冲。” ;
       scale_params.Scale(1.0 / overshoot);
      }
    } //否则不要做“过冲”的事情。
   
    Vector <BaseFloat> scale_params_float(scale_params);
   //输出到“nnet_out”:
   AddDirection(nnets [0],direction,scale_params_float,nnet_out);
 
   //现在更新神经网络学习率。
    int32 i = 0;
   for(int32 j = 0; j <nnet_out-> NumComponents(); j ++){
      UpdatableComponent * uc =
         dynamic_cast < UpdatableComponent * >(&(nnet_out-> GetComponent(j)));
     if(uc!= NULL){
       BaseFloat step_length = scale_params(i),factor = step_length;
       //我们的基本规则是通过乘以它来更新学习率
       // by“step_lenght”,但这受到某些限制。
       if(factor <config.min_learning_rate_factor)
          factor = config.min_learning_rate_factor;
       if(factor> config.max_learning_rate_factor)
          factor = config.max_learning_rate_factor;
       BaseFloat new_learning_rate = factor * uc-> LearningRate();
       if(new_learning_rate <config.min_learning_rate)
          new_learning_rate = config.min_learning_rate;
       KALDI_LOG << “对于组件” << j << “,步长为” << step_length
                  << “,按因子更新学习率” << factor << “,改变”
                  << “学习率从” << uc-> LearningRate()<< “到”
                  << new_learning_rate;
        uc-> SetLearningRate(new_learning_rate);
        i ++;
      }
    }
  }
◆  CombineNnetsFast()
void CombineNnetsFast	(	const NnetCombineFastConfig& 	combine_config,
const std :: vector < NnetExample >& 	validation_set,
const std :: vector < Nnet >& 	nnets_in,
Nnet * 	nnet_out 
)		
在文件combine-nnet-fast.cc的第430行定义。

由main()和NnetCombineFastConfig :: Register()引用。

                                        {
   //初始化程序中发生了一切。
    FastNnetCombiner组合器(combine_config,
                              validation_set,
                              nnets_in,
                              nnet_out);
  }
◆  ComputeNnetGradient()
双ComputeNnetGradient	(	const Nnet& 	nnet,
const std :: vector < NnetExample >& 	例子,
INT32 	batch_size,
Nnet * 	梯度 
)		
ComputeNnetGradient主要用于计算验证集的渐变; 它将示例分成批处理并在每个上调用DoBackprop()。

它返回每帧*平均*目标函数。

在文件nnet-update.cc的第302行定义。

引用DoBackprop(),rnnlm :: i和Nnet :: SetZero()。

由ComputeObjfAndGradient()和main()引用。

                      {
   bool treat_as_gradient = true ;
    gradient-> SetZero(treat_as_gradient);
    std :: vector <NnetExample> batch;
    batch.reserve(batch_size);
   double tot_objf = 0.0;
   for(int32 start_pos = 0;
         start_pos <static_cast <int32>(validation_set.size());
         start_pos + = batch_size){
      batch.clear();
     for(int32 i = start_pos;
          我 <std :: min(start_pos + batch_size,
                        static_cast <int32>(validation_set.size()));
          i ++){
        batch.push_back(validation_set [ i ]);
      }
      tot_objf + = DoBackprop(nnet,
                             批,
                             渐变);
    }
   return tot_objf / validation_set.size();
  }
◆  ComputeNnetObjf() [1/2]
double ComputeNnetObjf	(	const Nnet& 	nnet,
const std :: vector < NnetExample >& 	例子,
双* 	tot_accuracy =NULL 
)		
计算小批量的目标函数。

返回miniatch上的* total *加权目标函数。如果tot_accuracy!= NULL,则向该指针输出总(加权)精度。

在文件nnet-update.cc的第258行定义。

引用NnetUpdater :: ComputeForMinibatch()。

由ComputeNnetObjf(),DoBackprop(),GetInitialModel(),main()和DoBackpropParallelClass :: operator()()引用。

                                               {
    NnetUpdater更新程序(nnet,NULL);
   return updater.ComputeForMinibatch(examples,tot_accuracy);
  }
◆  ComputeNnetObjf() [2/2]
double ComputeNnetObjf	(	const Nnet& 	nnet,
const std :: vector < NnetExample >& 	例子,
INT32 	minibatch_size,
双* 	tot_accuracy =NULL 
)		
此版本的ComputeNnetObjf将示例分解为多个小批量来进行计算。

返回* total *(加权)目标函数。如果tot_accuracy!= NULL,则向该指针输出总(加权)精度。

在文件nnet-update.cc的第329行定义。

引用ComputeNnetObjf()和rnnlm :: i。

                            {
   double tot_accuracy_tmp;
   if(tot_accuracy)
      * tot_accuracy = 0.0;
    std :: vector <NnetExample> batch;
    batch.reserve(batch_size);
   double tot_objf = 0.0;
   for(int32 start_pos = 0;
         start_pos <static_cast <int32>(validation_set.size());
         start_pos + = batch_size){
      batch.clear();
     for(int32 i = start_pos;
          i <std :: min(start_pos + batch_size,
                        static_cast <int32>(validation_set.size()));
          i ++){
        batch.push_back(validation_set [ i ]);
      }
      tot_objf + = ComputeNnetObjf(nnet,batch,
                                  tot_accuracy!= NULL?&tot_accuracy_tmp:NULL);
     if(tot_accuracy)
        * tot_accuracy + = tot_accuracy_tmp;
    }
   return tot_objf;
  }
◆  ComputeNnetObjfParallel()
double kaldi :: nnet2 :: ComputeNnetObjfParallel	(	const Nnet& 	nnet,
INT32 	minibatch_size,
INT32 	num_threads,
const std :: vector < NnetExample >& 	例子,
双* 	num_frames 
)		
排队
这基本上是为了澄清DoBackpropParallel也将与nnet_to_update == NULL一起使用,并将计算objf。

这两个版本的函数都支持它,但是这个版本(带有一个向量)是我们目前唯一需要这样做的版本。

在文件nnet-update-parallel.h的第71行定义。

引用DoBackpropParallel()。

由FastNnetCombiner :: GetInitialModel()引用。

                          {
   返回 DoBackpropParallel(nnet,minibatch_size,num_threads,
                              例子,num_frames,NULL);
  }
◆  ComputeObjfAndGradient() [1/3]
static BaseFloat kaldi :: nnet2 :: ComputeObjfAndGradient	(	const std :: vector < NnetExample >& 	validation_set,
const Vector <double>& 	log_scale_params,
const Nnet& 	nnet,
矢量 <double> * 	梯度 
)		
静态的
在文件shrink-nnet.cc的第25行定义。

引用VectorBase <Real> :: ApplyExp(),ComputeNnetGradient(),VectorBase <Real> :: Dim(),UpdatableComponent :: DotProduct(),Nnet :: GetComponent(),rnnlm :: i,rnnlm :: j,KALDI_ASSERT,Nnet :: NumComponents(),Nnet :: ScaleComponents()和Nnet :: SetZero()。

                                {
    Vector <BaseFloat> scale_params(log_scale_params);
    scale_params.ApplyExp();
    Nnet nnet_scaled(nnet);
    nnet_scaled.ScaleComponents(scale_params);
   
    Nnet nnet_gradient(nnet);
   bool is_gradient = true ;
    nnet_gradient.SetZero(is_gradient);
 
   //注意:“ans”由验证帧的总权重标准化。
    int32 batch_size = 1024;
   BaseFloat ans = ComputeNnetGradient(nnet_scaled,
                                        validation_set,
                                        batch_size,
                                        &nnet_gradient);
 
   BaseFloat tot_count = validation_set.size();
    int32 i = 0; //索引到log_scale_params。
   for(int32 j = 0; j <nnet_scaled.NumComponents(); j ++){
     const UpdatableComponent * uc =
         dynamic_cast < const UpdatableComponent * >(&(nnet.GetComponent(j))),
          * uc_gradient =
         dynamic_cast < const UpdatableComponent * >(&(nnet_gradient.GetComponent(j)));
     if(uc!= NULL){
       BaseFloat dotprod = uc-> DotProduct(* uc_gradient)/ tot_count;
        (* gradient)(i)= dotprod * scale_params(i); //渐变wrt日志缩放因子。
       //我们乘以scale_params(i)来考虑d / dx exp(x); “梯度”
       //是scale_params日志的梯度。
        i ++;
      }
    }
   KALDI_ASSERT(ⅰ== log_scale_params。暗淡());
   返回 ;
  }
◆  ComputeObjfAndGradient() [2/3]
static BaseFloat kaldi :: nnet2 :: ComputeObjfAndGradient	(	const std :: vector < NnetExample >& 	validation_set,
const Vector <double>& 	scale_params,
const Nnet& 	orig_nnet,
const Nnet& 	方向,
矢量 <double> * 	梯度 
)		
静态的
在文件combine-nnet-a.cc的第61行定义。

引用AddDirection(),ComputeNnetGradient(),VectorBase <Real> :: Dim(),UpdatableComponent :: DotProduct(),Nnet :: GetComponent(),rnnlm :: i,rnnlm :: j,KALDI_ASSERT,Nnet :: NumComponents( )和Nnet :: SetZero()。

由CombineNnets(),CombineNnetsA(),ComputeObjfAndGradient(),FastNnetCombiner :: FastNnetCombiner()和ShrinkNnet()引用。

                                {
   
    Vector <BaseFloat> scale_params_float(scale_params);
 
    Nnet nnet_combined;
   AddDirection(orig_nnet,direction,scale_params_float,&nnet_combined);
   
    Nnet nnet_gradient(nnet_combined);
   bool is_gradient = true ;
    nnet_gradient.SetZero(is_gradient);
   
   //注意:“ans”由验证帧的总权重标准化。
    int32 batch_size = 1024;
   BaseFloat ans = ComputeNnetGradient(nnet_combined,
                                        validation_set,
                                        batch_size,
                                        &nnet_gradient);
 
   BaseFloat tot_count = validation_set.size();
    int32 i = 0; //索引到scale_params。
   for(int32 j = 0; j <nnet_combined.NumComponents(); j ++){
     const UpdatableComponent * uc_direction =
         dynamic_cast < const UpdatableComponent * >(&(direction.GetComponent(j))),
          * uc_gradient =
         dynamic_cast < const UpdatableComponent * >(&(nnet_gradient.GetComponent(j)));
     if(uc_direction!= NULL){
       BaseFloat dotprod = uc_direction-> DotProduct(* uc_gradient)/ tot_count;
        (* gradient)(i)= dotprod;
        i ++;
      }
    }
   KALDI_ASSERT(ⅰ== scale_params。暗淡());
   返回 ans;
  }
◆  ComputeObjfAndGradient() [3/3]
static double kaldi :: nnet2 :: ComputeObjfAndGradient	(	const std :: vector < NnetExample >& 	validation_set,
const Vector <double>& 	scale_params,
const std :: vector < Nnet >& 	nnets,
布尔 	调试,
矢量 <double> * 	梯度 
)		
静态的
在文件combine-nnet.cc的第124行定义。

引用CombineNnets(),ComputeNnetGradient(),ComputeObjfAndGradient(),VectorBase <Real> :: Dim(),UpdatableComponent :: DotProduct(),Nnet :: GetComponent(),rnnlm :: i,rnnlm :: j,KALDI_ASSERT,KALDI_LOG,rnnlm :: n,Nnet :: NumComponents()和Nnet :: SetZero()。

                                {
 
    Vector <BaseFloat> scale_params_float(scale_params);
   
    Nnet nnet_combined;
   CombineNnets(scale_params_float,nnets,&nnet_combined);
   
    Nnet nnet_gradient(nnet_combined);
   bool is_gradient = true ;
    nnet_gradient.SetZero(is_gradient);
   
   //注意:“ans”由验证帧的总权重标准化。
    int32 batch_size = 1024;
   double ans = ComputeNnetGradient(nnet_combined,
                                     validation_set,
                                     batch_size,
                                     &nnet_gradient);
 
   double tot_frames = validation_set.size();
   if(gradient!= NULL){
      int32 i = 0; //索引到scale_params。  
     for(int32 n = 0; n <static_cast <int32>(nnets.size()); n ++){
       for(int32 j = 0; j <nnet_combined.NumComponents(); j ++){
         const UpdatableComponent * uc =
             dynamic_cast < const UpdatableComponent * >(&(nnets [ n ] .GetComponent(j))),
              * uc_gradient =
             dynamic_cast < const UpdatableComponent * >(&(nnet_gradient.GetComponent(j)));
         if(uc!= NULL){
           double dotprod = uc-> DotProduct(* uc_gradient)/ tot_frames;
            (* gradient)(i)= dotprod;
            i ++;
          }
        }
      }
     KALDI_ASSERT(ⅰ== scale_params。暗淡());
    }
 
   if(debug){
     KALDI_LOG << “双重梯度计算” ;
     
      矢量<BaseFloat> manual_gradient(scale_params。暗淡());
     为(我的int32 = 0; I <scale_params。暗淡();我++){
       double delta = 1.0e-04,fg = fabs((* gradient)(i));
       if(fg <1.0e-07)fg = 1.0e-07;
       if(fg * delta <1.0e-05)
          delta = 1.0e-05 / fg;
       
        Vector <double> scale_params_temp(scale_params);
        scale_params_temp(i)+ = delta;
       double new_ans = ComputeObjfAndGradient(validation_set,
                                                scale_params_temp,
                                                nnets,
                                               假,
                                                NULL);
        manual_gradient(i)=(new_ans  -  ans)/ delta;
      }
     KALDI_LOG << “手动计算的梯度是” << manual_gradient;
     KALDI_LOG << “我们计算的梯度是” <<梯度;
    }
   
   返回 ;
  }
◆  DoBackprop() [1/2]
双DoBackprop	(	const Nnet& 	nnet,
const std :: vector < NnetExample >& 	例子,
Nnet * 	nnet_to_update,
双* 	tot_accuracy =NULL 
)		
此函数计算目标函数,并更新模型或添加参数渐变。

返回在所有样本上求和的交叉熵目标函数(通过除以TotalNnetTrainingWeight(示例)将其归一化)。它主要是在nnet-update.cc中定义的类NnetUpdater的包装器,但我们不希望在此级别公开该复杂性。所有这些例子将被视为一个小批量。如果tot_accuracy!= NULL,则向该指针输出总(加权)精度。

在文件nnet-update.cc的第265行定义。

引用NnetUpdater :: ComputeForMinibatch(),ComputeNnetObjf(),Nnet :: Info()和KALDI_LOG。

由ComputeNnetGradient(),DoBackpropSingleThreaded(),FisherComputationClass :: operator()(),DoBackpropParallelClass :: operator()()和TrainNnetSimple()引用。

                                          {
   if(nnet_to_update == NULL)
     返回 ComputeNnetObjf(nnet,examples,tot_accuracy);
   试试 {
      NnetUpdater更新程序(nnet,nnet_to_update);
     return updater.ComputeForMinibatch(examples,tot_accuracy);
    } catch(...){
     KALDI_LOG << “执行backprop时出错,nnet信息为:” << nnet.Info();
     投掷 ;
    }
  }
◆  DoBackprop() [2/2]
双DoBackprop	(	const Nnet& 	nnet,
const std :: vector < NnetExample >& 	例子,
Matrix < BaseFloat > * 	examples_formatted,
Nnet * 	nnet_to_update,
双* 	tot_accuracy =NULL 
)		
此版本的DoBackprop允许您单独调用FormatNnetInput并将结果提供给DoBackprop; 这在使用GPU时非常有用,因为对FormatNnetInput的调用可以与使用GPU的线程分开。

“examples_formatted”实际上是一个输入,但它是一个指针,因为我们在内部调用Swap(),所以我们销毁它的内容。

在文件nnet-update.cc的第281行定义。

引用NnetUpdater :: ComputeForMinibatch(),ComputeNnetObjf(),Nnet :: Info(),KALDI_LOG和KALDI_WARN。

                                          {
   if(nnet_to_update == NULL){
     KALDI_WARN << “没想到达到这条代码路径”
                 << “(浪费格式化数据两次)” ;
     返回 ComputeNnetObjf(nnet,examples,tot_accuracy);
   } 尝试 {
      NnetUpdater更新程序(nnet,nnet_to_update);
     返回 updater.ComputeForMinibatch(示例,
                                         examples_formatted,
                                         tot_accuracy);
    } catch(...){
     KALDI_LOG << “执行backprop时出错,nnet信息为:” << nnet.Info();
     投掷 ;
    }
  }
◆  DoBackpropParallel() [1/2]
双DoBackpropParallel	(	const Nnet& 	nnet,
INT32 	minibatch_size,
SequentialNnetExampleReader * 	example_reader,
双* 	tot_weight,
Nnet * 	nnet_to_update 
)		
此函数类似于nnet-update.h中的 “DoBackprop”。此函数计算目标函数,并更新模型或计算参数渐变。

它返回对所有样本求和的加权的交叉熵目标函数,以及样本的总权重(通常与#frames相同)为total_weight。它主要是在nnet-update.cc中定义的类NnetUpdater的包装器,但我们不希望在此级别公开该复杂性。注意:这个函数如果&nnet == nnet_to_update,它假设我们正在做SGD并做类似Hogwild的事情; 否则它假设我们正在计算一个渐变,它总结了渐变。返回值是#frames上总log-prob的总和。它还将#frames输出到“num_frames”。

在文件nnet-update-parallel.cc的第147行定义。

引用ExamplesRepository :: AcceptExamples(),DoBackpropSingleThreaded(),SequentialTableReader <Holder> :: Done(),ExamplesRepository :: ExamplesDone(),kaldi :: g_num_threads,KALDI_LOG,SequentialTableReader <Holder> :: Next()和SequentialTableReader <Holder > :: Value()。

由ComputeNnetObjfParallel(),FastNnetCombiner :: ComputeObjfAndGradient()和main()引用。

                                                  {
 #if HAVE_CUDA == 1
   //我们的GPU代码不适用于多线程; 我们这样做
   //使其能够在单线程中使用此代码
   //案例
   if(CuDevice :: Instantiate()。Enabled())
     返回 DoBackpropSingleThreaded(nnet,minibatch_size,examples_reader,
                                      tot_weight,nnet_to_update);
 #endif
 
    ExamplesRepository存储库; //处理有关的并行编程问题
   //数据的“例子”。
   double tot_log_prob = 0.0;
    * tot_weight = 0.0;
 
   //此函数假定您需要精确的渐变,如果
   // nnet_to_update!=&nnet。
   const  bool store_separate_gradients =(nnet_to_update!=&nnet);
 
    DoBackpropParallelClass c(nnet,&repository,tot_weight,
                              &tot_log_prob,nnet_to_update,
                              store_separate_gradients);
 
    {
     //以下类的初始化产生了那些线程
     //处理示例。他们在析构函数中重新加入。
      MultiThreader <DoBackpropParallelClass> m(g_num_threads,c);
 
      std :: vector <NnetExample>示例;
     for(;!examples_reader-> Done(); examples_reader-> Next()){
        examples.push_back(examples_reader-> Value());
       if(examples.size()== minibatch_size)
          repository.AcceptExamples(&examples);
      }
     if(!examples.empty())//部分minibatch。
        repository.AcceptExamples(&examples);
     //这里,“m”的析构函数重新加入线程,并且
     //如果我们正在做渐变,会对渐变进行求和
     //计算(即&nnet!= nnet_to_update)。这得到了
     //在类型对象的析构函数中完成
     // DoBackpropParallelClass。
      repository.ExamplesDone();
    }
   KALDI_LOG << “ backprop on” << * tot_weight << “示例,平均log-prob”
              << “每帧是” <<(tot_log_prob / * tot_weight);
   KALDI_LOG << “[此行将由脚本解析:] log-prob-per-frame =”
              <<(tot_log_prob / * tot_weight);
   return tot_log_prob;
  }
◆  DoBackpropParallel() [2/2]
双DoBackpropParallel	(	const Nnet& 	nnet,
INT32 	minibatch_size,
INT32 	num_threads,
const std :: vector < NnetExample >& 	例子,
双* 	num_frames,
Nnet * 	nnet_to_update 
)		
此版本的DoBackpropParallel采用示例矢量,通常用于计算精确梯度。

在文件nnet-update-parallel.cc的第221行定义。

引用ExamplesRepository :: AcceptExamples(),DoBackpropSingleThreaded(),ExamplesRepository :: ExamplesDone()和KALDI_VLOG。

                                                  {
   if(num_threads == 1)//支持GPU:1个线程的特殊情况。
     返回 DoBackpropSingleThreaded(nnet,minibatch_size,egs,
                                      tot_weight,nnet_to_update);
 
    ExamplesRepository存储库; //处理有关的并行编程问题
   //数据的“例子”。
   double tot_log_prob = 0.0;
    * tot_weight = 0;
   const  bool store_separate_gradients =(nnet_to_update!=&nnet);
 
    DoBackpropParallelClass c(nnet,&repository,tot_weight,
                              &tot_log_prob,nnet_to_update,
                              store_separate_gradients);
 
    {
     //以下类的初始化产生了那些线程
     //处理示例。他们在析构函数中重新加入。
      MultiThreader <DoBackpropParallelClass> m(num_threads,c);
 
      int32 num_egs = egs.size();
     for(int32 offset = 0; offset <num_egs; offset + = minibatch_size){
        int32 this_minibatch_size = std :: min(minibatch_size,num_egs  -  offset);
 
       //我们浪费了一点时间复制这里的例子,但这很小。
        std :: vector <NnetExample>示例(egs.begin()+ offset,
                                                  egs.begin()+ offset + this_minibatch_size);
 
        repository.AcceptExamples(&examples);
      }
 
     //这里,“m”的析构函数重新加入线程,并且
     //如果我们正在做渐变,会对渐变进行求和
     //计算(即&nnet!= nnet_to_update)。这得到了
     //在类型对象的析构函数中完成
     // DoBackpropParallelClass。
      repository.ExamplesDone();
    }
   KALDI_VLOG(2)<< “ backprop on” << * tot_weight << “例子,平均log-prob”
                  << “每帧是” <<(tot_log_prob / * tot_weight);
   return tot_log_prob;
  }
◆  DoBackpropSingleThreaded()
double kaldi :: nnet2 :: DoBackpropSingleThreaded	(	const Nnet& 	nnet,
INT32 	minibatch_size,
const std :: vector < NnetExample >& 	egs,
双* 	tot_weight,
Nnet * 	nnet_to_update 
)		
在文件nnet-update-parallel.cc的第202行定义。

引用DoBackprop(),rnnlm :: i和TotalNnetTrainingWeight()。

由DoBackpropParallel()引用。

                                                        {
   double ans = 0.0;
    * tot_weight = TotalNnetTrainingWeight(egs);
   for(size_t  i = 0; i <egs.size(); i + = minibatch_size){
      std :: vector <NnetExample> :: const_iterator end_iter =
        (i + minibatch_size> egs.size()?egs.end():
         egs.begin()+ i + minibatch_size);
      std :: vector <NnetExample> this_egs(egs.begin()+ i,
                                                end_iter);
      ans + = DoBackprop(nnet,this_egs,nnet_to_update);
    }
   返回 ;
  }
◆  ExampleToPdfPost()
void ExampleToPdfPost	(	const TransitionModel& 	tmodel,
const std :: vector <int32>& 	silence_phones,
的std :: string 	标准,
布尔 	drop_frames,
布尔 	one_silence_class,
const DiscriminativeNnetExample& 	例如,
后方 * 	岗位 
)		
鉴于一个有辨别力的训练范例,这个功能可以在pdf级别找出后代(注意:这些是“区别对待 - 训练后验”,可能是积极的或消极的。

示例“eg”中的分母点阵“den_lat”应该已经进行了声学重新校正,以使其声学探测器是最新的,并且应该已经应用了任何声学缩放。

“标准”可以是“mmi”或“mpfe”或“smbr”。如果标准是“mmi”,则“drop_frames”表示我们不包括分子pdf不在分母点阵中的帧的导数。

如果“one_silence_class”为true,则可以为MPE / SMBR获得更新的行为,这将减少插入。

“silence_phones”是一个静音电话列表(这仅适用于mpfe或smbr,如果我们想特别对待沉默)。

在文件nnet-example-functions.cc的第838行定义。

引用fst :: ConvertLattice(),kaldi :: ConvertPosteriorToPdfs(),DiscriminativeNnetExample :: den_lat,KALDI_ASSERT,kaldi :: LatticeForwardBackwardMmi(),kaldi :: LatticeForwardBackwardMpeVariants(),DiscriminativeNnetExample :: num_ali,kaldi :: ScalePosterior()和DiscriminativeNnetExample ::重量。

由SplitExampleStats :: SplitExampleStats()和UpdateHash()引用。

                       {
   KALDI_ASSERT(标准== “mpfe” ||标准== “smbr” ||标准== “mmi”);
   
   Lattice lat;
   ConvertLattice(eg.den_lat,&lat);
    TopSort(&lat);
   if(criterion == “mpfe” || criterion == “smbr”){
     后 tid_post;
     LatticeForwardBackwardMpeVariants(tmodel,silence_phones,lat,eg.num_ali,
                                        标准,one_silence_class,&tid_post);
     
     ConvertPosteriorToPdfs(tmodel,tid_post,post);
    } else {
     bool convert_to_pdf_ids = true,cancel = true ;
     LatticeForwardBackwardMmi(tmodel,lat,eg.num_ali,
                                drop_frames,convert_to_pdf_ids,取消,
                                帖子);
    }
   ScalePosterior(例如,重量,后);
  }
◆  ExciseDiscriminativeExample()
void ExciseDiscriminativeExample	(	const SplitDiscriminativeExampleConfig& 	配置,
const TransitionModel& 	tmodel,
const DiscriminativeNnetExample& 	例如,
std :: vector < DiscriminativeNnetExample > * 	egs_out,
SplitExampleStats * 	stats_out 
)		
从歧视性训练示例中删除不必要的帧。

调用后输出egs_out的大小为零或一(通常为一)。

在文件nnet-example-functions.cc的第775行定义。

参考文献DiscriminativeExampleSplitter :: Excise()。

由main()和SplitExampleStats :: SplitExampleStats()引用。

                                    {
    DiscriminativeExampleSplitter拆分器(config,tmodel,例如egs_out);
    splitter.Excise(stats_out);
  }
◆  ExpectOneOrTwoTokens()
static void kaldi :: nnet2 :: ExpectOneOrTwoTokens	(	std :: istream& 	是的,
布尔 	二进制,
const std :: string& 	token1,
const std :: string& 	token2 
)		
静态的
在文件nnet-component.cc的第135行定义。

引用kaldi :: ExpectToken(),KALDI_ASSERT,KALDI_ERR和kaldi :: ReadToken()。

引用于NonlinearComponent :: Read(),MaxoutComponent :: Read(),MaxpoolingComponent :: Read(),PnormComponent :: Read(),PowerComponent :: Read(),ScaleComponent :: Read(),AffineComponent :: Read(),AffineComponentPreconditioned :: Read(),AffineComponentPreconditionedOnline :: Read(),SpliceComponent :: Read(),SpliceMaxComponent :: Read(),BlockAffineComponent :: Read(),BlockAffineComponentPreconditioned :: Read(),SumGroupComponent :: Read(),PermuteComponent :: Read(),DctComponent :: Read(),FixedLinearComponent :: Read(),FixedAffineComponent :: Read(),FixedScaleComponent :: Read(),FixedBiasComponent :: Read(),DropoutComponent :: Read(),AdditiveNoiseComponent :: Read(),以及Convolutional1dComponent :: Read()。

                                                            {
   KALDI_ASSERT(token1!= token2);
    std :: string temp;
   ReadToken(is,binary,&temp);
   if(temp == token1){
     ExpectToken(是,binary,token2);
    } else {
     if(temp!= token2){
       KALDI_ERR << “期望令牌” << token1 << “或” << token2
                  << “但得到了” << temp;
      }
    }
  }
◆  FixNnet()
void FixNnet	(	const NnetFixConfig& 	配置,
Nnet * 	NNET 
)		
在文件nnet-fix.cc的第31行定义。

引用AffineComponent :: BiasParams(),count,NonlinearComponent :: Count(),rnnlm :: d,NonlinearComponent :: DerivSum(),Nnet :: GetComponent(),NonlinearComponent :: InputDim(),KALDI_ASSERT,KALDI_LOG,KALDI_WARN,AffineComponent :: LinearParams(),NnetFixConfig :: max_average_deriv,NnetFixConfig :: min_average_deriv,Nnet :: NumComponents(),NnetFixConfig :: parameter_factor,NnetFixConfig :: relu_bias_change,andAffineComponent :: SetParams()。

由main()和NnetFixConfig :: Register()引用。

                                                        {
   for(int32 c = 0; c + 1 <nnet-> NumComponents(); c ++){
      AffineComponent * ac = dynamic_cast < AffineComponent * >(
          &(nnet-> GetComponent(c)));
      NonlinearComponent * nc = dynamic_cast < NonlinearComponent * >(
          &(nnet-> GetComponent(c + 1)));
     if(ac == NULL || nc == NULL)继续 ;
     //我们只想处理它,如果它是SigmoidComponent类型
     //或TanhComponent。
     BaseFloat max_deriv; //这种非线性的最大导数。
     bool is_relu = false ;
      {
        SigmoidComponent * sc = dynamic_cast < SigmoidComponent * >(nc);
        TanhComponent * tc = dynamic_cast < TanhComponent * >(nc);
        RectifiedLinearComponent * rc = dynamic_cast < RectifiedLinearComponent * >(nc);
       if(sc!= NULL)max_deriv = 0.25;
       否则 if(tc!= NULL)max_deriv = 1.0;
       否则 if(rc!= NULL){max_deriv = 1.0; is_relu = true ; }
       否则 继续 ; //例如SoftmaxComponent; 我们不处理这个。
      }
     double  count = nc-> Count();
      Vector <double> deriv_sum(nc-> DerivSum());
     if(count == 0.0 || deriv_sum.Dim()== 0){
       KALDI_WARN << “无法修复神经网络,因为没有存储统计信息。” ;
       继续 ;
      }
      Vector <BaseFloat> bias_params(ac-> BiasParams());
      Matrix <BaseFloat> linear_params(ac-> LinearParams());
      int32 dim = nc-> InputDim(),num_small_deriv = 0,num_large_deriv = 0;
     for(int32 d = 0; d <dim; d ++){
       //派生比率是计算出的平均导数与
       //该非线性函数的最大导数。
       BaseFloat deriv_ratio = deriv_sum(d)/(count * max_deriv);
       KALDI_ASSERT(deriv_ratio> = 0.0 && deriv_ratio <1.01); //或者有一个
                                                               //错误
       //数学
       if(deriv_ratio <config.min_average_deriv){
         //衍生物太小了,这意味着我们已经进入了“扁平部分”
         // sigmoid(或ReLU,我们总是关闭)。
         if(is_relu){
            bias_params(d)+ = config.relu_bias_change;
          } else {
           BaseFloat parameter_factor = std :: min(config.min_average_deriv /
                                                  deriv_ratio,
                                                  config.parameter_factor);
           //我们需要减少参数,因此乘以1 /参数因子。
            bias_params(d)* = 1.0 / parameter_factor;
            linear_params.Row(d).Scale(1.0 / parameter_factor);
          }
          num_small_deriv ++;
        } 否则 if(deriv_ratio> config.max_average_deriv){
         //导数太大,意味着我们只是在线性部分
         // sigmoid,在中间。(或者对于ReLU,我们永远在线。
         if(is_relu){
            bias_params(d) -  = config.relu_bias_change;
          } else {
           BaseFloat parameter_factor = std :: min(deriv_ratio / config.max_average_deriv,
                                                  config.parameter_factor);
           //我们需要增加因子,所以乘以parameter_factor。
            bias_params(d)* = parameter_factor;
            linear_params.Row(d).Scale(parameter_factor);
          }
          num_large_deriv ++;
        }
      }
     if(is_relu){
       KALDI_LOG << “对于图层” << c << “(ReLU单位),增加偏见”
                  << num_small_deriv << “索引并将其减少为”
                  << num_large_deriv << “,共出” << dim;
      } else {
       KALDI_LOG << “对于图层” << c << “,参数减少”
                  << num_small_deriv << “索引,并增加它们为”
                  << num_large_deriv << “共出” << dim;
      }
      ac-> SetParams(bias_params,linear_params);
    }
  }
◆  FormatNnetInput()
void FormatNnetInput	(	const Nnet& 	nnet,
const std :: vector < NnetExample >& 	数据,
Matrix < BaseFloat > * 	垫 
)		
获取nnet的输入以获取示例的小批量,并将其格式化为单个矩阵。

data.size()必须> 0.注意:调用此函数后,您可能希望将其复制到CuMatrix。在退出时,输出的num-rows将等于(1 + nnet.LeftContext()+ nnet.RightContext())* data.size()。只需要nnet,因此我们可以在其上调用LeftContext(),RightContext()和InputDim()。

在文件nnet-update.cc的第207行定义。

引用MatrixBase <Real> :: CopyFromMat(),MatrixBase <Real> :: CopyRowsFromVec(),Nnet :: InputDim(),KALDI_ASSERT,kaldi :: kUndefined,Nnet :: LeftContext(),Matrix <Real> :: Resize( )和Nnet :: RightContext()。

由NnetUpdater :: FormatInput()和NnetExampleBackgroundReader :: ReadExamples()引用。

                                                     {
   KALDI_ASSERT(data.size()> 0);
    int32 num_splice = 1 + nnet.RightContext()+ nnet.LeftContext();
   KALDI_ASSERT(data [0] .input_frames.NumRows()> = num_splice);
   
    int32 feat_dim = data [0] .input_frames.NumCols(),
           spk_dim = data [0] .spk_info.Dim(),
           tot_dim = feat_dim + spk_dim; //我们将它们附加在神经网络上
                                        //输入...注意,spk_dim可能为0。
   KALDI_ASSERT(tot_dim == nnet.InputDim());
   KALDI_ASSERT(data [0] .left_context> = nnet.LeftContext());
    int32 ignore_frames = data [0] .left_context  -  nnet.LeftContext(); //如果
   // NnetExample有比我们需要更多的左上下文,忽略一些。
   //这可能发生在我们增加上下文量的环境中
   //训练,例如通过添加需要更多上下文的图层。  
 
    int32 num_chunks = data.size();
   
    input_mat-> Resize(num_splice * num_chunks,
                      tot_dim,kUndefined);
   
   for(int32 chunk = 0; chunk <num_chunks; chunk ++){
      SubMatrix <BaseFloat> dest(* input_mat,
                                chunk * num_splice,num_splice,
                                0,feat_dim);
 
      Matrix <BaseFloat> full_src(data [chunk] .input_frames);
      SubMatrix <BaseFloat> src(full_src,ignore_frames,num_splice,0,feat_dim);
                              
      dest.CopyFromMat(src);
     if(spk_dim!= 0){
        SubMatrix <BaseFloat> spk_dest(* input_mat,
                                      chunk * num_splice,num_splice,
                                      feat_dim,spk_dim);
        spk_dest.CopyRowsFromVec(data [chunk] .spk_info);
      }
    }
  }
◆  GenRandomNnet()
Nnet * GenRandomNnet	(	INT32 	input_dim,
INT32 	output_dim 
)		
该函数生成随机神经网络,用于测试目的。

它将包含一个随机数的SigmoidComponent,AffineComponent和SpliceComponent,然后是最终的AffineComponent和SoftmaxComponent。参数都将被随机初始化。

在文件nnet-nnet.cc的第772行定义。

引用rnnlm :: i,Nnet :: Init(),AffineComponent :: Init(),SpliceComponent :: Init()和Nnet :: Nnet()。

由UnitTestAmNnet(),UnitTestNnet(),UnitTestNnetCompute(),UnitTestNnetComputeChunked()和UnitTestNnetDecodable()引用。

                                        {
    std :: vector <Component *>组件;
    int32 cur_dim = input_dim;
   //在最后一层之前最多有10层。
   for(size_t  i = 0; i <10; i ++){
     if(rand()%2 == 0){
       //添加仿射组件。
        int32 next_dim = 50 + rand()%100;
       BaseFloat learning_rate = 0.0001,param_stddev = 0.001,
            bias_stddev = 0.1;
        AffineComponent * component = new AffineComponent();
        component-> Init(learning_rate,cur_dim,next_dim,
                        param_stddev,bias_stddev);
        components.push_back(component);
        cur_dim = next_dim;
      } 否则 if(rand()%2 == 0){
        components.push_back(new SigmoidComponent(cur_dim));
      } 否则 if(rand()%2 == 0 && cur_dim <200){
        SpliceComponent * component = new SpliceComponent();
        std :: vector <int32> context;
       而(true){
          context.clear();
         for(int32 i = -3; i <= 3; i ++){
           if(rand()%3 == 0)
              context.push_back(i);
          }
         if(!context.empty()&& context.front()<= 0 &&
              context.back()> = 0)
           休息 ;
        }
        component-> Init(cur_dim,context);
        components.push_back(component);
        cur_dim = cur_dim * context.size();
      } else {
       休息 ;
      }
    }
 
    {
      AffineComponent * component = new AffineComponent();
     BaseFloat learning_rate = 0.0001,param_stddev = 0.001,
          bias_stddev = 0.1;
      component-> Init(learning_rate,cur_dim,output_dim,
                      param_stddev,bias_stddev);
      components.push_back(component);
      cur_dim = output_dim;
    }
 
    components.push_back(new SoftmaxComponent(cur_dim));
 
    Nnet * ans = new Nnet();
    ans-> Init(&components);
   返回 ;
  }
◆  GetCount()
int32 GetCount	(	双 	expected_count	)	
在文件nnet-copy-egs-discriminative.cc的第31行定义。

引用KALDI_ASSERT和kaldi :: WithProb()。

由main()和ProcessFile()引用。

                                        {
   KALDI_ASSERT(expected_count> = 0.0);
    int32 ans = 0;
   while(expected_count> 1.0){
      ans ++;
      expected_count--;
    }
   if(WithProb(expected_count))
      ans ++;
   返回 ;
  }
◆  GetInitialModel()
static int32 kaldi :: nnet2 :: GetInitialModel	(	const std :: vector < NnetExample >& 	validation_set,
const std :: vector < Nnet >& 	nnets 
)		
静态的
返回一个整数,说明要使用的模型:0 ...

num-models - 1表示最佳单个模型,或(#models)表示所有模型的平均值。

在文件combine-nnet.cc的第49行定义。

引用CombineNnets(),ComputeNnetObjf(),KALDI_ASSERT,KALDI_LOG,rnnlm :: n和VectorBase <Real> :: Set()。

由FastNnetCombiner :: FastNnetCombiner(),FastNnetCombiner :: GetInitialParams()和GetInitialScaleParams()引用。

                                    {
    int32 minibatch_size = 1024;
    int32 num_nnets = static_cast < int32 >(nnets.size());
   KALDI_ASSERT(!nnets.empty());
   BaseFloat tot_frames = validation_set.size();
    int32 best_n = -1;
   BaseFloat best_objf = -std :: numeric_limits <BaseFloat> :: infinity();
    Vector <BaseFloat> objfs(nnets.size());
   for(int32 n = 0; n <num_nnets; n ++){
     BaseFloat objf = ComputeNnetObjf(nnets [ n ],validation_set,
                                       minibatch_size)/ tot_frames;
     
     if(n == 0 || objf> best_objf){
        best_objf = objf;
        best_n = n ;
      }
      objfs(n)= objf;
    }
   KALDI_LOG << “源神经网络的目标函数是” << objfs;
 
    int32 num_uc = nnets [0] .NumUpdatableComponents();
 
    { //现在尝试一个所有神经网具有相同权重的版本。
      Vector <BaseFloat> scale_params(num_uc * num_nnets);
      scale_params.Set(1.0 / num_nnets);
      Nnet average_nnet;
     CombineNnets(scale_params,nnets和average_nnet);
     BaseFloat objf = ComputeNnetObjf(average_nnet,validation_set,
                                       minibatch_size)/ tot_frames;
     KALDI_LOG << “平均所有神经网络的 Objf 是” << objf;
     if(objf> best_objf){
       返回 num_nnets;
      } else {
       返回 best_n;
      }
    }
  }
 GetInitialScaleParams()
static void kaldi :: nnet2 :: GetInitialScaleParams	(	const NnetCombineConfig& 	combine_config,
const std :: vector < NnetExample >& 	validation_set,
const std :: vector < Nnet >& 	nnets,
矢量 <double> * 	scale_params 
)		
静态的
在文件combine-nnet.cc的第91行定义。

引用GetInitialModel(),NnetCombineConfig :: initial_model,KALDI_ASSERT,KALDI_LOG,Vector <Real> :: Resize()和VectorBase <Real> :: Set()。

由CombineNnets()引用。

                                    {
 
    int32 initial_model = combine_config.initial_model,
        num_nnets = static_cast < int32 >(nnets.size());
   if(initial_model <0 || initial_model> num_nnets)
      initial_model = GetInitialModel(validation_set,nnets);
   
   KALDI_ASSERT(initial_model> = 0 && initial_model <= num_nnets);
    int32 num_uc = nnets [0] .NumUpdatableComponents();
 
    scale_params-> Resize(num_uc * num_nnets);
   if(initial_model <num_nnets){
     KALDI_LOG << “使用具有索引的神经网络初始化” << initial_model;
     //此时我们正在使用最好的个人神经网络。
      scale_params-> Set(0.0);
     
     //设置与“最佳”对应的参数块
     //源神经网络
      SubVector <double> best_block(* scale_params,num_uc * initial_model,num_uc);
      best_block.Set(1.0);
    } else { // initial_model == num_nnets
     KALDI_LOG << “初始化所有神经网络平均值。” ;
      scale_params-> Set(1.0 / num_nnets);
    }
  }
◆  GetNnetStats()
void GetNnetStats	(	const NnetStatsConfig& 	配置,
const Nnet& 	nnet,
std :: vector < NnetStats > * 	统计 
)		
在文件nnet-stats.cc的第99行定义。

引用NnetStatsConfig :: bucket_width,Nnet :: GetComponent(),KALDI_ASSERT,NnetStats :: NnetStats()和Nnet :: NumComponents()。

                                                 {
   KALDI_ASSERT(stats- > size()== 0);
   for(int32 c = 0; c + 1 <nnet.NumComponents(); c ++){
     const AffineComponent * ac = dynamic_cast < const AffineComponent * >(
          &(nnet.GetComponent(c)));
     if(ac == NULL)继续 ;
     const NonlinearComponent * nc = dynamic_cast < const NonlinearComponent * >(
          &(nnet.GetComponent(c + 1)));
     if(nc == NULL)继续 ;
     //排除softmax。
     const SoftmaxComponent * sc = dynamic_cast < const SoftmaxComponent * >(
          &(nnet.GetComponent(c + 1)));
     if(sc!= NULL)继续 ;
      stats-> push_back(NnetStats(c,config.bucket_width));
      stats-> back()。AddStatsFromNnet(nnet);
    }
  }
◆  GetUpdateDirection()
static void kaldi :: nnet2 :: GetUpdateDirection	(	const std :: vector < Nnet >& 	nnets,
Nnet * 	方向 
)		
静态的
在文件combine-nnet-a.cc的第31行定义。

引用Nnet :: AddNnet(),KALDI_ASSERT,rnnlm :: n,kaldi :: nnet3 :: NumUpdatableComponents(),Nnet :: ScaleComponents()和VectorBase <Real> :: Set()。

由CombineNnetsA()引用。

                                                  {
   KALDI_ASSERT(nnets.size()> 1);
    int32 num_new_nnets = nnets.size() -  1;
    Vector <BaseFloat> scales(nnets [0] .NumUpdatableComponents());
 
    scales.Set(1.0 / num_new_nnets);
   
    * direction = nnets [1];
    方向 - > ScaleComponents(尺度); //第一个新的nnets。
   for(int32 n = 2; n <1 + num_new_nnets; n ++)
      方向 - > AddNnet(scales,nnets [ n ]);
   //现在“方向”是新nnets的平均值。减去
   //旧的nnet参数。
    scale.Set(-1.0);
    direction-> AddNnet(scales,nnets [0]);
  }
◆  GiveNnetCorrectTopology()
static void kaldi :: nnet2 :: GiveNnetCorrectTopology	(	Nnet * 	nnet,
AffineComponent ** 	affine_component,
SoftmaxComponent ** 	softmax_component,
SumGroupComponent ** 	sum_group_component 
)		
静态的
此函数确保神经网络以SumGroupComponent结束。

如果没有,则添加一个(对应于每个输出元素的单个混合/矩阵。)[在此之前,它确保最后一层是SoftmaxLayer,这是我们所期望的。如果有一些用例在前一层的类型不同的情况下有意义,则可以删除此检查。

在文件mixup-nnet.cc的第37行定义。

引用Nnet :: Append(),Nnet :: GetComponent(),KALDI_ASSERT,KALDI_ERR,KALDI_LOG,Nnet :: NumComponents(),Component :: OutputDim()和Component :: Type()。

由MixupNnet()引用。

                                                                               {
    int32 nc = nnet-> NumComponents();
   KALDI_ASSERT(nc> 0);
    Component * component =&(nnet-> GetComponent(nc  -  1));
   if((* sum_group_component =
         dynamic_cast <SumGroupComponent *>(component))== NULL){
     KALDI_LOG << “将SumGroupComponent添加到神经网络中。” ;
      int32 dim = component-> OutputDim();
     //为它提供与我们拥有的第一个可更新层相同的学习率。
      std :: vector <int32> sizes(dim,1); //所有的向量,维度为“dim”。
   
      * sum_group_component = new SumGroupComponent();
      (* sum_group_component) - > Init(sizes);
      nnet-> Append(* sum_group_component);
      nc ++;
    }
    component =&(nnet-> GetComponent(nc  -  2));    
   if((* softmax_component = dynamic_cast <SoftmaxComponent *>(component))== NULL)
     KALDI_ERR << “神经网络具有错误的拓扑结构:预期倒数第二个”
                << “组件为SoftmaxComponent,类型为”
                << component-> Type();
    component =&(nnet-> GetComponent(nc  -  3));
   if((* affine_component = dynamic_cast <AffineComponent *>(component))== NULL)
     KALDI_ERR << “神经网络具有错误的拓扑结构:预期倒数第三”
                << “组件为AffineComponent,类型为”
                << component-> Type();
  }
◆  HasSimpleLabels()
bool kaldi :: nnet2 :: HasSimpleLabels	(	const NnetExample& 	例如,
std :: vector <int32> * 	simple_labels 
)		
在文件nnet-example.cc的第32行定义。

引用NnetExample :: labels。

由NnetExample :: Write()引用。

                                       {
   size_t num_frames = eg.labels.size();
   for(int32 t = 0; t <num_frames; t ++)
     if(eg.labels [t] .size()!= 1 || eg.labels [t] [0] .second!= 1.0)
       返回 false ;
    simple_labels-> resize(num_frames);
   for(int32 t = 0; t <num_frames; t ++)
      (* simple_labels)[t] = eg.labels [t] [0] .first;
   返回 true ;
  }
◆  IndexOfSoftmaxLayer()
int32 IndexOfSoftmaxLayer	(	const Nnet& 	NNET	)	
如果“nnet”只有一个softmax图层,则此函数将返回其索引; 否则它将返回-1。

在文件nnet-functions.cc的第27行定义。

引用Nnet :: GetComponent()和Nnet :: NumComponents()。

由main()引用。

                                              {
    int32 index = -1,nc = nnet.NumComponents();
   for(int32 c = 0; c <nc; c ++){
     const Component * component =&(nnet.GetComponent(c));
     if(dynamic_cast <const SoftmaxComponent *>(component)!= NULL){
       if(index!= -1)返回 -1; //> 1 softmax组件。
       否则 index = c;
      }
    }
   回报指数;
  }
◆  InsertComponents()
void InsertComponents	(	const Nnet& 	src_nnet,
INT32 	c,
Nnet * 	dest_nnet 
)		
将一个神经网络的组件插入另一个神经网络的特定位置。

这对于将隐藏层添加到神经网络非常有用。在“dest_nnet”的组件索引c之前插入“src_nnet”的组件。

在文件nnet-functions.cc的第39行定义。

引用Component :: Copy(),Nnet :: GetComponent(),Nnet :: Init(),KALDI_ASSERT和Nnet :: NumComponents()。

由main()引用。

                                         {
   KALDI_ASSERT(c_to_insert> = 0 && c_to_insert <= dest_nnet-> NumComponents());
    int32 c_tot = dest_nnet-> NumComponents()+ src_nnet.NumComponents();
    std :: vector <Component *> components(c_tot);
   for(int32 c = 0; c <c_to_insert; c ++)
      组件[c] = dest_nnet-> GetComponent(c).Copy();
   for(int32 c = 0; c <src_nnet.NumComponents(); c ++)
      组件[c + c_to_insert] = src_nnet.GetComponent(c).Copy();
   for(int32 c = c_to_insert; c <dest_nnet-> NumComponents(); c ++)
      组件[c + src_nnet.NumComponents()] = dest_nnet-> GetComponent(c).Copy();
   //从结果的组件列表中重新初始化“dest_nnet”。
 
   // Init方法将获取向量中指针的所有权:
    dest_nnet-> Init(&components);
  }
◆  KlDivergence()
BaseFloat kaldi :: nnet2 :: KlDivergence	(	const Vector < BaseFloat >& 	p,
const Vector < BaseFloat >& 	q 
)		
在文件nnet-adjust-priors.cc的第31行定义。

引用VectorBase <Real> :: Dim(),rnnlm :: i,KALDI_ASSERT,KALDI_WARN,kaldi :: Log()和VectorBase <Real> :: Sum()。

由PrintPriorDiagnostics()引用。

                                                     {
   BaseFloat sum_p = p。Sum(),sum_q = q。Sum();
   if(fabs(sum_p  -  1.0)> 0.01 || fabs(sum_q  -  1.0)> 0.01){
     KALDI_WARN << “KlDivergence:向量不接近正常化”
                 << sum_p << “,” << sum_q;
    }
   KALDI_ASSERT(第暗淡()== Q值。暗淡());
   double ans = 0.0;
 
   for(int32 i = 0; i < p.Dim(); i ++){
     BaseFloat p_prob = p(i)/ sum_p,q_prob = q(i)/ sum_q;
      ans + = p_prob * Log(p_prob / q_prob);
    }
   返回 ;
  }
◆  LatticeToDiscriminativeExample()
bool LatticeToDiscriminativeExample	(	const std :: vector <int32>& 	对齐,
const Matrix < BaseFloat >& 	壮举,
const CompactLattice& 	CLAT,
BaseFloat 	重量,
INT32 	left_context,
INT32 	right_context,
DiscriminativeNnetExample * 	例如 
)		
将格子转换为判别训练的例子。

成功时返回true,输入不匹配时返回false(在这种情况下也会发出警告)。

在文件nnet-example-functions.cc的第27行定义。

引用DiscriminativeNnetExample :: Check(),kaldi :: CompactLatticeStateTimes(),DiscriminativeNnetExample :: den_lat,DiscriminativeNnetExample :: input_frames,KALDI_ASSERT,KALDI_WARN,DiscriminativeNnetExample :: left_context,DiscriminativeNnetExample :: num_ali,MatrixBase <Real> :: NumCols(),MatrixBase <Real> :: NumRows(),MatrixBase <Real> :: Range(),Matrix <Real> :: Resize(),MatrixBase <Real> :: Row()和DiscriminativeNnetExample :: weight。

由main()和SplitExampleStats :: SplitExampleStats()引用。

                                     {
   KALDI_ASSERT(left_context> = 0 && right_context> = 0);
    int32 num_frames = alignment.size();
   if(num_frames == 0){
     KALDI_WARN << “空对齐” ;
     返回 false ;
    }
   if(num_frames!= feats.NumRows()){
     KALDI_WARN << “尺寸不匹配:对齐” << num_frames
                 << “与壮举” <<壮举。NumRows();
     返回 false ;
    }
    std :: vector <int32>次;
    int32 num_frames_clat = CompactLatticeStateTimes(clat,&times);  
   if(num_frames_clat!= num_frames){
     KALDI_WARN << “分子/帧与denlat帧不匹配:”
                 << num_frames << “与” << num_frames_clat;
     返回 false ;
    }
    eg-> weight = weight;
    eg-> num_ali = alignment;
    eg-> den_lat = clat;
 
    int32 feat_dim = feats。NumCols();
    eg-> input_frames.Resize(left_context + num_frames + right_context,
                            feat_dim);
    eg-> input_frames.Range(left_context,num_frames,
                           0,feat_dim).CopyFromMat(feats);
 
   //复制第一帧和最后一帧。
   for(int32 t = 0; t <left_context; t ++)
      EG-> input_frames.Row(t)的.CopyFromVec(技艺。行(0));
   for(int32 t = 0; t <right_context; t ++)
      eg-> input_frames.Row(left_context + num_frames + t).CopyFromVec(
          壮举。Row(num_frames  -  1));
 
    eg-> left_context = left_context;
    eg-> Check();
   返回 true ;
  }
◆  LimitRankParallel()
void LimitRankParallel	(	const NnetLimitRankOpts& 	选择,
Nnet * 	NNET 
)		
该函数通过将最小的奇异值归零来限制神经网络中每个仿射变换的等级。

将零输出的奇异值的数量逐层确定,使用“parameter_proportion”来设置要移除的参数的比例。

在文件nnet-limit-rank.cc的第99行定义。

引用Nnet :: GetComponent(),NnetLimitRankOpts :: num_threads,TaskSequencerConfig :: num_threads,Nnet :: NumComponents()和TaskSequencer <C> :: Run()。

由NnetLimitRankOpts :: Register()引用。

                                          {
    TaskSequencerConfig task_config;
    task_config.num_threads = opts.num_threads;
    TaskSequencer <LimitRankClass> tc(task_config);
   for(int32 c = 0; c <nnet-> NumComponents(); c ++){
     if(dynamic_cast <AffineComponent *>(&(nnet-> GetComponent(c)))!= NULL)
        tc.Run(new LimitRankClass(opts,c,nnet));
    }
  }
◆  MakePair()
static Int32Pair kaldi :: nnet2 :: MakePair	(	INT32 	首先,
INT32 	第二 
)		
内联静态
在文件train-nnet-ensemble.cc的第27行定义。

引用Int32Pair :: first和Int32Pair :: second。

由NnetEnsembleTrainer引用:: TrainOneMinibatch()。

                                                              {
   Int32Pair ans;
    ans。第一个 =第一个
    ans。第二 =第二;
   返回 ;
  }
◆  MixupNnet()
void MixupNnet	(	const NnetMixupConfig& 	mixup_config,
Nnet * 	NNET 
)		
此功能的工作原理如下。

除了应用于神经网络的输出层之外,该函数类似于GMM的高斯混合分裂。

我们首先确保神经网络具有正确的拓扑,因此它的最后一个组件是SumGroupComponent。

然后我们得到SumGroupComponent中每个矩阵的计数(如果我们有一个2级树系统,它们将对应于决策树中的叶子,或者对应于1级叶子)。我们通过从SoftmaxComponent获取计数来计算每个矩阵的总计数。

然后,我们增加,如果必要的话,该尺寸的SumGroupComponent金额超过增加的尺寸SoftmaxComponent如果必要,重复,然后扰乱的相关行AffineComponent。

我们创建了额外的输出,这些输出将使用SumGroupComponent进行求和。

在文件mixup-nnet.cc的第86行定义。

引用Nnet :: Check(),GiveNnetCorrectTopology(),NnetMixupConfig :: min_count,SoftmaxComponent :: MixUp(),NnetMixupConfig :: num_mixtures,NnetMixupConfig :: perturb_stddev和NnetMixupConfig :: power。

由main()和NnetMixupConfig :: Register()引用。

                             {
    AffineComponent * affine_component = NULL;
    SoftmaxComponent * softmax_component = NULL;
    实实交件实实交似交件实实交件实交件实实实交件实交交似实交件实交件实交件实交交实交件件实实件实实实件实件件实实交实交件件似件件实件交件实实实件实似交件实似交实实件交件实件实件交件实实件件似实交件实似实件实交交件件实件似件实实件件实件实件实件实交件件
   GiveNnetCorrectTopology(nnet,
                            &affine_component,
                            &softmax_component,
                            &sum_group_component); 交交交交交实交实交件实实实件交件件交交交实交实件件实实实件交件实实件件实件件实件实件件交交交实似件实实似件交实实交件实件实件件实实件实实实实实件似件件件实件交实件件件实交交实交件实实实件实实件件实件件实实件实件似件实件件件实件实似件交件实件实实实实实实似件实件交件实件交件实件实实件件件实交交实实实件实件件交实件
   
    softmax_component-> MixUp(mixup_config.num_mixtures,
                             mixup_config.power,
                             mixup_config.min_count,
                             mixup_config.perturb_stddev,
                             affine_component,
                             sum_group_component);
    nnet-> Check(); //检查尺寸是否匹配。
  }
◆  NnetComputation()
void NnetComputation	(	const Nnet& 	nnet,
const CuMatrixBase < BaseFloat >& 	输入,
布尔 	pad_input,
CuMatrixBase < BaseFloat > * 	产量 
)		
对数据序列进行基本神经网络计算(例如:

一个话语)。如果pad_input == true,我们将用足够的上下文帧填充输入,输出将是网络输出dim的#frames矩阵,通常代表州级后验。如果pad_input == false,我们将不会这样做,输出的#frames将低于输入; 我们在左边输了nnet.LeftContext(),在输出输了nnet.RightContext()。

在文件nnet-compute.cc的第160行定义。

引用CuMatrixBase <Real> :: CopyFromMat(),NnetComputer :: GetOutput()和NnetComputer :: Propagate()。

引用NnetComputation :: Clear(),CachingOptimizingCompiler :: CompileNoShortcut(),CachingOptimizingCompiler :: CompileViaShortcut(),DecodableAmNnetParallel :: Compute(),DecodableNnet2Online :: ComputeForFrame(),DecodableAmNnet :: DecodableAmNnet(),main(),ComputationCache: :Read(),UnitTestNnetCompute()和UnitTestNnetComputeChunked()。

                                                        {
    NnetComputer nnet_computer(nnet,input,pad_input,NULL);
    nnet_computer.Propagate();
    output-> CopyFromMat(nnet_computer.GetOutput());
  }
◆  NnetComputationChunked()
void NnetComputationChunked	(	const Nnet& 	nnet,
const Matrix < BaseFloat >& 	输入,
INT32 	chunk_size,
Matrix < BaseFloat > * 	产量 
)		
对数据序列进行基本神经网络计算(例如:

一个话语)。NnetComputation的这种变体根据chunk_size对输入进行分块,并按块进行后验计算。这允许在输入矩阵非常大时在GPU上执行计算。使用足够的上下文帧填充输入,以便输出将是带有input.NumRows()的矩阵。

在文件nnet-compute.cc的第169行定义。

引用MatrixBase <Real> :: CopyFromMat(),NnetComputer :: GetOutput(),rnnlm :: i,Nnet :: LeftContext(),MatrixBase <Real> :: NumCols(),MatrixBase <Real> :: NumRows(),NnetComputer :: Propagate(),MatrixBase <Real> :: Range(),Matrix <Real> :: Resize(),Nnet :: RightContext()和MatrixBase <Real> :: Row()。

由main()和UnitTestNnetComputeChunked()引用。

                                                  {
    int32 num_rows,
         num_chunks = ceil((BaseFloat)输入.NumRows()/ chunk_size),
         dim =输入。NumCols(),
         left_context = nnet.LeftContext(),
         right_context = nnet.RightContext();
    Matrix <BaseFloat> full_input;
    num_rows = left_context +输入。NumRows()+ right_context ;
    full_input.Resize(num_rows,dim);
    full_input.Range(left_context,input.NumRows(),
              0,昏暗).CopyFromMat(输入);
   for(int32 i = 0; i <left_context; i ++)
      full_input.Row(我).CopyFromVec(输入。行(0));
    int32 last_row =输入。NumRows() -  1;
   for(int32 i = 0; i <right_context; i ++)
      full_input.Row(NUM_ROWS - 我 - 1).CopyFromVec(输入。行(LAST_ROW));
 
   for(int32 i = 0; i <num_chunks; i ++){
      int32 index = i * chunk_size,
            offset = std :: min(num_rows  -  chunk_size * i,
                              left_context + chunk_size + right_context);
      SubMatrix <BaseFloat> chunk_input(full_input,index,offset,0,dim);
      CuMatrix <BaseFloat> cu_chunk_input(chunk_input);
 
     //注意:我们已经考虑了输入填充,所以我们通过了
     // pad_input == false到NnetComputer。
      NnetComputer nnet_computer(nnet,cu_chunk_input,false,NULL);
      nnet_computer.Propagate();
      CuMatrix <BaseFloat> cu_chunk_output(nnet_computer.GetOutput());
      SubMatrix <BaseFloat> chunk_out(* output,i * chunk_size,
                             cu_chunk_output.NumRows(),0,
                             cu_chunk_output.NumCols());
      chunk_out.CopyFromMat(cu_chunk_output);
    }
  }
◆  NnetDiscriminativeUpdate()
void NnetDiscriminativeUpdate	(	const AmNnet& 	am_nnet,
const TransitionModel& 	tmodel,
const NnetDiscriminativeUpdateOptions& 	选择,
const DiscriminativeNnetExample& 	例如,
Nnet * 	nnet_to_update,
NnetDiscriminativeStats * 	统计 
)		
对于MMI,MPFE或SMBR目标函数,神经网络计算,网格前向后向和后向推进。

如果nnet_to_update ==&(am_nnet.GetNnet()),则执行随机梯度下降,否则(假设您在* nnet_to_update上调用了SetZero(true)),它将计算此数据的梯度。如果nnet_to_update_ == NULL,则不进行反向传播。

注意:我们忽略“eg”晶格中任何现有的声学分数。

出于显示目的,您应该将此返回值的总和除以示例中的总和,以及帧数(num_ali.size())乘以权重。

你需要注意的是,占领计数和衍生物遵循传统,缺少一个等于声学尺度的因子。因此,如果您计划执行L-BFGS之类的操作,您需要将它们乘以该比例,其中您可以查看导数和函数值。

在文件nnet-compute-discriminative.cc的第365行定义。

引用NnetDiscriminativeUpdater :: Update()。

由main(),NnetDiscriminativeStats :: NnetDiscriminativeStats()和DiscTrainParallelClass :: operator()()引用。

                                                                {
    NnetDiscriminativeUpdater更新程序(am_nnet,tmodel,opts,例如,
                                      nnet_to_update,stats);
    updater.Update();
  }
◆  NnetDiscriminativeUpdateParallel()
void NnetDiscriminativeUpdateParallel	(	const AmNnet& 	am_nnet,
const TransitionModel& 	tmodel,
const NnetDiscriminativeUpdateOptions& 	选择,
INT32 	num_threads,
SequentialDiscriminativeNnetExampleReader * 	example_reader,
Nnet * 	nnet_to_update,
NnetDiscriminativeStats * 	统计 
)		
在文件nnet-compute-discriminative-parallel.cc的第189行定义。

引用DiscriminativeExamplesRepository :: AcceptExample(),NnetDiscriminativeUpdateOptions :: criterion,SequentialTableReader <Holder> :: Done(),DiscriminativeExamplesRepository :: ExamplesDone(),AmNnet :: GetNnet(),SequentialTableReader <Holder> :: Next(),NnetDiscriminativeStats :: Print()和SequentialTableReader <Holder> :: Value()。

由main()引用。

                                      {
 
    DiscriminativeExamplesRepository存储库;
 
   const  bool store_separate_gradients =(nnet_to_update!=&(am_nnet.GetNnet()));
 
    DiscTrainParallelClass c(am_nnet,tmodel,opts,
                             store_separate_gradients,
                             &repository,nnet_to_update,stats);
 
    {
     //以下类的初始化产生了那些线程
     //处理示例。他们在析构函数中重新加入。
      MultiThreader <DiscTrainParallelClass> m(num_threads,c);
 
     for(;!example_reader-> Done(); example_reader-> Next()){
        repository.AcceptExample(example_reader-> Value());
      }
      repository.ExamplesDone();
    }
    stats-> Print(opts.criterion);
  }
◆  NnetGradientComputation() [1/2]
BaseFloat kaldi :: nnet2 :: NnetGradientComputation	(	const Nnet& 	nnet,
const MatrixBase < BaseFloat >& 	输入,
布尔 	pad_input,
BaseFloat 	utterance_weight,
const std :: vector <int32>& 	标签,
Nnet * 	nnet_to_update 
)		
神经网络计算和backprop,给定输入和标签。

注意:如果pad_input == true,则输入的行数应与标签数相同,如果为false,则应省略左侧的nnet.LeftContext()标签和右侧的nnet.RightContext()。如果nnet_to_update ==&nnet,则执行随机梯度下降,否则(假设您在* nnet_to_update上调用了SetZero(true)),它将计算此数据的梯度。返回在帧上求和的总目标函数乘以话语权重。

◆  NnetGradientComputation() [2/2]
BaseFloat kaldi :: nnet2 :: NnetGradientComputation	(	const Nnet& 	nnet,
const CuMatrixBase < BaseFloat >& 	输入,
布尔 	pad_input,
const 后部& 	pdf_post,
Nnet * 	nnet_to_update 
)		
在文件nnet-compute.cc的第208行定义。

引用NnetComputer :: Backprop(),NnetComputer :: ComputeLastLayerDeriv()和NnetComputer :: Propagate()。

                                                          {
    NnetComputer nnet_computer(nnet,input,pad_input,nnet_to_update);
    nnet_computer.Propagate();
    CuMatrix <BaseFloat>衍生物;
   BaseFloat ans;
    ans = nnet_computer.ComputeLastLayerDeriv(pdf_post,&deriv);  
    nnet_computer.Backprop(&deriv);
   返回 ;
  }
◆  ParseFromString() [1/5]
bool ParseFromString	(	const std :: string& 	名字,
std :: string * 	字符串,
int32 * 	PARAM 
)		
Init例程中使用的函数。

假设name ==“foo”,如果“string”有一个类似foo = 12的字段,则此函数将“param”设置为12并从“string”中删除该元素。如果读取参数,则返回true。

在文件nnet-component.cc的第153行定义。

引用kaldi :: ConvertStringToInteger(),rnnlm :: i,rnnlm :: j,KALDI_ERR和kaldi :: SplitStringToVector()。

引用于NonlinearComponent :: InitFromString(),MaxoutComponent :: InitFromString(),MaxpoolingComponent :: InitFromString(),PnormComponent :: InitFromString(),PowerComponent :: InitFromString(),ScaleComponent :: InitFromString(),AffineComponent :: InitFromString(),AffineComponentPreconditioned :: InitFromString(),AffineComponentPreconditionedOnline :: InitFromString(),SpliceComponent :: InitFromString(),SpliceMaxComponent :: InitFromString(),BlockAffineComponent :: InitFromString(),BlockAffineComponentPreconditioned :: InitFromString(),SumGroupComponent :: InitFromString(),PermuteComponent :: InitFromString(),DctComponent :: InitFromString(),FixedLinearComponent :: InitFromString(),FixedAffineComponent :: InitFromString(),FixedScaleComponent :: InitFromString(),FixedBiasComponent :: InitFromString(),DropoutComponent :: InitFromString(),AdditiveNoiseComponent :: InitFromString(),Convolutional1dComponent :: InitFromString()和UnitTestParsing()。

                                     {
    std :: vector <std :: string> split_string;
   SplitStringToVector(* string,“\ t”,true,
                        &split_string);
    std :: string name_equals = name + “=” ; //名称,然后是等号。
   size_t len = name_equals.length();
 
   for(size_t  i = 0; i <split_string.size(); i ++){
     if(split_string [ i ] .compare(0,len,name_equals)== 0){
       if(!ConvertStringToInteger(split_string [ i ] .substr(len),param))
         KALDI_ERR << “坏选项” << split_string [ i ];
        * string = “” ;
       //将“string”设置为我们使用的所有部分。
       for(size_t  j = 0; j <split_string.size(); j ++){
         if(j!= i){
           if(!string-> empty())* string + = “” ;
            * string + = split_string [ j ];
          }
        }
       返回 true ;
      }
    }
   返回 false ;
  }
◆  ParseFromString() [2/5]
bool ParseFromString	(	const std :: string& 	名字,
std :: string * 	字符串,
布尔 * 	PARAM 
)		
此版本适用于bool类型的参数,它可以显示为以f,F,t或T开头的任何字符串。

在文件nnet-component.cc的第179行定义。

引用rnnlm :: i,rnnlm :: j,KALDI_ERR和kaldi :: SplitStringToVector()。

                                    {
    std :: vector <std :: string> split_string;
   SplitStringToVector(* string,“\ t”,true,
                        &split_string);
    std :: string name_equals = name + “=” ; //名称,然后是等号。
   size_t len = name_equals.length();
 
   for(size_t  i = 0; i <split_string.size(); i ++){
     if(split_string [ i ] .compare(0,len,name_equals)== 0){
        std :: string b = split_string [ i ] .substr(len);
       if(b.empty())
         KALDI_ERR << “错误选项” << split_string [ i ];
       if(b [0] == 'f' || b [0] == 'F')* param = false ;
       else  if(b [0] == 't' || b [0] == 'T')* param = true ;
       其他
         KALDI_ERR << “坏选项” << split_string [ i ];
        * string = “” ;
       //将“字符串”设置为所有部分,但是我们使用的部分。
       for(size_t  j = 0; j <split_string.size(); j ++){
         if(j!= i){
           if(!string-> empty())* string + = “” ;
            * string + = split_string [ j ];
          }
        }
       返回 true ;
      }
    }
   返回 false ;
  }
◆  ParseFromString() [3/5]
bool ParseFromString	(	const std :: string& 	名字,
std :: string * 	字符串,
BaseFloat * 	PARAM 
)		
此版本适用于BaseFloat类型的参数。

在文件nnet-component.cc的第210行定义。

引用kaldi :: ConvertStringToReal(),rnnlm :: i,rnnlm :: j,KALDI_ERR和kaldi :: SplitStringToVector()。

                                         {
    std :: vector <std :: string> split_string;
   SplitStringToVector(* string,“\ t”,true,
                        &split_string);
    std :: string name_equals = name + “=” ; //名称,然后是等号。
   size_t len = name_equals.length();
 
   for(size_t  i = 0; i <split_string.size(); i ++){
     if(split_string [ i ] .compare(0,len,name_equals)== 0){
       if(!ConvertStringToReal(split_string [ i ] .substr(len),param))
         KALDI_ERR << “坏选项” << split_string [ i ];
        * string = “” ;
       //将“string”设置为我们使用的所有部分。
       for(size_t  j = 0; j <split_string.size(); j ++){
         if(j!= i){
           if(!string-> empty())* string + = “” ;
            * string + = split_string [ j ];
          }
        }
       返回 true ;
      }
    }
   返回 false ;
  }
◆  ParseFromString() [4/5]
bool kaldi :: nnet2 :: ParseFromString	(	const std :: string& 	名字,
std :: string * 	字符串,
std :: string * 	PARAM 
)		
在文件nnet-component.cc的第236行定义。

引用rnnlm :: i,rnnlm :: j和kaldi :: SplitStringToVector()。

                                         {
    std :: vector <std :: string> split_string;
   SplitStringToVector(* string,“\ t”,true,
                        &split_string);
    std :: string name_equals = name + “=” ; //名称,然后是等号。
   size_t len = name_equals.length();
 
   for(size_t  i = 0; i <split_string.size(); i ++){
     if(split_string [ i ] .compare(0,len,name_equals)== 0){
        * param = split_string [ i ] .substr(len);
 
       //将“string”设置为我们使用的所有部分。
        * string = “” ;
       for(size_t  j = 0; j <split_string.size(); j ++){
         if(j!= i){
           if(!string-> empty())* string + = “” ;
            * string + = split_string [ j ];
          }
        }
       返回 true ;
      }
    }
   返回 false ;
  }
◆  ParseFromString() [5/5]
bool ParseFromString	(	const std :: string& 	名字,
std :: string * 	字符串,
std :: vector <int32> * 	PARAM 
)		
此版本适用于std :: vector <int32>类型的参数; 它希望它们是一个以冒号分隔的列表,没有空格。

在文件nnet-component.cc的第262行定义。

引用rnnlm :: i,rnnlm :: j,KALDI_ERR,kaldi :: SplitStringToIntegers()和kaldi :: SplitStringToVector()。

                                                {
    std :: vector <std :: string> split_string;
   SplitStringToVector(* string,“\ t”,true,
                        &split_string);
    std :: string name_equals = name + “=” ; //名称,然后是等号。
   size_t len = name_equals.length();
 
   for(size_t  i = 0; i <split_string.size(); i ++){
     if(split_string [ i ] .compare(0,len,name_equals)== 0){
       if(!SplitStringToIntegers(split_string [ i ] .substr(len),“:”,
                                  false,param))
         KALDI_ERR << “错误选项” << split_string [ i ];
        * string = “” ;
       //将“string”设置为我们使用的所有部分。
       for(size_t  j = 0; j <split_string.size(); j ++){
         if(j!= i){
           if(!string-> empty())* string + = “” ;
            * string + = split_string [ j ];
          }
        }
       返回 true ;
      }
    }
   返回 false ;
  }
◆  PreconditionDirections()
void PreconditionDirections	(	const CuMatrixBase < BaseFloat >& 	R,
双 	lambda,
CuMatrixBase < BaseFloat > * 	P 
)		
请参阅下面的评论。

函数PreconditionDirections将输入R视为一组方向或渐变,每行r_i是方向之一。

对于每个i,它使用以下公式构造由* other * i形成的预处理矩阵G_i:

G_i =(I +(1 /(N-1)){ji} r_j r_j ^ T)^ { - 1},

其中N是R中的行数。这可以看作是一种估计的Fisher矩阵,它已经用身份进行平滑以使其可逆。我们建议您使用:= /(ND)trace(R ^ T,R)设置一些小的,例如= 0.1。但是,我们将此留给调用者,因为有一些原因导致随机梯度下降的无偏差,为什么您可能想要使用“其他”数据进行设置,例如之前的小批量数据。

该函数的输出是矩阵P,其每一行的p_i与r_i相关:p_i = G_i r_i这里,p_i由估计的Fisher矩阵预处理,使得它适合用作更新方向。

在文件nnet-precondition.cc的第26行定义。

引用CuVectorBase <Real> :: AddDiagMatMat(),CuMatrixBase <Real> :: AddMatMat(),CuMatrixBase <Real> :: AddToDiag(),CuMatrixBase <Real> :: CopyFromMat(),CuMatrixBase <Real> :: CopyLowerToUpper(),kaldi :: GetVerboseLevel(),KALDI_ASSERT,KALDI_ERR,KALDI_WARN,kaldi :: kNoTrans,kaldi :: kTakeLower,kaldi :: kTrans,kaldi :: kUndefined,CuMatrixBase <Real> :: MulRowsVec(),rnnlm :: n,CuMatrixBase <Real> :: NumCols(),CuMatrixBase <Real> :: NumRows(),SpMatrix <Real> :: PrintEigs(),kaldi :: Rand(),kaldi :: SameDim(),CuVectorBase <Real> :: Scale(),CuMatrixBase <Real> :: SymAddMat2(),CuMatrixBase <Real> :: SymInvertPosDef()和kaldi :: VecVec()。

由PreconditionDirectionsAlpha(),PreconditionDirectionsAlphaRescaled()和UnitTestPreconditionDirections()引用。

                                                          {
   
    int32 N = R.NumRows(),D = R.NumCols();
   KALDI_ASSERT(SameDim(R,* P)&& N> 0);
   if(N == 1){
     KALDI_WARN << “试图预先设置一组帧:返回”
                 << “不变。如果不经常,请忽略此警告。” ;
      P-> CopyFromMat(R);
     回归 ;
    }
    CuMatrixBase <BaseFloat>&Q = * P;
   
   if(N> = D){
     //通过直接反演计算G =(\ lambda I + 1 /(N-1)R ^ TR)^ { -  1}。
     // G < -  lambda I.
      CuMatrix <BaseFloat> G(D,D);
      G.AddToDiag(lambda);
     // G + = 1.0 /(N-1)* R ^ T R.
      G.SymAddMat2(1.0 /(N-1),R,kTrans,1.0);
      G.CopyLowerToUpper();
     if(GetVerboseLevel()> = 5 && Rand()%20 == 0){
        CuSpMatrix <BaseFloat> tmp(G,kTakeLower);
        SpMatrix <BaseFloat> G_cpu(tmp);
        G_cpu.PrintEigs(“G”);
      }
      G.SymInvertPosDef();
     // Q < -  RG ^ T(我们只是按照我们的想法进行调换
     //它会稍快一点; 它是对称的)。
      Q.AddMatMat(1.0,R,kNoTrans,G,kTrans,0.0);
    } else {
     //经过大量的重新安排,结果证明了这一点
     //如果我们让S =(\ lambda I + 1 /(N-1)RR ^ T)^ { -  1}
     //那么我们需要的是什么
     // Q < -  S R.
     //奇怪的是(对我而言)意外的是实际的代码基本上是
     //换位时相同
      CuMatrix <BaseFloat> S(N,N);
     // S < -  lambda I.
      S.AddToDiag(lambda);
     // S + =(N-1)RR ^ T.
     //以下函数仅更新下三角形。
      S.SymAddMat2(1.0 /(N-1),R,kNoTrans,1.0);
      S.CopyLowerToUpper();
     //反转S,所以现在S =(\ lambda I +(N-1)RR ^ T)^ { -  1}。
     if(GetVerboseLevel()> = 5 && Rand()%20 == 0){
        CuSpMatrix <BaseFloat> tmp(S,kTakeLower);
        SpMatrix <BaseFloat> S_cpu(tmp);
        S_cpu.PrintEigs(“S”);
      }
      S.SymInvertPosDef();
      Q.AddMatMat(1.0,S,kNoTrans,R,kNoTrans,0.0);
    }
 
 #if 0 //为CUDA优化之前的旧代码:
   for(int32 n = 0; n <N; n ++){
      CuSubVector <BaseFloat> r(R,n),q(Q,n);
     BaseFloat gamma = VecVec(r,q),// gamma_n = r_n ^ T q_n。
                 beta = 1 + gamma /(N  -  1  -  gamma);
     if(!(gamma> = 0.0 && beta> 0.0)){
       KALDI_ERR << “预处理中遇到的错误值:gamma =” << gamma
                  << “,beta =” << beta;
      }
     // Q和P共享相同的内存。结果
     //以下缩放将输出为P.
      q.Scale(beta);
    }
 #else
    CuVector <BaseFloat> gamma(N);
    gamma.AddDiagMatMat(1.0,R,kNoTrans,Q,kTrans,0.0);
   //此时,gamma(i)等于R的第i行
   //第一行Q.
    Vector <BaseFloat> cpu_gamma(gamma),cpu_beta(N,kUndefined);
   for(int32 n = 0; n <N; n ++){
     BaseFloat this_gamma = cpu_gamma(n),
          this_beta = 1.0 + this_gamma /(N  -  1  -  this_gamma);
     if(!(this_gamma> = 0.0 && this_beta> 0.0))
       KALDI_ERR << “预处理中遇到的错误值:gamma =”
                  << this_gamma << “,beta =” << this_beta;
      cpu_beta(n)= this_beta;
    }
    CuVector <BaseFloat> beta(cpu_beta);
    P-> MulRowsVec(beta);
 #endif
  }
PreconditionDirectionsAlpha()
void PreconditionDirectionsAlpha	(	const CuMatrixBase < BaseFloat >& 	R,
双 	阿尔法,
CuMatrixBase < BaseFloat > * 	P 
)		
PreconditionDirections的这个包装器使用= /(ND)trace(R ^ T,R)计算lambda,并调用PreconditionDirections。

在文件nnet-precondition.cc的第114行定义。

引用KALDI_ASSERT,KALDI_WARN,kaldi :: kTrans,CuMatrixBase <Real> :: NumCols(),CuMatrixBase <Real> :: NumRows(),PreconditionDirections()和kaldi :: TraceMatMat()。

                                  {
   KALDI_ASSERT(alpha> 0.0);
   //可能没有意义。
   double t = TraceMatMat(R,R,kTrans),floor = 1.0e-20;
   if(t <floor){
     KALDI_WARN << “地板痕迹” << t
                 << “to” << floor;
      t =楼层;
    }
   double lambda = t * alpha / R.NumRows()/ R.NumCols();
   //请参阅下面的扩展评论,以获得对此的解释。
   if(lambda <= 0.0){
     //这应该永远不会发生,它可能表示一个错误
     //在调用代码中。
     KALDI_WARN << “PreconditionDirectionsAlpha中的零或负lambda。” ;
      lambda = 1.0e-10;
    }
   PreconditionDirections(R,lambda,P);
  }
◆  PreconditionDirectionsAlphaRescaled()
void PreconditionDirectionsAlphaRescaled	(	const CuMatrixBase < BaseFloat >& 	R,
双 	阿尔法,
CuMatrixBase < BaseFloat > * 	P 
)		
PreconditionDirections的这个包装器使用= /(ND)trace(R ^ T,R)计算lambda,并调用PreconditionDirections。

然后重新调整* P,使其2范数与R的范数相同。

在文件nnet-precondition.cc的第138行定义。

引用CuMatrixBase <Real> :: CopyFromMat(),KALDI_ASSERT,KALDI_WARN,kaldi :: kTrans,CuMatrixBase <Real> :: NumCols(),CuMatrixBase <Real> :: NumRows(),PreconditionDirections(),CuMatrixBase <Real> :: Scale()和kaldi :: TraceMatMat()。

由AffineComponentPreconditioned :: Update()和BlockAffineComponentPreconditioned :: Update()引用。

                                  {
   KALDI_ASSERT(alpha> 0.0); // alpha> 1.0
   //可能没有意义。
   双 t = TraceMatMat(R,R,kTrans),floor = 1.0e-20;
   if(t == 0.0){
      P-> CopyFromMat(R);
     回归 ;
    }
   if(t <floor){
     KALDI_WARN << “地板痕迹” << t
                 << “to” << floor;
      t =楼层;
    }
   double lambda = t * alpha / R.NumRows()/ R.NumCols();
   //请参阅下面的扩展评论,以获得对此的解释。
   KALDI_ASSERT(lambda!= 0.0);
   PreconditionDirections(R,lambda,P);
   double p_trace = TraceMatMat(* P,* P,kTrans),
        rescale = sqrt(t / p_trace);
   KALDI_ASSERT(p_trace!= 0.0);
    P->比例(重新缩放);
  }
◆  PrintPriorDiagnostics()
void kaldi :: nnet2 :: PrintPriorDiagnostics	(	const Vector < BaseFloat >& 	old_priors,
const Vector < BaseFloat >& 	new_priors 
)		
在文件nnet-adjust-priors.cc的第48行定义。

引用VectorBase <Real> :: AddVec(),VectorBase <Real> :: ApplyAbs(),VectorBase <Real> :: Dim(),KALDI_LOG,KlDivergence()和VectorBase <Real> :: Max()。

由main()引用。

                                                                  {
   如果(old_priors。暗淡()== 0){
     KALDI_LOG << “模型以前没有附加先验。” ;
    } else {
     Vector <BaseFloat> diff_prior(new_priors);
      diff_prior.AddVec(-1.0,old_priors);
      diff_prior.ApplyAbs();
      int32 max_index;
      diff_prior.Max(&max_index);
     KALDI_LOG << “调整先验:最大的绝对差异是”
                << “pdf” << max_index << “,” << old_priors(max_index)
                << “ - >” << new_priors(max_index);
     KALDI_LOG << “调整先验:KL从旧到新的分歧是”
                << KlDivergence(old_priors,new_priors);
    }
  }
◆  ProcessFile() [1/2]
static void kaldi :: nnet2 :: ProcessFile	(	const MatrixBase < BaseFloat >& 	壮举,
const 后部& 	pdf_post,
const std :: string& 	utt_id,
INT32 	left_context,
INT32 	right_context,
INT32 	num_frames,
INT32 	const_feat_dim,
int64 * 	num_frames_written,
int64 * 	num_egs_written,
NnetExampleWriter * 	example_writer 
)		
静态的
在文件nnet-get-egs.cc的第32行定义。

引用NnetExample :: input_frames,rnnlm :: j,KALDI_ASSERT,NnetExample :: labels,NnetExample :: left_context,MatrixBase <Real> :: NumCols(),MatrixBase <Real> :: NumRows(),MatrixBase <Real> :: Row (),NnetExample :: spk_info和TableWriter <Holder> :: Write()。

由main()引用。

                                                             {
   KALDI_ASSERT(专辑.NumRows()== static_cast < int32 >(pdf_post.size()));
    int32 feat_dim = feats。NumCols();
   KALDI_ASSERT(const_feat_dim <feat_dim);
   KALDI_ASSERT(num_frames> 0);
    int32 basic_feat_dim = feat_dim  -  const_feat_dim;
 
   for(int32 t = 0; t < feats.NumRows(); t + = num_frames){
      int32 this_num_frames = std :: min(num_frames,
                                       壮举。NumRows() -  t);
 
      int32 tot_frames = left_context + this_num_frames + right_context;
     Nnet例如:
     Matrix <BaseFloat> input_frames(tot_frames,basic_feat_dim);
      例如。left_context = left_context;
      例如。spk_info .Resize(const_feat_dim);
 
     //设置“input_frames”。
     for(int32 j = -left_context; j <this_num_frames + right_context; j ++){
        int32 t2 = j + t;
       if(t2 <0)t2 = 0;
       if(t2> = feats.NumRows())t2 =专长。NumRows() -  1;
       SubVector <BaseFloat> src(专长。行(t2),0,basic_feat_dim),
            dest(input_frames,j + left_context);
        dest.CopyFromVec(src);
       if(const_feat_dim> 0){
         SubVector <BaseFloat> src(专长。行(t2),basic_feat_dim,const_feat_dim);
         //将eg.spk_info设置为相应维度的平均值
         //输入,取自我们存储在例如的特征的帧。
          例如。spk_info .AddVec(1.0 / tot_frames,src);
        }
      }
      例如。标签 .resize(this_num_frames);
     for(int32 j = 0; j <this_num_frames; j ++)
        例如 labels [ j ] = pdf_post [t + j ];
      例如。input_frames = input_frames;  //复制到CompressedMatrix。
     
      std :: ostringstream os;
      os << utt_id << “ - ” << t;
 
      std :: string key = os.str(); // key是<utt_id>  -  <frame_id>
 
      * num_frames_written + = this_num_frames;
      * num_egs_written + = 1;
 
      example_writer-> Write(key,eg);
    }
  }
◆  ProcessFile() [2/2]
static void kaldi :: nnet2 :: ProcessFile	(	const MatrixBase < BaseFloat >& 	壮举,
const 后部& 	pdf_post,
const std :: string& 	utt_id,
const Vector < BaseFloat >& 	重量,
INT32 	left_context,
INT32 	right_context,
INT32 	const_feat_dim,
BaseFloat 	keep_proportion,
BaseFloat 	weight_threshold,
布尔 	use_frame_selection,
布尔 	use_frame_weights,
int64 * 	num_frames_written,
int64 * 	num_frames_skipped,
NnetExampleWriter * 	example_writer 
)		
静态的
在文件nnet-get-weighted-egs.cc的第45行定义。

引用VectorBase <Real> :: CopyFromVec(),count,GetCount(),rnnlm :: i,NnetExample :: input_frames,rnnlm :: j,KALDI_ASSERT,NnetExample :: labels,NnetExample :: left_context,MatrixBase <Real> :: NumCols(),MatrixBase <Real> :: NumRows(),MatrixBase <Real> :: Row(),NnetExample :: spk_info和TableWriter <Holder> :: Write()。

                                                             {
   KALDI_ASSERT(专辑.NumRows()== static_cast < int32 >(pdf_post.size()));
    int32 feat_dim =专长。NumCols();
   KALDI_ASSERT(const_feat_dim <feat_dim);
    int32 basic_feat_dim = feat_dim  -  const_feat_dim;
   Nnet例如:
   Matrix <BaseFloat> input_frames(left_context + 1 + right_context,
                                   basic_feat_dim);
    例如。left_context = left_context;
   // TODO:修改此代码,以及此二进制文件本身,以支持--num-frames
   //允许每个例如多个帧的选项。
   for(int32 i = 0; i < feats.NumRows(); i ++){
      int32 count = GetCount(keep_proportion); // 次数
     //我们会把它写出来(默认为1)。
     if(count> 0){
       //设置“input_frames”。
       for(int32 j = -left_context; j <= right_context ; j ++){
          int32 j2 = j + i ;
         if(j2 <0)j2 = 0;
         if(j2> = feats.NumRows())j2 = feats。NumRows() -  1;
         SubVector <BaseFloat> src(feats,j2),dest(input_frames,
                                                   j + left_context);
          dest.CopyFromVec(src);
        }
        例如。labels .push_back(pdf_post [i]);
        例如。input_frames = input_frames;
       if(const_feat_dim> 0){
         //如果我们使用在线估计的iVectors,我们通常会到达这里。
         SubVector <BaseFloat> const_part(专辑。行(i),
                                          basic_feat_dim,const_feat_dim);
          例如。spk_info .CopyFromVec(const_part);
        }
       if(use_frame_selection){
         if(weights(i)<weight_threshold){
            (* num_frames_skipped)++;
           继续 ;
          }
        }
        std :: ostringstream os;
        os << utt_id << “ - ” << i ;
        std :: string key = os.str(); //存档中的键是示例的编号
 
       for(int32 c = 0; c < count ; c ++)
          example_writer-> Write(key,eg);
      }
    }
  }
◆  ReplaceLastComponents()
void ReplaceLastComponents	(	const Nnet& 	src_nnet,
INT32 	num_to_remove,
Nnet * 	dest_nnet 
)		
删除最后一个“num_to_remove”组件并添加“src_nnet”中的组件。

在文件nnet-functions.cc的第58行定义。

引用Component :: Copy(),Nnet :: GetComponent(),Nnet :: Init(),KALDI_ASSERT和Nnet :: NumComponents()。

由main()引用。

                                              {
   KALDI_ASSERT(num_to_remove> = 0 && num_to_remove <= dest_nnet-> NumComponents());
    int32 c_orig = dest_nnet-> NumComponents() -  num_to_remove;
 
    std :: vector <Component *>组件;
   for(int32 c = 0; c <c_orig; c ++)
      components.push_back(dest_nnet-> GetComponent(c).Copy());
   for(int32 c = 0; c <src_nnet.NumComponents(); c ++)
      components.push_back(src_nnet.GetComponent(c).Copy());
 
   //从结果组件列表中重新初始化“dest_nnet”。
   // Init方法将获取向量中指针的所有权:
    dest_nnet-> Init(&components);
  }
◆  RescaleNnet()
void RescaleNnet	(	const NnetRescaleConfig& 	rescale_config,
const std :: vector < NnetExample >& 	例子,
Nnet * 	NNET 
)		
在文件rescale-nnet.cc的第218行定义。

引用NnetRescaler :: Rescale()。

由NnetRescaleConfig :: Register()引用。

                               {
    NnetRescaler rescaler(rescale_config,examples,nnet);
    rescaler.Rescale();
  }
◆  SetMaxChange()
void kaldi :: nnet2 :: SetMaxChange	(	BaseFloat 	max_change,
Nnet * 	NNET 
)		
在文件nnet-modify-learning-rates.cc的第29行定义。

引用Nnet :: GetComponent(),Nnet :: NumComponents()和AffineComponentPreconditioned :: SetMaxChange()。

由main()引用。

                                                      {
   for(int32 c = 0; c <nnet-> NumComponents(); c ++){
     组件 *组件=&(nnet-> GetComponent(c));
     AffineComponentPreconditioned * ac =
         dynamic_cast < AffineComponentPreconditioned * >(component);
     if(ac!= NULL)
        ac-> SetMaxChange(max_change);
    }
  }
◆  SetPriors()
void kaldi :: nnet2 :: SetPriors	(	const TransitionModel& 	tmodel,
const Vector <double>& 	transition_accs,
双 	prior_floor,
AmNnet * 	am_nnet 
)		
在文件nnet-train-transitions.cc的第28行定义。

引用VectorBase <Real> :: Dim(),KALDI_ASSERT,AmNnet :: NumPdfs(),TransitionModel :: NumPdfs(),AmNnet :: SetPriors()和TransitionModel :: TransitionIdToPdf()。

由main()引用。

                                  {
   KALDI_ASSERT(tModel的。NumPdfs()== am_nnet-> NumPdfs());
   Vector <BaseFloat> pdf_counts(tmodel.NumPdfs());
   KALDI_ASSERT(transition_accs(0)== 0.0); // 有
   //没有零转换ID。
   为(INT32 TID = 1; TID <transition_accs。暗淡(); TID ++){
      int32 pdf = tmodel。TransitionIdToPdf(tid);
      pdf_counts(pdf)+ = transition_accs(tid);
    }
   BaseFloat sum = pdf_counts.Sum();
   KALDI_ASSERT(sum!= 0.0);
   KALDI_ASSERT(prior_floor> 0.0 && prior_floor <1.0);
    pdf_counts.Scale(1.0 / sum);
    pdf_counts.ApplyFloor(prior_floor);
    pdf_counts.Scale(1.0 / pdf_counts.Sum()); //再次标准化
    am_nnet-> SetPriors(pdf_counts);
  }               
◆  ShrinkNnet()
void ShrinkNnet	(	const NnetShrinkConfig& 	shrink_config,
const std :: vector < NnetExample >& 	validation_set,
Nnet * 	NNET 
)		
在文件shrink-nnet.cc的第66行定义。

引用VectorBase <Real> :: ApplyExp(),ComputeObjfAndGradient(),OptimizeLbfgs <Real> :: DoStep(),LbfgsOptions :: first_step_length,OptimizeLbfgs <Real> :: GetProposedValue(),OptimizeLbfgs <Real> :: GetValue(),rnnlm :: i,NnetShrinkConfig :: initial_step,KALDI_ASSERT,KALDI_LOG,KALDI_VLOG,LbfgsOptions :: m,LbfgsOptions :: minimize,NnetShrinkConfig :: num_bfgs_iters,Nnet :: NumUpdatableComponents()和Nnet :: ScaleComponents()。

由NnetShrinkConfig :: Register()引用。

                              {
 
    int32 dim = nnet-> NumUpdatableComponents();
   KALDI_ASSERT(dim> 0);
    矢量<double> log_scale(dim),gradient(dim); //将为零。
   
   //获取初始渐变。
   double objf,initial_objf;
 
 
    LbfgsOptions lbfgs_options;
    lbfgs_options.minimize = false ; //我们正在最大化
    lbfgs_options.m =昏暗; //存储与维度相同数量的向量
   //本身,所以这是BFGS。
    lbfgs_options.first_step_length = shrink_config.initial_step;
   
    OptimizeLbfgs <double> lbfgs(log_scale,
                                lbfgs_options);
   
   for(int32 i = 0; i <shrink_config.num_bfgs_iters; i ++){
      log_scale.CopyFromVec(lbfgs.GetProposedValue());
      objf = ComputeObjfAndGradient(validation_set,log_scale,
                                    * nnet,
                                    &gradient);
 
     KALDI_VLOG(2)<< “log-scale =” << log_scale << “,objf =” << objf
                    << “,gradient =” << gradient;
     if(i == 0)initial_objf = objf;
 
      lbfgs.DoStep(objf,gradient);
    }
 
    log_scale.CopyFromVec(lbfgs.GetValue(&objf));
 
    Vector <BaseFloat> scale(log_scale);
    scale.ApplyExp();
   KALDI_LOG << “缩小nnet,每帧验证objf改变自”
              << initial_objf << “到” << objf << “,每层的比例因子是”
              <<尺度;
    nnet-> ScaleComponents(scale);
  }
◆  SolvePackingProblem()
void SolvePackingProblem	(	BaseFloat 	max_cost,
const std :: vector < BaseFloat >& 	费用,
std :: vector <std :: vector < size_t >> * 	组 
)		
该功能使用“首次拟合”算法解决了“打包问题”。

它将索引0到sizes.size() - 1组合在一起,这样每个组内的成本总和不会超过max_lcost。[但是,如果有单个示例超过max_cost,则将它们放在自己的bin中]。该算法不是特别有效 - 它应该比n log(n)更多n ^ 2。

在文件nnet-example-functions.cc的第867行定义。

引用rnnlm :: i和rnnlm :: j。

由CombineDiscriminativeExamples(),SplitExampleStats :: SplitExampleStats()和UnitTestSolvePackingProblem()引用。

                                                                  {
    组 - > clear();
    std :: vector <BaseFloat> group_costs;
   for(size_t  i = 0; i <costs.size(); i ++){
     bool found_group = false ;
     BaseFloat this_cost = costs [ i ];
     for(size_t  j = 0; j <groups-> size(); j ++){
       if(group_costs [ j ] + this_cost <= max_cost){
          (* groups)[ j ] .push_back(i);
          group_costs [ j ] + = this_cost;
          found_group = true ;
         休息 ;
        }
      }
     if(!found_group){ //将此对象放入新创建的组中。
        组 - >调整大小(groups-> size()+ 1);
        groups-> back()。push_back(i);
        group_costs.push_back(this_cost);
      }
    }
  }
◆  SplitDiscriminativeExample()
void SplitDiscriminativeExample	(	const SplitDiscriminativeExampleConfig& 	配置,
const TransitionModel& 	tmodel,
const DiscriminativeNnetExample& 	例如,
std :: vector < DiscriminativeNnetExample > * 	egs_out,
SplitExampleStats * 	stats_out 
)		
将“判别性示例”分成多个部分,分裂格子具有“夹点”的位置。

在文件nnet-example-functions.cc的第764行定义。

引用DiscriminativeExampleSplitter :: Split()。

由main()和SplitExampleStats :: SplitExampleStats()引用。

                                    {
    DiscriminativeExampleSplitter拆分器(config,tmodel,例如egs_out);
    splitter.Split(stats_out);
  }
◆  TotalNnetTrainingWeight()
BaseFloat TotalNnetTrainingWeight	(	const std :: vector < NnetExample >& 	EGS	)	
返回所有示例中总和的总权重...

只是一个简单的实用功能。

在文件nnet-update.cc的第248行定义。

引用rnnlm :: i和rnnlm :: j。

由DoBackpropSingleThreaded(),main(),DoBackpropParallelClass :: operator()()和NnetExampleBackgroundReader :: ReadExamples()引用。

                                                                       {
   double ans = 0.0;
   for(size_t  i = 0; i <egs.size(); i ++)
     for(size_t  j = 0; j <egs [ i ] .labels.size(); j ++)//对于每个标记的帧
       for(size_t k = 0; k <egs [ i ] .labels [ j ] .size (); k ++)
          ans + = egs [ i ] .labels [ j ] [k] .second;
   返回 ;
  }
◆  TrainNnetSimple()
int64 TrainNnetSimple	(	const NnetSimpleTrainerConfig& 	配置,
Nnet * 	nnet,
SequentialNnetExampleReader * 	读者,
双* 	tot_weight = NULL,
双* 	tot_logprob =NULL 
)		
培训它可以从阅读器中读取的所有示例。

这可以在单个线程中进行训练,但它使用单独的线程来读取示例并在CPU上格式化输入数据; 这节省了我们使用GPU的时间。返回已处理的示例数。输出到tot_weight和tot_logprob_per_frame,如果非NULL,则示例的总权重(通常等于示例数)和总logprob目标函数。

在文件train-nnet.cc的第147行定义。

引用DoBackprop(),NnetExampleBackgroundReader :: GetNextMinibatch(),rnnlm :: i,KALDI_ASSERT,KALDI_LOG,KALDI_WARN,NnetSimpleTrainerConfig :: minibatch_size和NnetSimpleTrainerConfig :: minibatches_per_phase。

由main()和NnetSimpleTrainerConfig :: Register()引用。

                                                 {
    int64 num_egs_processed = 0;
   double tot_weight = 0.0,tot_logprob = 0.0;
    NnetExampleBackgroundReader background_reader(config.minibatch_size,
                                                  nnet,读者);
   KALDI_ASSERT(config.minibatches_per_phase> 0);
   while(true){
     //迭代阶段。培训阶段只是一定数量的
     // minibatches,其唯一的意义是它是周期性的
     //我们打印诊断。
     double tot_weight_this_phase = 0.0,tot_logprob_this_phase = 0.0;
 
      int32 i ;
     for(i = 0; i <config.minibatches_per_phase; i ++){
        std :: vector <NnetExample>示例;
        Matrix <BaseFloat> examples_formatted;
       double minibatch_total_weight;  //这通常等于小批量大小。
       if(!background_reader.GetNextMinibatch(&examples,&examples_formatted,
                                                &minibatch_total_weight))
         休息 ;
        tot_logprob_this_phase + = DoBackprop(* nnet,examples,&examples_formatted,
                                             nnet,NULL);
        tot_weight_this_phase + = minibatch_total_weight;
        num_egs_processed + = examples.size();
      }
     if(i!= 0){
       KALDI_LOG << “训练目标函数(此阶段)是”
                  <<(tot_logprob_this_phase / tot_weight_this_phase)<< “over”
                  << tot_weight_this_phase << “帧。” ;
      }
      tot_weight + = tot_weight_this_phase;
      tot_logprob + = tot_logprob_this_phase;
     if(i!= config.minibatches_per_phase){
       //没有得到我们想要的所有小型机,因为没有更多的输入。
       //当且仅当我们在上面的循环中“断开”时,这是真的。
       休息 ;
      }
    }
   if(tot_weight == 0.0){
     KALDI_WARN << “没有看到数据。” ;
    } else {
     KALDI_LOG << “ backprop on” << tot_weight
                << “例子,每帧的平均对数概率是”
                <<(tot_logprob / tot_weight);
     KALDI_LOG << “[此行将由脚本解析:] log-prob-per-frame =”
                <<(tot_logprob / tot_weight);
    }
   if(tot_weight_ptr)* tot_weight_ptr = tot_weight;
   if(tot_logprob_ptr)* tot_logprob_ptr = tot_logprob;
   返回 num_egs_processed;
  }
◆  UnitTestAdditiveNoiseComponent()
void kaldi :: nnet2 :: UnitTestAdditiveNoiseComponent	(		)	
在文件nnet-component-test.cc的第434行定义。

引用rnnlm :: i,AdditiveNoiseComponent :: InitFromString(),KALDI_ERR,KALDI_WARN,kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                        {
   //我们正在测试梯度是否正确计算:
   //输入梯度和模型梯度。
 
    int32 num_fail = 0,num_tries = 4;
   for(int32 i = 0; i <num_tries; i ++){
     试试 {
        int32 input_dim = 10 + Rand()%50;
        {
         AdditiveNoiseComponent additive_noise_component(input_dim,0.1);
         UnitTestGenericComponentInternal(additive_noise_component);
        }
        {
         AdditiveNoiseComponent additive_noise_component;
          additive_noise_component。InitFromString(“dim = 15 stddev = 0.2”);
         UnitTestGenericComponentInternal(additive_noise_component);
        }
      } catch(...){
       KALDI_WARN << “忽略AdditiveNoiseComponent测试中的失败” ;
        num_fail ++;
      }
    }
   if(num_fail> = num_tries / 2){
     KALDI_ERR << “测试失败太多。” ;
    }
  }
◆  UnitTestAffineComponent()
void kaldi :: nnet2 :: UnitTestAffineComponent	(		)	
在文件nnet-component-test.cc的第337行定义。

引用AffineComponent :: Init(),AffineComponent :: InitFromString(),kaldi :: Rand(),MatrixBase <Real> :: Scale(),MatrixBase <Real> :: SetRandn(),kaldi :: Sleep(),UnitTestGenericComponentInternal ()和kaldi :: WriteKaldiObject()。

由main()引用。

                                 {
   BaseFloat learning_rate = 0.01,
        param_stddev = 0.1,bias_stddev = 1.0;
    int32 input_dim = 5 + Rand()%10,output_dim = 5 + Rand()%10;
    {
     AffineComponent组件;
     if(Rand()%2 == 0){
        组件。Init(learning_rate,input_dim,output_dim,
                       param_stddev,bias_stddev);
      } else {
       Matrix <BaseFloat> mat(output_dim + 1,input_dim);
        mat.SetRandn();
        mat.Scale(param_stddev);
       WriteKaldiObject(mat,“tmpf”,true);
       睡眠(0.5);
        组件。Init(learning_rate,“tmpf”);
        unlink(“tmpf”);
      }
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “learning-rate = 0.01 input-dim = 10 output-dim = 15 param-stddev = 0.1” ;
     AffineComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestAffineComponentPreconditioned()
void kaldi :: nnet2 :: UnitTestAffineComponentPreconditioned	(		)	
在文件nnet-component-test.cc的第478行定义。

引用AffineComponentPreconditioned :: Init(),AffineComponentPreconditioned :: InitFromString(),kaldi :: Rand(),MatrixBase <Real> :: Scale(),MatrixBase <Real> :: SetRandn(),kaldi :: Sleep(),UnitTestGenericComponentInternal ()和kaldi :: WriteKaldiObject()。

由main()引用。

                                               {
   BaseFloat learning_rate = 0.01,
        param_stddev = 0.1,bias_stddev = 1.0,alpha = 0.01,
        max_change = 100.0;
    int32 input_dim = 5 + Rand()%10,output_dim = 5 + Rand()%10;
    {
     AffineComponentPreconditioned组件;
     if(Rand()%2 == 0){
        组件。Init(learning_rate,input_dim,output_dim,
                       param_stddev,bias_stddev,
                       alpha,max_change);
      } else {
       Matrix <BaseFloat> mat(output_dim + 1,input_dim);
        mat.SetRandn();
        mat.Scale(param_stddev);
       WriteKaldiObject(mat,“tmpf”,true);
       睡眠(0.5);
        组件。Init(learning_rate,alpha,max_change,“tmpf”);
        unlink(“tmpf”);
      }
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “learning-rate = 0.01 input-dim = 16 output-dim = 15 param-stddev = 0.1 alpha = 0.01” ;
     AffineComponentPreconditioned组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestAffineComponentPreconditionedOnline()
void kaldi :: nnet2 :: UnitTestAffineComponentPreconditionedOnline	(		)	
在文件nnet-component-test.cc的第509行定义。

参考文献AffineComponentPreconditionedOnline :: Init(),AffineComponentPreconditionedOnline :: InitFromString(),kaldi :: Rand(),MatrixBase <Real> :: Scale(),MatrixBase <Real> :: SetRandn(),kaldi :: Sleep(),UnitTestGenericComponentInternal ()和kaldi :: WriteKaldiObject()。

由main()引用。

                                                     {
   BaseFloat learning_rate = 0.01,
        param_stddev = 0.1,bias_stddev = 1.0,num_samples_history = 2000.0,alpha = 4.0,
        max_change_per_sample = 0.1,update_period = 1;
    int32 input_dim = 5 + Rand()%10,output_dim = 5 + Rand()%10,
        rank_in = 1 + Rand()%5,rank_out = 1 + Rand()%5;
    {
     AffineComponentPreconditionedOnline组件;
     if(Rand()%2 == 0){
        组件。Init(learning_rate,input_dim,output_dim,
                       param_stddev,bias_stddev,
                       rank_in,rank_out,update_period,
                       num_samples_history,alpha,
                       max_change_per_sample);
      } else {
       Matrix <BaseFloat> mat(output_dim + 1,input_dim);
        mat.SetRandn();
        mat.Scale(param_stddev);
       WriteKaldiObject(mat,“tmpf”,true);
       睡眠(0.5);
        组件。Init(learning_rate,rank_in,rank_out,
                       update_period,num_samples_history,alpha,
                       max_change_per_sample,“tmpf”);
        unlink(“tmpf”);
      }
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “learning-rate = 0.01 input-dim = 16 output-dim = 15 param-stddev = 0.1 num-samples-history = 3000 alpha = 2.0 update-period = 1 rank-in = 5 rank-out = 6“ ;
     AffineComponentPreconditionedOnline组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestAmNnet()
void kaldi :: nnet2 :: UnitTestAmNnet	(		)	
在am-nnet-test.cc文件的第29行定义。

引用VectorBase <真实> :: ApplyExp() ,kaldi :: GenRandContextDependencyLarge() ,GenRandomNnet() ,kaldi :: GetDefaultTopology() ,rnnlm ::我,KALDI_ASSERT,TransitionModel :: NumPdfs() ,AmNnet ::读() ,VectorBase <Real> :: Scale(),AmNnet :: SetPriors(),VectorBase <Real> :: SetRandn(),VectorBase <Real> :: Sum()和AmNnet :: Write()。

由main()引用。

                        {
    std :: vector <int32>手机;
    phones.push_back(1);
   for(int32 i = 2; i <20; i ++)
     if(rand()%2 == 0)
        phones.push_back(i);
    int32 N = 2 + rand()%2,// context-size N为2或3。
        P = rand()%N;  //中央电话在[0,N]上是随机的
 
    std :: vector <int32> num_pdf_classes;
 
   ContextDependency * ctx_dep =
       GenRandContextDependencyLarge(手机,N,P,
                                     true,&num_pdf_classes);
 
   HmmTopology topo = GetDefaultTopology(电话);
 
   TransitionModel trans_model(* ctx_dep,topo);
 
   删除 ctx_dep; //我们不会再需要这个了。
    ctx_dep = NULL;
 
    int32 input_dim = 40,output_dim = trans_model。NumPdfs();
   NNET * NNET = GenRandomNnet(input_dim,output_dim);
 
   AmNnet am_nnet(* nnet);
   删除 nnet;
    nnet = NULL;
   Vector <BaseFloat> priors(output_dim);
    priors.SetRandn();
    priors.ApplyExp();
    priors.Scale(1.0 / priors.Sum());
 
    am_nnet.SetPriors(先生们);
 
   bool binary =(rand()%2 == 0);
    std :: ostringstream os;
    am_nnet.Write(os,binary);
   AmNnet am_nnet2;
    std :: istringstream是(os.str());
    am_nnet2。读(是,二进制);
 
    std :: ostringstream os2;
    am_nnet2。写(os2,二进制);
 
   KALDI_ASSERT(os2.str()== os.str());
  }
◆  UnitTestBlockAffineComponent()
void kaldi :: nnet2 :: UnitTestBlockAffineComponent	(		)	
在文件nnet-component-test.cc的第544行定义。

引用BlockAffineComponent :: Init(),BlockAffineComponent :: InitFromString(),kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                      {
   BaseFloat learning_rate = 0.01,
        param_stddev = 0.1,bias_stddev = 0.1;
    int32 num_blocks = 1 + Rand()%3,
           input_dim = num_blocks *(2 + Rand()%4),
          output_dim = num_blocks *(2 + Rand()%4);
 
    {
     BlockAffineComponent组件;
      组件。Init(learning_rate,input_dim,output_dim,
                     param_stddev,bias_stddev,num_blocks);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “learning-rate = 0.01 input-dim = 10 output-dim = 15 param-stddev = 0.1 num-blocks = 5” ;
     BlockAffineComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestBlockAffineComponentPreconditioned()
void kaldi :: nnet2 :: UnitTestBlockAffineComponentPreconditioned	(		)	
在文件nnet-component-test.cc的第565行定义。

引用BlockAffineComponentPreconditioned :: Init(),BlockAffineComponentPreconditioned :: InitFromString(),kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                                    {
   BaseFloat learning_rate = 0.01,
        param_stddev = 0.1,bias_stddev = 1.0,alpha = 3.0;
    int32 num_blocks = 1 + Rand()%3,
           input_dim = num_blocks *(2 + Rand()%4),
          output_dim = num_blocks *(2 + Rand()%4);
 
    {
     BlockAffineComponentPreconditioned组件;
      组件。Init(learning_rate,input_dim,output_dim,
                     param_stddev,bias_stddev,num_blocks,alpha);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “learning-rate = 0.01 input-dim = 10 output-dim = 15 param-stddev = 0.1 num-blocks = 5 alpha = 3.0” ;
     BlockAffineComponentPreconditioned组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestConvolutional1dComponent()
void kaldi :: nnet2 :: UnitTestConvolutional1dComponent	(		)	
在文件nnet-component-test.cc的第365行定义。

引用Convolutional1dComponent :: Init(),Convolutional1dComponent :: InitFromString(),kaldi :: Rand(),MatrixBase <Real> :: Scale(),MatrixBase <Real> :: SetRandn(),kaldi :: Sleep(),UnitTestGenericComponentInternal ()和kaldi :: WriteKaldiObject()。

由main()引用。

                                          {
   BaseFloat learning_rate = 0.01,
              param_stddev = 0.1,bias_stddev = 1.0;
    int32 patch_stride = 10,patch_step = 1,patch_dim = 4;
    int32 num_patches = 1 +(patch_stride  -  patch_dim)/ patch_step;
    int32 num_splice = 5 + Rand()%10,num_filters = 5 + Rand()%10;
    int32 input_dim = patch_stride * num_splice;
    int32 filter_dim = patch_dim * num_splice;
    int32 output_dim = num_patches * num_filters;
    {
     卷积1dComponent组件;
     if(Rand()%2 == 0){
        组件。Init(learning_rate,input_dim,output_dim,
                       patch_dim,patch_step,patch_stride,
                       param_stddev,bias_stddev,true);
      } else {
       Matrix <BaseFloat> mat(num_filters,filter_dim + 1);
        mat.SetRandn();
        mat.Scale(param_stddev);
       WriteKaldiObject(mat,“tmpf”,true);
       睡眠(0.5);
        组件。Init(learning_rate,patch_dim,
                       patch_step,patch_stride,“tmpf”,false);
        unlink(“tmpf”);
      }
     UnitTestGenericComponentInternal(component);
    }
    {
     // attach-conv默认为false
     const  char * str = “learning-rate = 0.01 input-dim = 100 output-dim = 70 param-stddev = 0.1 patch-dim = 4 patch-step = 1 patch-stride = 10” ;
     Convolutional1dComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “learning-rate = 0.01 input-dim = 100 output-dim = 70 param-stddev = 0.1 patch-dim = 4 patch-step = 1 patch-stride = 10 attached-conv = true” ;
     Convolutional1dComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestDctComponent()
void kaldi :: nnet2 :: UnitTestDctComponent	(		)	
在文件nnet-component-test.cc的第607行定义。

引用DctComponent :: Init(),DctComponent :: InitFromString(),rnnlm :: n,kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                              {
    int32 m = 1 + Rand()%4,n = 1 + Rand()%4,
    dct_dim = m,dim = m * n ;
   bool reorder =(Rand()%2 == 0);
    {
     DctComponent组件;
      组件。Init(dim,dct_dim,reorder);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “dim = 10 dct-dim = 5 reorder = true” ;
     DctComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “dim = 10 dct-dim = 5 reorder = true dct-keep-dim = 1” ;
     DctComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “dim = 10 dct-dim = 5 reorder = true dct-keep-dim = 2” ;
     DctComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “dim = 10 dct-dim = 5 reorder = true dct-keep-dim = 3” ;
     DctComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “dim = 10 dct-dim = 5 reorder = true dct-keep-dim = 4” ;
     DctComponent组件;
      分量。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestDropoutComponent()
void kaldi :: nnet2 :: UnitTestDropoutComponent	(		)	
在文件nnet-component-test.cc的第407行定义。

引用rnnlm :: i,DropoutComponent :: InitFromString(),KALDI_ERR,KALDI_WARN,kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                  {
   //我们正在测试梯度是否正确计算:
   //输入渐变和模型渐变。
 
    int32 num_fail = 0,num_tries = 4;
   for(int32 i = 0; i <num_tries; i ++){
     试试 {
        int32 input_dim = 10 + Rand()%50;
        {
         DropoutComponent dropout_component(input_dim,0.5,0.3);
         UnitTestGenericComponentInternal(dropout_component);
        }
        {
         DropoutComponent dropout_component;
          dropout_component。InitFromString(“dim = 15 dropout -proportion = 0.6 dropout -scale = 0.1”);
         UnitTestGenericComponentInternal(dropout_component);
        }
      } catch(...){
       KALDI_WARN << “忽略UnitTestDropoutComponent()中的测试失败。” ;
        num_fail ++;
      }
    }
   if(num_fail> = num_tries / 2){
     KALDI_ERR << “测试失败太多。” ;
    }
  }
◆  UnitTestFixedAffineComponent()
void kaldi :: nnet2 :: UnitTestFixedAffineComponent	(		)	
在文件nnet-component-test.cc的第661行定义。

引用FixedAffineComponent :: Init(),rnnlm :: n,kaldi :: Rand(),CuMatrixBase <Real> :: SetRandn()和UnitTestGenericComponentInternal()。

由main()引用。

                                      {
    int32 m = 15 + Rand()%4,n = 15 + Rand()%4;
    {
     CuMatrix <BaseFloat> mat(m,n);
      mat.SetRandn();
     FixedAffineComponent组件;
      组件。Init(mat);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestFixedBiasComponent()
void kaldi :: nnet2 :: UnitTestFixedBiasComponent	(		)	
在文件nnet-component-test.cc的第683行定义。

引用FixedBiasComponent :: Init(),kaldi :: Rand(),CuVectorBase <Real> :: SetRandn()和UnitTestGenericComponentInternal()。

由main()引用。

                                    {
    int32 m = 1 + Rand()%20;
    {
     CuVector <BaseFloat> vec(m);
      vec.SetRandn();
     FixedBiasComponent组件;
      组件。Init(vec);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestFixedLinearComponent()
void kaldi :: nnet2 :: UnitTestFixedLinearComponent	(		)	
在文件nnet-component-test.cc的第649行定义。

引用FixedLinearComponent :: Init(),rnnlm :: n,kaldi :: Rand(),CuMatrixBase <Real> :: SetRandn()和UnitTestGenericComponentInternal()。

由main()引用。

                                      {
    int32 m = 1 + Rand()%4,n = 1 + Rand()%4;
    {
     CuMatrix <BaseFloat> mat(m,n);
      mat.SetRandn();
     FixedLinearComponent组件;
      组件。Init(mat);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestFixedScaleComponent()
void kaldi :: nnet2 :: UnitTestFixedScaleComponent	(		)	
在文件nnet-component-test.cc的第672行定义。

引用FixedScaleComponent :: Init(),kaldi :: Rand(),CuVectorBase <Real> :: SetRandn()和UnitTestGenericComponentInternal()。

由main()引用。

                                     {
    int32 m = 1 + Rand()%20;
    {
     CuVector <BaseFloat> vec(m);
      vec.SetRandn();
     FixedScaleComponent组件;
      组件。Init(vec);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestGenericComponent()
void kaldi :: nnet2 :: UnitTestGenericComponent	(	的std :: string 	extra_str =""	)	
在文件nnet-component-test.cc的第244行定义。

引用kaldi :: Rand()和UnitTestGenericComponentInternal()。

                                                          {
   //如果它有来自int的初始值设定项,则有效
   //例如,tanh,sigmoid。
 
   //我们正在测试梯度是否正确计算:
   //输入渐变和模型渐变。
 
    int32 input_dim = 10 + Rand()%50;
    {
      T分量(input_dim);
     UnitTestGenericComponentInternal(component);
    }
    {
      T组分;
      component.InitFromString(static_cast <std :: string>(“dim = 15”)+ extra_str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestGenericComponentInternal() [1/2]
void kaldi :: nnet2 :: UnitTestGenericComponentInternal	(	const 组件& 	组件,
const ChunkInfo 	in_info,
const ChunkInfo 	out_info 
)		
在文件nnet-component-test.cc的第28行定义。

引用CuVectorBase <真实> :: AddMatVec() ,组分:: Backprop() ,组分:: BackpropNeedsInput() ,组分:: BackpropNeedsOutput() ,组分::复制() ,UpdatableComponent :: DotProduct() ,rnnlm ::我,KALDI_ASSERT,KALDI_ERR,KALDI_LOG,KALDI_WARN,kaldi :: kNoTrans,kaldi :: kTrans,ChunkInfo :: NumCols(),ChunkInfo :: NumRows(),UpdatableComponent :: PerturbParams(),Component :: Propagate(),kaldi :: Rand(),Component :: ReadNew(),RandomComponent :: ResetGenerator(),CuMatrixBase <Real> :: Row(),CuVectorBase <Real> :: SetRandn(),CuMatrixBase <Real> :: SetRandn(),Output :: Stream(),Input :: Stream(),kaldi :: TraceMatMat()和Component :: Write()。

通过引用UnitTestAdditiveNoiseComponent() ,UnitTestAffineComponent() ,UnitTestAffineComponentPreconditioned() ,UnitTestAffineComponentPreconditionedOnline() ,UnitTestBlockAffineComponent() ,UnitTestBlockAffineComponentPreconditioned() ,UnitTestConvolutional1dComponent() ,UnitTestDctComponent() ,UnitTestDropoutComponent() ,UnitTestFixedAffineComponent() ,UnitTestFixedBiasComponent() ,UnitTestFixedLinearComponent() ,UnitTestFixedScaleComponent(),UnitTestGenericComponent(),UnitTestGenericComponentInternal(),UnitTestMaxoutComponent(),UnitTestMaxpoolingComponent(),UnitTestPnormComponent(),UnitTestScaleComponent(),UnitTestSigmoidComponent(),UnitTestSpliceComponent()和UnitTestSumGroupComponent()。

                                                                   {
 
   CuMatrix <BaseFloat>输入(in_info。numRows行(),in_info。NUMCOLS()),
        输出(1,out_info。numRows行()* out_info。NUMCOLS());
    输入。SetRandn();
   CuVector <BaseFloat> objf_vec(out_info.NumCols()); //目标函数是输出的线性函数。
    objf_vec。SetRandn(); //设置为高斯噪声。
 
    int32 rand_seed = Rand();
 
   RandomComponent * rand_component =
       const_cast < RandomComponent * >(dynamic_cast < const RandomComponent * >(&component));
   if(rand_component!= NULL){
      srand(rand_seed);
      rand_component-> ResetGenerator();
    }
    组件。传播(in_info,out_info,输入和输出);
    {
     bool binary =(Rand()%2 == 0);
     输出 ko(“tmpf”,二进制);
      组件。写(ko.Stream(),二进制);
    }
   组件 * component_copy;
    {
     bool binary_in;
     输入 ki(“tmpf”,&binary_in);
      component_copy = Component :: ReadNew(ki.Stream(),binary_in);
    }
    unlink(“tmpf”);
 
    { //测试反向导数是正确的。
     CuVector <BaseFloat> output_objfs(out_info numRows行());
      output_objfs。AddMatVec(1.0,输出,kNoTrans,objf_vec,0.0);
     BaseFloat objf = output_objfs.Sum();
 
 
     CuMatrix <BaseFloat> output_deriv(output.NumRows(),output.NumCols());
     for(int32 i = 0; i <output_deriv.NumRows(); i ++)
        output_deriv。Row(i).CopyFromVec(objf_vec);
 
     CuMatrix <BaseFloat> input_deriv(input.NumRows(),input.NumCols());
 
 
     CuMatrix <BaseFloat> empty_mat;
     CuMatrix <BaseFloat>&input_ref =
          (component_copy-> BackpropNeedsInput?()输入:empty_mat),
          &output_ref =
          (component_copy-> BackpropNeedsOutput()输出:empty_mat);
 
      component_copy-> Backprop(in_info,out_info,input_ref,output_ref,
                               output_deriv,NULL和input_deriv);
 
      int32 num_ok = 0,num_bad = 0,num_tries = 10;
     KALDI_LOG << “比较要素渐变” << num_tries << “次。” ;
     for(int32 i = 0; i <num_tries; i ++){
       CuMatrix <BaseFloat> perturbed_input(input.NumRows(),input.NumCols());
        {
         RandomComponent * rand_component =
             const_cast < RandomComponent * >(dynamic_cast < const RandomComponent * >(&component));
         if(rand_component!= NULL){
            srand(rand_seed);
            rand_component-> ResetGenerator();
          }
        }
        perturbed_input.SetRandn();
        perturbed_input.Scale(1.0e-04); //缩小一点,这就像一个三角洲。
       BaseFloat predict_difference = TraceMatMat(perturbed_input,
                                                     input_deriv,kTrans);
        perturbed_input.AddMat(1.0,输入); //现在它是输入+一个delta。
        { //使用扰动的输入计算objf并确保它匹配
         //预测。
         CuMatrix <BaseFloat> perturbed_output(output.NumRows(),output.NumCols());
          {
           RandomComponent * rand_component =
               const_cast < RandomComponent * >(dynamic_cast < const RandomComponent * >(&component));
           if(rand_component!= NULL){
              srand(rand_seed);
              rand_component-> ResetGenerator();
            }
          }
          组件。传播(in_info,out_info,perturbed_input和perturbed_output);
         CuVector <BaseFloat> perturbed_output_objfs(out_info numRows行());
          perturbed_output_objfs。AddMatVec(1.0,perturbed_output,kNoTrans,
                                           objf_vec,0.0);
         BaseFloat perturbed_objf = perturbed_output_objfs.Sum(),
               observed_difference = perturbed_objf  -  objf;
         KALDI_LOG << “输入渐变:比较” << predict_difference
                    << “和” << observe_difference;
         if(fabs(predict_difference  -  observed_difference)>
              0.15 * fabs((predict_difference + observed_difference)/ 2)&&
              工厂(predict_difference  -  observed_difference)> 1.0e-06){
           KALDI_WARN << “差异很大!” ;
            num_bad ++;
          } else {
            num_ok ++;
          }
        }
      }
     KALDI_LOG << “成功” << num_ok << “out of” << num_tries
                << “尝试”。;
     if(num_ok <= num_bad){
       删除 component_copy;
       KALDI_ERR << “特征导数检查失败” ;
      }
    }
 
   UpdatableComponent * ucomponent =
       dynamic_cast < UpdatableComponent * >(component_copy);
 
   if(ucomponent!= NULL){ //测试参数导数是否正确。
 
      int32 num_ok = 0,num_bad = 0,num_tries = 10;
     KALDI_LOG << “比较模型渐变” << num_tries << “次。” ;
     for(int32 i = 0; i <num_tries; i ++){
       UpdatableComponent * perturbed_ucomponent =
           dynamic_cast < UpdatableComponent * >(ucomponent-> Copy()),
            * gradient_ucomponent =
            dynamic_cast <UpdatableComponent *>(ucomponent-> Copy());
       KALDI_ASSERT(perturbed_ucomponent!= NULL);
        gradient_ucomponent-> SetZero(true); //将params设置为零并视为渐变。
       BaseFloat perturb_stddev = 5.0e-04;
perturbed_ucomponent-        > PerturbParams(perturb_stddev);
 
       CuVector <BaseFloat> output_objfs(out_info numRows行());
        output_objfs。AddMatVec(1.0,输出,kNoTrans,objf_vec,0.0);
       BaseFloat objf = output_objfs.Sum();
 
       CuMatrix <BaseFloat> output_deriv(output.NumRows(),output.NumCols());
       for(int32 i = 0; i <output_deriv.NumRows(); i ++)
          output_deriv。Row(i).CopyFromVec(objf_vec);
       CuMatrix <BaseFloat> input_deriv; //(input.NumRows(),input.NumCols());
 
       //这将计算参数渐变。
        ucomponent-> Backprop(in_info,out_info,输入,输出,output_deriv,
                             gradient_ucomponent,&input_deriv);
 
       //现在计算扰动的objf。
       BaseFloat objf_perturbed;
        {
         CuMatrix <BaseFloat> output_perturbed; //(num_egs,output_dim);
          {
           RandomComponent * rand_component =
               const_cast < RandomComponent * >(dynamic_cast < const RandomComponent * >(&component));
           if(rand_component!= NULL){
              srand(rand_seed);
              rand_component-> ResetGenerator();
            }
          }
 perturbed_ucomponent-          > Propagate(in_info,out_info,input和output_perturbed);
         CuVector <BaseFloat> output_objfs_perturbed(out_info numRows行());
          output_objfs_perturbed。AddMatVec(1.0,output_perturbed,
                                          kNoTrans,objf_vec,0.0);
          objf_perturbed = output_objfs_perturbed.Sum();
        }
 
       BaseFloat delta_objf_observed = objf_perturbed  -  objf,
            delta_objf_predicted =(perturbed_ucomponent-> DotProduct(* gradient_ucomponent) -
                                    ucomponent-> DotProduct(* gradient_ucomponent));
 
       KALDI_LOG << “模型渐变:比较” << delta_objf_observed
                  << “和” << delta_objf_predicted;
       if(fabs(delta_objf_predicted  -  delta_objf_observed)>
            0.05 *(fabs(delta_objf_predicted + delta_objf_observed)/ 2)&&
            工厂(delta_objf_predicted  -  delta_objf_observed)> 1.0e-06){
         KALDI_WARN << “差异很大!” ;
          num_bad ++;
        } else {
          num_ok ++;
        }
       删除 perturbed_ucomponent;
       删除 gradient_ucomponent;
      }
     if(num_ok <num_bad){
       删除 component_copy;
       KALDI_ERR << “模型导数检查失败” ;
      }
    }
   删除 component_copy; // 不再需要。
  }
◆  UnitTestGenericComponentInternal() [2/2]
void kaldi :: nnet2 :: UnitTestGenericComponentInternal	(	const 组件& 	零件	)	
在文件nnet-component-test.cc的第210行定义。

引用Component :: Info(),Component :: InputDim(),KALDI_LOG,Component :: OutputDim(),kaldi :: Rand()和UnitTestGenericComponentInternal()。

                                                                    {
    int32 input_dim = component。InputDim(),
        output_dim =组件。OutputDim();
 
   KALDI_LOG <<组件。信息();
    int32 num_egs = 10 + Rand()%5;
    int32 num_chunks = 1,
          first_offset = 0,
          last_offset = num_egs-1;
 
   ChunkInfo in_info(input_dim,num_chunks,first_offset,last_offset);
   ChunkInfo out_info(output_dim,num_chunks,first_offset,last_offset);
   UnitTestGenericComponentInternal(component,in_info,out_info);
  }
◆  UnitTestMaxoutComponent()
void kaldi :: nnet2 :: UnitTestMaxoutComponent	(		)	
在文件nnet-component-test.cc的第263行定义。

引用rnnlm :: i,MaxoutComponent :: InitFromString(),kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                 {
   //如果它有来自int的初始值设定项,则有效
   //例如,tanh,sigmoid。
 
   //我们正在测试渐变是否正确计算:
   //输入梯度和模型梯度。
 
   for(int32 i = 0; i <5; i ++){
      int32 output_dim = 10 + Rand()%20,
          group_size = 1 + Rand()%10,
          input_dim = output_dim * group_size;
 
     MaxoutComponent组件(input_dim,output_dim);
     UnitTestGenericComponentInternal(component);
    }
 
    {
     MaxoutComponent组件;
      组件。InitFromString(“input-dim = 15 output-dim = 5”);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestMaxpoolingComponent()
void kaldi :: nnet2 :: UnitTestMaxpoolingComponent	(		)	
在文件nnet-component-test.cc的第310行定义。

引用rnnlm :: i,MaxpoolingComponent :: InitFromString(),kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                     {
   //如果它有来自int的初始值设定项,则有效
   //例如,tanh,sigmoid。
   //我们正在测试渐变是否正确计算:
   //输入梯度和模型梯度。
 
   for(int32 i = 0; i <5; i ++){
      int32 pool_stride = 5 + Rand()%10,
            pool_size = 2 + Rand()%3,
            num_pools = 1 + Rand()%10;
      int32 output_dim = num_pools * pool_stride;
      int32 num_patches = num_pools * pool_size;
      int32 input_dim = pool_stride * num_patches;
 
     MaxpoolingComponent组件(input_dim,output_dim,
                                    pool_size,pool_stride);
     UnitTestGenericComponentInternal(component);
    }
 
    {
     MaxpoolingComponent组件;
      组件。InitFromString(“input-dim = 192 output-dim = 64 pool-size = 3 pool-stride = 16”);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestNnet()
void kaldi :: nnet2 :: UnitTestNnet	(		)	
在文件nnet-nnet-test.cc的第26行定义。

引用GenRandomNnet (),KALDI_ASSERT,Nnet :: Read()和Nnet :: Write()。

由main()引用。

                      {
    int32 input_dim = 40,output_dim = 500;
   NNET * NNET = GenRandomNnet(input_dim,output_dim);
 
   bool binary =(rand()%2 == 0);
    std :: ostringstream os;
    nnet-> 写(os,二进制);
   Nnet nnet2;
    std :: istringstream是(os.str());
    nnet2。读(是,二进制);
 
    std :: ostringstream os2;
    nnet2。写(os2,二进制);
 
   KALDI_ASSERT(os2.str()== os.str());
   删除 nnet;
  }
◆  UnitTestNnetCompute()
void kaldi :: nnet2 :: UnitTestNnetCompute	(		)	
在文件nnet-compute-test.cc的第29行定义。

参考kaldi :: assertEqual便() ,NnetOnlineComputer ::计算() ,NnetOnlineComputer ::同花顺() ,GenRandomNnet() ,rnnlm ::我,NNET ::信息() ,KALDI_LOG,NNET :: LeftContext() ,NnetComputation(),CuMatrixBase <Real> :: NumCols(),CuMatrixBase <Real> :: NumRows(),Nnet :: RightContext()和CuMatrixBase <Real> :: SetRandn()。

由main()引用。

                             {
    int32 input_dim = 10 + rand()%40,output_dim = 100 + rand()%500;
   bool pad_input =(rand()%2 == 0);
   
   NNET * NNET = GenRandomNnet(input_dim,output_dim);
   KALDI_LOG << “左上下文=” << nnet-> LeftContext()<< “,右上下文=”
              << nnet-> RightContext()<< “,pad-input =” << pad_input;
   KALDI_LOG << “NNet信息是” << nnet-> Info();
    int32 num_feats = 5 + rand()%1000;
   CuMatrix <BaseFloat>输入(num_feats,input_dim);
    input.SetRandn();
 
    int32 num_output_rows = num_feats  -
        (pad_input?0:nnet-> LeftContext()+ nnet-> RightContext());
   if(num_output_rows <= 0)
     回归 ;
   CuMatrix <BaseFloat> output1(num_output_rows,output_dim);
   NnetComputation(* nnet,input,pad_input和output1);
 
   CuMatrix <BaseFloat> output2(output1.NumRows(),output1.NumCols());
    int32 cur_input_pos = 0,cur_output_pos = 0;
 
   NnetOnlineComputer计算机(* nnet,pad_input);
   而(cur_input_pos <= num_feats){
      int32 feats_left = num_feats  -  cur_input_pos;
     CuMatrix <BaseFloat> output_part;
     if(feats_left> 0){
        int32 chunk_size = std :: min <int32>(1 + rand()%10,feats_left);
       CuSubMatrix <BaseFloat> input_part(input,cur_input_pos,chunk_size,
                                          0,input_dim);
        computer.Compute(input_part,&output_part);
        cur_input_pos + = chunk_size;
      } else {
        computer.Flush(&output_part);
        cur_input_pos ++; //将终止循环。
      }
     如果(output_part。numRows行()!= 0){
        output2.Range(cur_output_pos,output_part。numRows行(),
                      0,output_dim).CopyFromMat(output_part);
        cur_output_pos + = output_part。NumRows();
      }
    }  
   AssertEqual(output1,output2);
   for(int32 i = 0; i <output1.NumRows(); i ++){
     //只是仔细检查一下接近结尾的帧是否正确,以防万一
     //尽管如此,上面的测试以某种方式通过了。
     if(i <10 || output1.NumRows() - i <10){
       CuSubVector <BaseFloat> vec1(output1,i),vec2(output2,i);
       AssertEqual(vec1,vec2);
      }
    }
   KALDI_LOG << “OK” ;
   删除 nnet;
  }

 

 

 

 

 

 

 

 UnitTestNnetComputeChunked()
void kaldi :: nnet2 :: UnitTestNnetComputeChunked	(		)	
在文件nnet-compute-test.cc的第84行定义。

引用kaldi :: assertEqual便() ,GenRandomNnet() ,rnnlm ::我,NNET ::信息() ,KALDI_LOG,NNET :: LeftContext() ,NnetComputation() ,NnetComputationChunked() ,MatrixBase <真实> :: numRows行(),Nnet :: RightContext()和CuMatrixBase <Real> :: SetRandn()。

由main()引用。

                                    {
    int32 input_dim = 10 + rand()%40,output_dim = 100 + rand()%500;
   bool pad_input = true ;
   
   NNET * NNET = GenRandomNnet(input_dim,output_dim);
    int32 num_feats = 100 + rand()%500;
    int32 chunk_size = num_feats /(2 + rand()%10);
   CuMatrix <BaseFloat>输入(num_feats,input_dim);
    input.SetRandn();
 
   KALDI_LOG << “左上下文=” << nnet-> LeftContext()
              << “,right context =” << nnet-> RightContext()
              << “,chunk size =” << chunk_size;
   KALDI_LOG << “NNet信息是” << nnet-> Info();
 
    int32 num_output_rows = num_feats;
   CuMatrix <BaseFloat> cu_output1(num_output_rows,output_dim);
   Matrix <BaseFloat> output2(num_output_rows,output_dim);
   NnetComputation(* nnet,input,pad_input,&cu_output1);
   NnetComputationChunked(* nnet,Matrix <BaseFloat>(输入),chunk_size,
                           &output2);
   Matrix <BaseFloat> output1(cu_output1);
   AssertEqual(output1,output2);
   for(int32 i = 0; i <output1.NumRows(); i ++){
     //只需仔细检查结尾附近的帧是否正确,以防万一
     //上面的测试以某种方式通过了尽管如此。
     if(i <10 || output1.NumRows() - i <10){
       SubVector <BaseFloat> vec1(output1,i),vec2(output2,i);
       AssertEqual(vec1,vec2);
      }
    }
   KALDI_LOG << “OK” ;
   删除 nnet;
  }
◆  UnitTestNnetDecodable()
void kaldi :: nnet2 :: UnitTestNnetDecodable	(		)	
在online-nnet2-decodable-test.cc文件的第31行定义。

引用DecodableNnet2OnlineOptions :: acoustic_scale,VectorBase <真实> :: ApplyExp() ,kaldi :: ApproxEqual() ,kaldi :: GenRandContextDependencyLarge() ,GenRandomNnet() ,kaldi :: GetDefaultTopology() ,rnnlm ::我,KALDI_ASSERT,DecodableNnet2Online: :LogLikelihood(),DecodableAmNnet :: LogLikelihood(),DecodableNnet2OnlineOptions :: max_nnet_batch_size,DecodableNnet2Online :: NumFramesReady(),DecodableAmNnet :: NumFramesReady(),TransitionModel :: NumPdfs(),TransitionModel :: NumTransitionIds(),DecodableNnet2OnlineOptions :: pad_input,VectorBase <Real> :: Scale(),AmNnet :: SetPriors(),VectorBase <Real> :: SetRandn(),MatrixBase <Real> :: SetRandn(),以及VectorBase <Real> :: Sum()。

由main()引用。

                               {
    std :: vector <int32>手机;
    phones.push_back(1);
   for(int32 i = 2; i <20; i ++)
     if(rand()%2 == 0)
        phones.push_back(i);
    int32 N = 2 + rand()%2,// context-size N为2或3。
        P = rand()%N;  //中央电话在[0,N]上是随机的
 
    std :: vector <int32> num_pdf_classes;
 
   ContextDependency * ctx_dep =
       GenRandContextDependencyLarge(手机,N,P,
                                     true,&num_pdf_classes);
 
   HmmTopology topo = GetDefaultTopology(电话);
 
   TransitionModel trans_model(* ctx_dep,topo);
 
   删除 ctx_dep; //我们不会再需要这个了。
    ctx_dep = NULL;
 
    int32 input_dim = 40,output_dim = trans_model。NumPdfs();
   NNET * NNET = GenRandomNnet(input_dim,output_dim);
 
   AmNnet am_nnet(* nnet);
   删除 nnet;
    nnet = NULL;
   Vector <BaseFloat> priors(output_dim);
    priors.SetRandn();
    priors.ApplyExp();
    priors.Scale(1.0 / priors.Sum());
 
    am_nnet.SetPriors(先生);
 
   DecodableNnet2OnlineOptions选择;
    选择。max_nnet_batch_size = 20;
    选择。acoustic_scale = 0.1;
 
    选择。pad_input =(rand()%2 == 0);
 
    int32 num_input_frames = 400;
   Matrix <BaseFloat> input_feats(num_input_frames,input_dim);
    input_feats.SetRandn();
 
   OnlineMatrixFeature matrix_feature(input_feats);
 
   DecodableNnet2Online online_decodable(am_nnet,trans_model,
                                          opts,&matrix_feature);
 
   DecodableAmNnet offline_decodable(trans_model,am_nnet,
                                     CuMatrix <BaseFloat>(input_feats),
                                      选择。pad_input,
                                      选择。acoustic_scale);
 
   KALDI_ASSERT(online_decodable.NumFramesReady()==
                 offline_decodable.NumFramesReady());
    int32 num_frames = online_decodable.NumFramesReady(),
        num_tids = trans_model.NumTransitionIds();
 
   for(int32 i = 0; i <50; i ++){
 
      int32 t = rand()%num_frames,tid = 1 + rand()%num_tids;
     BaseFloat l1 = online_decodable.LogLikelihood(t,tid),
          l2 = offline_decodable.LogLikelihood(t,tid);
     KALDI_ASSERT(ApproxEqual(l1,l2));
    }
  }
◆  UnitTestParsing()
void kaldi :: nnet2 :: UnitTestParsing	(		)	
在文件nnet-component-test.cc的第696行定义。

引用rnnlm :: i,KALDI_ASSERT和ParseFromString()。

由main()引用。

                         {
    int32 i ;
   BaseFloat f;
   布尔 b;
    std :: vector <int32> v;
    std :: string s = “x = y” ;
   KALDI_ASSERT(ParseFromString(“foo”,&s,&i)== false
                 && s == “x = y”);
   KALDI_ASSERT(ParseFromString(“foo”,&s,&f)== false
                 && s == “x = y”);
   KALDI_ASSERT(ParseFromString(“foo”,&s,&v)== false
                 && s == “x = y”);
   KALDI_ASSERT(ParseFromString(“foo”,&s,&b)== false
                 && s == “x = y”);
    {
      std :: string s = “x = 1” ;
     KALDI_ASSERT(ParseFromString(“x”,&s,&i)== true
                   && i == 1 && s == “”);
      s = “a = bx = 1” ;
     KALDI_ASSERT(ParseFromString(“x”,&s,&i)== true
                   && i == 1 && s == “a = b”);
    }
    {
      std :: string s = “foo = false” ;
     KALDI_ASSERT(ParseFromString(“foo”,&s,&b)== true
                   && b == false && s == “”);
      s = “x = y foo = true a = b” ;
     KALDI_ASSERT(ParseFromString(“foo”,&s,&b)== true
                   && b == true && s == “x = ya = b”);
    }
 
    {
      std :: string s = “foobar x = 1” ;
     KALDI_ASSERT(ParseFromString(“x”,&s,&f)== true
                   && f == 1.0 && s == “foobar”);
      s = “a = bx = 1 bxy” ;
     KALDI_ASSERT(ParseFromString(“x”,&s,&f)== true
                   && f == 1.0 && s == “a = b bxy”);
    }
    {
      std :: string s = “x = 1:2:3” ;
     KALDI_ASSERT(ParseFromString(“x”,&s,&v)== true
                   && v.size()== 3 && v [0] == 1 && v [1] == 2 && v [2] == 3
                   && s == “”);
      s = “a = bx = 1:2:3 c = d” ;
     KALDI_ASSERT(ParseFromString(“x”,&s,&v)== true
                   && f == 1.0 && s == “a = bc = d”);
    }
 
  }
◆  UnitTestPnormComponent()
void kaldi :: nnet2 :: UnitTestPnormComponent	(		)	
在文件nnet-component-test.cc的第286行定义。

引用rnnlm :: i,KALDI_ERR,KALDI_WARN,kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                {
   //我们正在测试梯度是否正确计算:
   //输入梯度和模型梯度。
 
    int32 num_fail = 0,num_tries = 4;
   for(int32 i = 0; i <num_tries; i ++){
     试试 {
        int32 output_dim = 10 + Rand()%20,
            group_size = 1 + Rand()%10,
            input_dim = output_dim * group_size;
       BaseFloat p = 1.0 + 0.1 *(Rand()%20);
 
       PnormComponent组件(input_dim,output_dim,p);
       UnitTestGenericComponentInternal(component);
      } catch(...){
       KALDI_WARN << “忽略UnitTestPnormComponent()中的测试失败。” ;
        num_fail ++;
      }
    }
   if(num_fail> = num_tries / 2){
     KALDI_ERR << “测试失败太多。” ;
    }
  }
◆  UnitTestPreconditionDirections()
void kaldi :: nnet2 :: UnitTestPreconditionDirections	(		)	
在文件nnet-precondition-test.cc的第26行定义。

引用CuSpMatrix <Real> :: AddMat2(),CuVectorBase <Real> :: AddSpVec(),CuSpMatrix <Real> :: AddVec2(),CuVectorBase <Real> :: ApproxEqual(),CuSpMatrix <Real> :: Invert(),KALDI_ASSERT,kaldi :: kTrans,rnnlm :: n,PreconditionDirections(),kaldi :: Rand(),CuPackedMatrix <Real> :: ScaleDiag(),CuMatrixBase <Real> :: SetRandn()和CuPackedMatrix <Real>: :SetUnit()。

由main()引用。

                                        {
   MatrixIndexT N = 2 + Rand()%30,
                 D = 1 + Rand()%20;
   BaseFloat lambda = 0.1;
   CuMatrix <BaseFloat> R(N,D),P(N,D);
    R.SetRandn();
    P.SetRandn(); //应覆盖内容。
 
   PreconditionDirections(R,lambda,&P);
   //这个函数的其余部分将执行函数正在进行的计算
   //一种不同的,效率较低的方式,并与函数调用进行比较。
   
   CuSpMatrix <BaseFloat> G(D);
    G.SetUnit();
    G.ScaleDiag(lambda);
   // G + = R ^ T R.
    G.AddMat2(1.0 /(N-1),R,kTrans,1.0);
   
   for(int32 n = 0; n <N; n ++){
     CuSubVector <BaseFloat> rn(R,n);
     CuSpMatrix <BaseFloat> Gn(G);
      Gn.AddVec2(-1.0 /(N-1),rn); //减去
     //“this”向量的外积。
      Gn.Invert();
     CuSubVector <BaseFloat> pn(P,n);
     CuVector <BaseFloat> pn_compare(D);
      pn_compare.AddSpVec(1.0,Gn,rn,0.0);
     KALDI_ASSERT(pn.ApproxEqual(pn_compare,0.1));
    }
  }
◆  UnitTestPreconditionDirectionsOnline()
void kaldi :: nnet2 :: UnitTestPreconditionDirectionsOnline	(		)	
在文件nnet-precondition-online-test.cc的第262行定义。

引用CuVectorBase <Real> :: AddDiagMatMat(),MatrixBase <Real> :: AddVecVec(),kaldi :: AssertEqual(),KALDI_ASSERT,kaldi :: kNoTrans,kaldi :: kTrans,CuMatrixBase <Real> :: NumRows(),OnlinePreconditionerSimple :: PreconditionDirections(),OnlinePreconditioner :: PreconditionDirections(),kaldi :: Rand(),kaldi :: RandInt(),VectorBase <Real> :: Scale(),MatrixBase <Real> :: Set(),VectorBase < Real> :: SetRandn(),MatrixBase <Real> :: SetRandn(),OnlinePreconditionerSimple :: SetRank(),OnlinePreconditioner :: SetRank(),kaldi :: TraceMatMat()和OnlinePreconditioner :: TurnOnDebug()。

由main()引用。

                                              {
   MatrixIndexT R = 1 + Rand()%30,   //校正等级
        N =(2 * R)+ Rand()%30,   //批量大小
        D = R + 1 + Rand()%20; //问题维度。必须> R.
 
   //有时使用全零或全一的特征进行测试; 这将
   //帮助确保低级别或零输入不会使代码崩溃。
   bool zero = false ;
   bool one = false ;
   if(Rand()%3 == 0)zero = true ;
   // else if(Rand()%2 == 0)one = true;
 
   CuVector <BaseFloat> row_prod1(N),row_prod2(N);
   BaseFloat gamma1,gamma2 ;
   BaseFloat big_eig_factor = RandInt(1,20);
    big_eig_factor = big_eig_factor * big_eig_factor;
   Vector <BaseFloat> big_eig_vector(D);
    big_eig_vector.SetRandn();
    big_eig_vector.Scale(big_eig_factor);
 
   OnlinePreconditionerSimple preconditioner1;
   OnlinePreconditioner preconditioner2;
    预处理器1。SetRank(R);
    预处理器2。SetRank(R);
    预处理器2。TurnOnDebug();
 
    int32 num_iters = 100;
   for(int32 iter = 0; iter <num_iters; iter ++){
     Matrix <BaseFloat> M_cpu(N,D);
     if(one)M_cpu.Set(1.0);
     否则 if(!zero){
        M_cpu.SetRandn();
       Vector <BaseFloat> rand_vec(N);
        rand_vec.SetRandn();
        M_cpu.AddVecVec(1.0,rand_vec,big_eig_vector);
      }
     CuMatrix <BaseFloat> M(M_cpu);
 
     CuMatrix <BaseFloat> Mcopy1(M),Mcopy2(M);
 
      预处理器1。PreconditionDirections(&Mcopy1,&row_prod1,&gamma1);
 
      预处理器2。PreconditionDirections(&Mcopy2,&row_prod2,&gamma2);
 
     BaseFloat trace1 = TraceMatMat(M,M,kTrans),
          trace2 = TraceMatMat(Mcopy1,Mcopy1,kTrans);
     AssertEqual(trace1,trace2 * gamma2 * gamma2,1.0e-02);
 
     AssertEqual(Mcopy1,Mcopy2);
      AssertEqual <BaseFloat>(row_prod1,row_prod2,1.0e-02);
     AssertEqual(gamma1,gamma2,1.0e -02);
 
     //确保肯定
     CuVector <BaseFloat> inner_prods(M.NumRows());
      inner_prods。AddDiagMatMat(1.0,M,kNoTrans,Mcopy1,kTrans,0.0);
     KALDI_ASSERT(inner_prods.Min()> = 0.0);
    }
   回归 ;
  }
◆  UnitTestScaleComponent()
void kaldi :: nnet2 :: UnitTestScaleComponent	(		)	
在文件nnet-component-test.cc的第461行定义。

引用ScaleComponent :: Init(),ScaleComponent :: InitFromString(),kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                {
    int32 dim = 1 + Rand()%10;
   BaseFloat scale = 0.1 + Rand()%3;
    {
     ScaleComponent组件;
     if(Rand()%2 == 0){
        组件。初始(昏暗,规模);
      } else {
        std :: ostringstream str;
        str << “dim =” << dim << “scale =” << scale;
        组件。InitFromString(str.str());
      }
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UnitTestSigmoidComponent()
void kaldi :: nnet2 :: UnitTestSigmoidComponent	(		)	
在文件nnet-component-test.cc的第227行定义。

引用NonlinearComponent :: InitFromString(),kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                  {
   //我们正在测试渐变是否正确计算:
   //输入渐变和模型渐变。
 
    int32 input_dim = 10 + Rand()%50;
    {
     SigmoidComponent sigmoid_component(input_dim);
     UnitTestGenericComponentInternal(sigmoid_component);
    }
    {
     SigmoidComponent sigmoid_component;
      sigmoid_component。InitFromString(“dim = 15”);
     UnitTestGenericComponentInternal(sigmoid_component);
    }
  }
◆  UnitTestSolvePackingProblem()
void kaldi :: nnet2 :: UnitTestSolvePackingProblem	(		)	
在文件nnet-example-functions-test.cc的第29行定义。

引用rnnlm :: i,rnnlm :: j,KALDI_ASSERT,kaldi :: Rand(),SolvePackingProblem()和kaldi :: SortAndUniq()。

由main()引用。

                                     {
   size_t size = Rand()%20;
    std :: vector <BaseFloat> item_costs;
   for(size_t  i = 0; i <size; i ++){
      item_costs.push_back(0.5 *(Rand()%15));
    }
   BaseFloat max_cost = 0.66 + Rand()%5;
 
    std :: vector <std :: vector <size_t >>组;
   SolvePackingProblem(max_cost,item_costs,&groups);
   
    std :: vector <size_t> all_indices;
   for(size_t  i = 0; i <groups.size(); i ++){
     BaseFloat this_group_cost = 0.0;
     for(size_t  j = 0; j <groups [ i ] .size(); j ++){
       size_t index = groups [ i ] [ j ];
        all_indices.push_back(index);
        this_group_cost + = item_costs [index];
      }
     KALDI_ASSERT(!groups [ i ] .empty());
     KALDI_ASSERT(groups [ i ] .size()== 1 || this_group_cost <= max_cost);
    }
   SortAndUniq(&all_indices);
   KALDI_ASSERT(all_indices.size()== size);
   if(!all_indices.empty())
     KALDI_ASSERT(all_indices.back()+ 1 == size);
  }
◆  UnitTestSpliceComponent()
void kaldi :: nnet2 :: UnitTestSpliceComponent	(		)	
在文件nnet-component-test.cc的第747行定义。

引用rnnlm :: i,SpliceComponent :: Init(),KALDI_LOG,kaldi :: RandInt()和UnitTestGenericComponentInternal()。

由main()引用。

                                 {
    int32 feat_dim = RandInt(1,20),
        const_dim =   RandInt(0,10),
        left_context = RandInt(-5,0),
right_context        = RandInt(0,5),
        num_chunks = RandInt(1,20);
         //需要多个块作为拼接组件
         //为多个块提供单独的索引计算逻辑
   KALDI_LOG << “Feat_dim:” << feat_dim << “const_dim:” << const_dim;
    std :: vector <bool> contiguous(2);
    连续[0] = 真 ;
    连续[1] = 假 ;
   for(int32 i = 0; i <contiguous.size(); i ++){
      std :: vector <int32> splice_indexes;
     if(contiguous [ i ]){
       //在范围内创建连续的拼接索引集
       //(-left_context,right_context)
       KALDI_LOG << “测试连续的拼接组件” ;
        splice_indexes.reserve(right_context  -  left_context + 1);
       for(int32 i = left_context; i <= right_context; i ++)
          splice_indexes.push_back(i);
      } 其他   {
       //生成范围内的随机拼接索引(-left_context,right_context)
       KALDI_LOG << “测试不连续的拼接组件” ;
        int32 num_left_splice_indexes = RandInt(0,-left_context)+ 1;
        int32 num_right_splice_indexes = RandInt(0,right_context);
        splice_indexes.reserve(num_left_splice_indexes + num_right_splice_indexes);
       while(splice_indexes.size()<num_left_splice_indexes){
          int32 new_index = RandInt(left_context,0);
         //检查向量中是否已存在索引
         if(std :: find(splice_indexes.begin(),splice_indexes.end(),new_index)
              == splice_indexes.end()){
            splice_indexes.push_back(new_index);
          }
        }
       while(splice_indexes.size()<num_left_splice_indexes + num_right_splice_indexes){
          int32 new_index = RandInt(0,right_context);
         //检查向量中是否已存在索引
         if(std :: find(splice_indexes.begin(),splice_indexes.end(),new_index)
              == splice_indexes.end()){
            splice_indexes.push_back(new_index);
          }
        }
        sort(splice_indexes.begin(),splice_indexes.end());
       if(splice_indexes.back()<0)//将在组件的init中失败断言
          splice_indexes.push_back(0);
      }
      std :: vector <int32> input_offsets;
     for(int32 i = 0; i <splice_indexes.size(); i ++){
        input_offsets.push_back(splice_indexes [i]  -  splice_indexes.front());
       KALDI_LOG << i << “:” << splice_indexes [ i ] << “:” << input_offsets [ i ];
      }
      int32 output_offset = -splice_indexes.front();
     SpliceComponent * component = new  SpliceComponent();
      component-> Init(feat_dim + const_dim,splice_indexes,const_dim);
     ChunkInfo in_info = ChunkInfo(feat_dim + const_dim,num_chunks,
                                    input_offsets),
                out_info = ChunkInfo(feat_dim * splice_indexes.size()+ const_dim,
                                     num_chunks,output_offset,output_offset);
     UnitTestGenericComponentInternal(* component,in_info,out_info);
     删除组件;
    }
  }
◆  UnitTestSumGroupComponent()
void kaldi :: nnet2 :: UnitTestSumGroupComponent	(		)	
在文件nnet-component-test.cc的第587行定义。

引用rnnlm :: i,SumGroupComponent :: Init(),SumGroupComponent :: InitFromString(),kaldi :: Rand()和UnitTestGenericComponentInternal()。

由main()引用。

                                   {
    std :: vector <int32>个大小;
    int32 num_sizes = 1 + Rand()%5;
   for(int32 i = 0; i <num_sizes; i ++)
      sizes.push_back(1 + Rand()%5);
 
    {
     SumGroupComponent组件;
      组件。初始(大小);
     UnitTestGenericComponentInternal(component);
    }
    {
     const  char * str = “sizes = 3:4:5” ;
     SumGroupComponent组件;
      组件。InitFromString(str);
     UnitTestGenericComponentInternal(component);
    }
  }
◆  UpdateHash()
void UpdateHash	(	const TransitionModel& 	tmodel,
const DiscriminativeNnetExample& 	例如,
的std :: string 	标准,
布尔 	drop_frames,
布尔 	one_silence_class,
矩阵 <double> * 	哈希,
双* 	num_weight,
双* 	den_weight,
双* 	tot_t 
)		
此函数用于测试我们在此提供的功能的代码,关于拆分和删除nnet示例。

它增加了一个“哈希函数”,它是一组例子的函数; 散列函数具有维度(pdf-id的数量x特征维度)。哈希函数由pdf-id上的(分母 - 分子)后验组成,乘以特征上下文窗口(左侧的左上下文,右侧的右上下文)的平均值。这很有用,因为我们所做的各种操作都应该保留它,如果有错误,它很可能会导致哈希函数发生变化。

如果矩阵为空,此函数将调整矩阵的大小。

在调用此函数之前,应完成晶格的任何声学缩放。

'标准'应该是'mmi','mpfe'或'smbr'。

如果使用丢弃框架== true进行MMI,则应将drop_frames设置为true。然后它不会计算分子pdf-id不在分母点阵中的帧的哈希值。

对于较新的可选行为,您可以将one_silence_class设置为true,这将减少已训练模型中的插入(或传统行为的false)。

该函数还将累计用作num_weight和den_weight的总分子和分母权重,用于附加诊断,以及总帧数,如tot_t。

在文件nnet-example-functions.cc的第786行定义。

引用VectorBase <Real> :: AddRowSumMat(),ExampleToPdfPost(),rnnlm :: i,DiscriminativeNnetExample :: input_frames,KALDI_ASSERT,DiscriminativeNnetExample :: left_context,DiscriminativeNnetExample :: num_ali,MatrixBase <Real> :: NumCols(),TransitionModel :: NumPdfs(),MatrixBase <Real> :: NumRows(),Matrix <Real> :: Resize()和MatrixBase <Real> :: Row()。

由main()和SplitExampleStats :: SplitExampleStats()引用。

                     {
    int32 feat_dim = eg.input_frames.NumCols(),
        left_context = eg.left_context,
        num_frames = eg.num_ali.size(),
        right_context = eg.input_frames.NumRows() -  num_frames  -  left_context,
        context_width = left_context + 1 + right_context;
    * tot_t + = num_frames;
   KALDI_ASSERT(right_context > = 0);
   KALDI_ASSERT(hash!= NULL);
   if(hash-> NumRows()== 0){
      hash-> Resize(tmodel.NumPdfs(),feat_dim);
    } else {
     KALDI_ASSERT(hash- > NumRows()== tmodel.NumPdfs()&&
                   hash-> NumCols()== feat_dim);
    }
 
   后柱;
    std :: vector <int32> silence_phones; //我们不让用户指定这个
                                      //因为没有必要进行测试
                                      //目的 - >留空
   ExampleToPdfPost(tmodel,silence_phones,criterion,drop_frames,
                     one_silence_class,例如&post);
 
    Vector <BaseFloat> avg_feat(feat_dim);
   
   for(int32 t = 0; t <num_frames; t ++){
      SubMatrix <BaseFloat> context_window(eg.input_frames,
                                          t,context_width,
                                          0,feat_dim);
     //将avg_feat设置为此帧的上下文窗口的平均值。
      avg_feat.AddRowSumMat(1.0 / context_width,context_window,0.0);
      Vector <double> avg_feat_dbl(avg_feat);
     for(size_t  i = 0; i <post [t] .size(); i ++){
        int32 pdf_id = post [t] [ i ] .first;
       BaseFloat weight = post [t] [ i ] .second;
        hash-> Row(pdf_id).AddVec(weight,avg_feat_dbl);
       if(weight> 0.0)* num_weight + = weight;
       else * den_weight + = -weight;
      }
    }
  }
◆  WidenNnet()
void WidenNnet	(	const NnetWidenConfig& 	widen_config,
Nnet * 	NNET 
)		
此功能通过增加目标的隐藏层尺寸来扩展神经网络。

在文件widen-nnet.cc的第62行定义。

引用NnetWidenConfig :: bias_stddev,Nnet :: Check(),Nnet :: GetComponent(),NnetWidenConfig :: hidden_​​layer_dim,AffineComponent :: InputDim(),KALDI_LOG,Nnet :: NumComponents(),AffineComponent :: OutputDim(),NnetWidenConfig: :param_stddev_factor和AffineComponent :: Widen()。

由main()和NnetWidenConfig :: Register()引用。

                             {
 
    int32 C = nnet-> NumComponents();
    int32 num_widened = 0;
 
   for(int32 c = 0; c <C  -  3; c ++){
      AffineComponent * c1 = dynamic_cast < AffineComponent * >(&(nnet-> GetComponent(c)));
     if(c1 == NULL)继续 ;
      std :: vector <NonlinearComponent *> c2; //通常只有一个元素,但现在允许两个元素。
      c2.push_back(dynamic_cast <NonlinearComponent *>(&(nnet-> GetComponent(c + 1))));
     if(c2.back()== NULL)继续 ;
      c2.push_back(dynamic_cast <NonlinearComponent *>(&(nnet-> GetComponent(c + 2))));
      AffineComponent * c3;
     if(c2.back()== NULL){
        c2.pop_back();
        c3 = dynamic_cast < AffineComponent * >(&(nnet-> GetComponent(c + 2)));
      } else {
       如果(c + 3> = C)继续,则为 ;
        c3 = dynamic_cast < AffineComponent * >(&(nnet-> GetComponent(c + 3)));
      }
     if(c3 == NULL)继续 ;
     BaseFloat param_stddev = widen_config.param_stddev_factor /
          sqrt(1.0 * c1-> InputDim());
     KALDI_LOG << “加宽组件” << c << “from”
                << c1-> OutputDim()<< “to” << widen_config.hidden_​​layer_dim;
     
      c1-> Widen(widen_config.hidden_​​layer_dim,
                param_stddev,widen_config.bias_stddev,
                c2,c3);
      num_widened ++;
    }
    nnet-> Check();
   KALDI_LOG << “ 加宽” << num_widened << “组件。” ;
  }  
可变文档
◆  nnet_example_warned_left
bool nnet_example_warned_left = false
静态的
在文件nnet-example.cc的第156行定义。

◆  nnet_example_warned_right
bool nnet_example_warned_right = false
静态的
在文件nnet-example.cc的第156行定义。

由NnetExample :: NnetExample()引用。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落雪snowflake

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值