将特征在xvector神经网络模型中前向传播,并写出输出向量。我们将说话人识别的特定神经网络结构的输出向量或embedding称之为"Xvector"。该网络结构包括:帧级别的多个前馈层、帧级别之上的聚合层、统计池化层以及段级别的附加层。通常在统计池化层之后的输出层提取xvector。默认情况下,每个语句生成一个xvector。根据需要,可以chunk中提取多个xvector并求平均,以生成单个矢量。

 
 

Usage: nnet3-xvector-compute [options] <raw-nnet-in> <features-rspecifier> <vector-wspecifier>

e.g.: nnet3-xvector-compute final.raw scp:feats.scp ark:nnet_prediction.ark

 
 

对一个语音特征chunk,生成一个xvector

static void RunNnetComputation(const MatrixBase<BaseFloat> &features,

const Nnet &nnet, CachingOptimizingCompiler *compiler,

Vector<BaseFloat> *xvector) {

ComputationRequest request;

request.need_model_derivative = false;

request.store_component_stats = false;

request.inputs.push_back(

IoSpecification("input", 0, features.NumRows()));

IoSpecification output_spec;

output_spec.name = "output";

output_spec.has_deriv = false;

 
 

将output-node所请求的输出Cindex索引数限制为1,这样,一个chunk(segment)只输出一个结果,即xvector

output_spec.indexes.resize(1);

 
 

request.outputs.resize(1);

request.outputs[0].Swap(&output_spec);

std::shared_ptr<const NnetComputation> computation(std::move(compiler->Compile(request)));

Nnet *nnet_to_update = NULL; // we're not doing any update.

NnetComputer computer(NnetComputeOptions(), *computation,

nnet, nnet_to_update);

CuMatrix<BaseFloat> input_feats_cu(features);

computer.AcceptInput("input", &input_feats_cu);

computer.Run();

CuMatrix<BaseFloat> cu_output;

//输出的cu_output为行数为1的矩阵

computer.GetOutputDestructive("output", &cu_output);

xvector->Resize(cu_output.NumCols());

//取输出矩阵的第一行向量作为xvector

xvector->CopyFromVec(cu_output.Row(0));

}

 
 

ParseOptions po(usage);

Timer timer;

 
 

NnetSimpleComputationOptions opts;

CachingOptimizingCompilerOptions compiler_config;

 
 

opts.acoustic_scale = 1.0; // by default do no scaling in this recipe.

 
 

std::string use_gpu = "no";

int32 chunk_size = -1,

min_chunk_size = 100;

//若帧组不足一个chunk,则对input进行左右padding。

bool pad_input = true;

 
 

opts.Register(&po);

compiler_config.Register(&po);

 
 

po.Register("use-gpu", &use_gpu,

"yes|no|optional|wait, only has effect if compiled with CUDA");

po.Register("chunk-size", &chunk_size,

"If set, extracts xectors from specified chunk-size, and averages. "

"If not set, extracts an xvector from all available features.");

po.Register("min-chunk-size", &min_chunk_size,

"Minimum chunk-size allowed when extracting xvectors.");

po.Register("pad-input", &pad_input, "If true, duplicate the first and "

"last frames of the input features as required to equal min-chunk-size.");

 
 

po.Read(argc, argv);

 
 

if (po.NumArgs() != 3) {

po.PrintUsage();

exit(1);

}

 
 

#if HAVE_CUDA==1

CuDevice::Instantiate().SelectGpuId(use_gpu);

#endif

 
 

std::string nnet_rxfilename = po.GetArg(1),

feature_rspecifier = po.GetArg(2),

vector_wspecifier = po.GetArg(3);

 
 

Nnet nnet;

ReadKaldiObject(nnet_rxfilename, &nnet);

SetBatchnormTestMode(true, &nnet);

SetDropoutTestMode(true, &nnet);

CollapseModel(CollapseModelConfig(), &nnet);

 
 

CachingOptimizingCompiler compiler(nnet, opts.optimize_config, compiler_config);

 
 

BaseFloatVectorWriter vector_writer(vector_wspecifier);

 
 

