为什么会采用x-vector?
在语音处理中(主流应用在声纹当中),特征采用的是MFCC特征,其中一个维度代表了帧长,通俗来说,对应的是一段语音的长度,另一个维度代表的是每一帧MFCC特征的维数。通常来说语音都采用了DNN,但是DNN需要补0,但是补0的话会把0,参与网络的运算当中,会影响网络的性能,TDNN加embedding(也就是x-vector)操作可以解决0参与到网络运算这一问题。
如图所示,这是一个经典的x-vector的网络结构,前几层为TDNN的处理,segment-level为embedding的方法。
最后输出x-vector。
如下图所示,为TDNN网络的基本架构,经过学习,发现与NLP中语音处理的方式(conv1d)一样。
import tensorflow as tf
length=None#帧长
input=39#MFCC特征维数
x = tf.placeholder(tf.float32,[1,length,input])#输入数据
print(x)
conv1=tf.layers.conv1d(x,32,3,strides=1, padding='valid')#第一层TDNN
print(conv1)
conv2=tf.layers.conv1d(conv1,64,3,strides=2, padding='valid')#第二层TDNN
print(conv1)
输出结果:
Tensor(“Placeholder_3:0”, shape=(1, ?, 39), dtype=float32)
Tensor(“conv1d_3/BiasAdd:0”, shape=(1, ?, 32), dtype=float32)
Tensor(“conv1d_4/BiasAdd:0”, shape=(1, ?, 64), dtype=float32)
输出每一层所得到的一个结果。
其实segment-level很简单,就是对最后一维求了均值与方差,代码操作如下:
mean, variance = tf.nn.moments(conv2, axes=1)
print(mean)
print(variance)
采用了tf.nn.moments,求取均值与方差,所得结果
Tensor(“moments/Squeeze:0”, shape=(1, 64), dtype=float32)
Tensor(“moments/Squeeze_1:0”, shape=(1, 64), dtype=float32)
使不定长的数据变成了128维的数据,最后输出我们的x-vector。
当然,后面的操作(如FC,loss函数等等)还需要自己来解决啦~