int32 num_success = 0, num_fail = 0;

int64 frame_count = 0;

int32 xvector_dim = nnet.OutputDim("output");

 
 

SequentialBaseFloatMatrixReader feature_reader(feature_rspecifier);

for (; !feature_reader.Done(); feature_reader.Next()) {

std::string utt = feature_reader.Key();

const Matrix<BaseFloat> &features (feature_reader.Value());

if (features.NumRows() == 0) {

KALDI_WARN << "Zero-length utterance: " << utt;

num_fail++;

continue;

}

int32 num_rows = features.NumRows(),

feat_dim = features.NumCols(),

this_chunk_size = chunk_size;

if (!pad_input && num_rows < min_chunk_size) {

KALDI_WARN << "Minimum chunk size of " << min_chunk_size

<< " is greater than the number of rows "

<< "in utterance: " << utt;

num_fail++;

continue;

} else if (num_rows < chunk_size) {

KALDI_LOG << "Chunk size of " << chunk_size << " is greater than "

<< "the number of rows in utterance: " << utt

<< ", using chunk size of " << num_rows;

this_chunk_size = num_rows;

} else if (chunk_size == -1) {

this_chunk_size = num_rows;

}

//num_chunks=1

int32 num_chunks = ceil(

num_rows / static_cast<BaseFloat>(this_chunk_size));

Vector<BaseFloat> xvector_avg(xvector_dim, kSetZero);

BaseFloat tot_weight = 0.0;

 
 

// Iterate over the feature chunks.

for (int32 chunk_indx = 0; chunk_indx < num_chunks; chunk_indx++) {

//若接近输入的末尾,需要考虑剩余的帧是否足以凑足一个chunk。

int32 offset = std::min(

this_chunk_size, num_rows - chunk_indx * this_chunk_size);

if (!pad_input && offset < min_chunk_size)

continue;

SubMatrix<BaseFloat> sub_features(

features, chunk_indx * this_chunk_size, offset, 0, feat_dim);

Vector<BaseFloat> xvector;

tot_weight += offset;

 
 

// Pad input if the offset is less than the minimum chunk size

if (pad_input && offset < min_chunk_size) {

Matrix<BaseFloat> padded_features(min_chunk_size, feat_dim);

int32 left_context = (min_chunk_size - offset) / 2;

int32 right_context = min_chunk_size - offset - left_context;

for (int32 i = 0; i < left_context; i++) {

padded_features.Row(i).CopyFromVec(sub_features.Row(0));

}

for (int32 i = 0; i < right_context; i++) {

padded_features.Row(min_chunk_size - i - 1).CopyFromVec(sub_features.Row(offset - 1));

}

padded_features.Range(left_context, offset, 0, feat_dim).CopyFromMat(sub_features);

//一个chunk生成一个xvector

RunNnetComputation(padded_features, nnet, &compiler, &xvector);

} else {

RunNnetComputation(sub_features, nnet, &compiler, &xvector);

}

//将所有chunk的xvectors进行累加

xvector_avg.AddVec(offset, xvector);

}

//求所有chunk的平均xvector

xvector_avg.Scale(1.0 / tot_weight);

vector_writer.Write(utt, xvector_avg);

 
 

frame_count += features.NumRows();

num_success++;

}

  

 

nnet3bin/nnet3-xvector-compute.cc的更多相关文章

  1. openStack kilo 手动Manual部署随笔记录

    一 ,基于neutron网络资源主机(控制节点,网络节点,计算节点)网络规划配置 1, controller.cc 节点 网络配置截图

  2. World Finals 2017

    Need for Speed   Sheila is a student and she drives a typical student car: it is old, slow, rusty, a ...

  3. 图像匹配 | NCC 归一化互相关损失 | 代码 + 讲解

    文章转载自:微信公众号「机器学习炼丹术」 作者:炼丹兄(已授权) 作者联系方式:微信cyx645016617(欢迎交流共同进步) 本次的内容主要讲解NCCNormalized cross-correl ...

  4. Xvector in Kaldi nnet3

    Xvector nnet Training of Xvector nnet Xvector nnet in Kaldi     Statistics Extraction Layer in Kaldi ...

  5. [CC]区域生长算法——点云分割

    基于CC写的插件,利用PCL中算法实现: void qLxPluginPCL::doRegionGrowing() { assert(m_app); if (!m_app) return; const ...

  6. [CC]点云密度计算

    包括两种计算方法:精确计算和近似计算(思考:local density=单位面积的点数 vs  local density =1/单个点所占的面积) 每种方法可以实现三种模式的点云密度计算,CC里面的 ...

  7. Atitti.dw cc 2015 绿色版本安装总结

    Atitti.dw cc 2015 绿色版本安装总结 1.1. 安装程序无法初始化.请下载adobe Support Advisor检测该问题.1 1.1.1. Adobe Application M ...

  8. C#中DataTable中的Compute方法使用收集

    原文: C#中DataTable中的Compute方法使用收集 Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式,关于Expression的详 ...

  9. 【Hello CC.NET】CC.NET 实现自动化集成

    一.背景 公司的某一金融项目包含 12 个子系统,新需求一般按分支来开发,测完后合并到主干发布.开发团队需要同时维护开发环境.测试环境.模拟环境(主干).目前面临最大的两个问题: 1.子系统太多,每次 ...

随机推荐

  1. Linux实战教学笔记51:Zabbix监控平台3.2.4(三)生产环境案例

    https://www.cnblogs.com/chensiqiqi/p/9162986.html 一,Zabbix生产环境监测案例概述 1.1 项目规划 [x] :主机分组 交换机 Nginx To ...

  2. C# — 实现软件开机自启功能(不需要管理员权限)

    因为最近项目需要,昨晚花了2个小时的时间,在网上搜索资料,通过C#实现了程序开机自启的功能,思路是:将软件的快捷方式创建到计算机的自动启动目录下就行了. 1.新建一个控制台项目:AutoStart 2 ...

  3. Python#常用的模块和简单用法

    目录 random 随机模块 os 文件夹模块: time 时间模块: matplotlab.pyplot 作图模块 mpl_toolkits.mplot3d 绘制3D图模块 Pygame Reque ...

  4. Vue-项目打包上线

    一.打包生成dist目录 运行npm run build 进行打包,控制台显示“Build complete”表示打包完成了. npm run build 二.dist目录放到后端跟目录 打包后生成一 ...

  5. 关于mysql中unique的插入Duplicate key

    MySQL数据库中 如果在后台中不做判断是否unique的column是否存在的话,直接把数据操作给dao层再传给DB的话,就会报重复的唯一值.如果确实是不希望先取出判断unique的column是否 ...

  6. hdu-1052(贪心)

    链接 [https://vjudge.net/contest/261555#problem/I] 题意 就是两个人都有n匹马,每只马都有战力 第二个人出马的顺序是战力大到小,请问第一个人采取怎样的策略 ...

  7. 安装VM-tools

    win10系统 VMware12 Ubuntu64位安装VM-tools时所遇到的提示信息: open-vm-tools are available from the OS vendor and VM ...

  8. Kubernetes一键部署利器:kubeadm

    要真正发挥容器技术的实力,你就不能仅仅局限于对 Linux 容器本身的钻研和使用. 这些知识更适合作为你的技术储备,以便在需要的时候可以帮你更快的定位问题,并解决问题. 而更深入的学习容器技术的关键在 ...

  9. PHP 5.0~5.6 各版本兼容性的 cURL 文件上传

    不同版本PHP之间cURL的区别 PHP的cURL支持通过给CURL_POSTFIELDS传递关联数组(而不是字符串)来生成multipart/form-data的POST请求. 传统上,PHP的cU ...

  10. Window下搭建X5本地应用打包服务器

    总的来说就是安装虚拟机,装载VM文件 X5打包服务器(App-Builder)是通过服务方式把X5开发工具(Studio)创建的本地应用进行打包和数字签名,开发者不用单独构建原生代码的编译环境,方便开 ...