我正在尝试将音频信号从语音分类到情感。为此,我提取音频信号的MFCC特征,并将其馈送到一个简单的神经网络(使用PyBrain中的BackpropTrainer训练的FeedForwardNetwork)。不幸的是,结果非常糟糕。在5个类别中,该网络似乎几乎总是得出相同的类别作为结果。
我有5个情感类别和大约7000个带标签的音频文件,我将它们分成了80%用于训练网络和20%用于测试网络。
想法是使用小窗口并从中提取MFCC特征以生成大量的训练示例。在评估过程中,对一个文件中的所有窗口进行评估,并通过多数表决来决定预测标签。
我有5个情感类别和大约7000个带标签的音频文件,我将它们分成了80%用于训练网络和20%用于测试网络。
想法是使用小窗口并从中提取MFCC特征以生成大量的训练示例。在评估过程中,对一个文件中的所有窗口进行评估,并通过多数表决来决定预测标签。
Training examples per class:
{0: 81310, 1: 60809, 2: 58262, 3: 105907, 4: 73182}
Example of scaled MFCC features:
[ -6.03465056e-01 8.28665733e-01 -7.25728303e-01 2.88611116e-05
1.18677218e-02 -1.65316583e-01 5.67322809e-01 -4.92335095e-01
3.29816126e-01 -2.52946780e-01 -2.26147779e-01 5.27210979e-01
-7.36851560e-01]
Layers________________________: 13 20 5 (also tried 13 50 5 and 13 100 5)
Learning Rate_________________: 0.01 (also tried 0.1 and 0.3)
Training epochs_______________: 10 (error rate does not improve at all during training)
Truth table on test set:
[[ 0. 4. 0. 239. 99.]
[ 0. 41. 0. 157. 23.]
[ 0. 18. 0. 173. 18.]
[ 0. 12. 0. 299. 59.]
[ 0. 0. 0. 85. 132.]]
Success rate overall [%]: 34.7314201619
Success rate Class 0 [%]: 0.0
Success rate Class 1 [%]: 18.5520361991
Success rate Class 2 [%]: 0.0
Success rate Class 3 [%]: 80.8108108108
Success rate Class 4 [%]: 60.8294930876
好的,现在你可以看到结果在各个类之间分布非常糟糕。0和2类从未被预测。我认为这暗示了我的网络或者更可能是我的数据存在问题。
我可以在这里发很多代码,但我认为更有意义的是展示下面的图片,展示我获取MFCC特征的所有步骤。请注意,为了说明,我使用整个信号而没有进行窗口处理。这看起来还好吗?MFCC值非常大,它们不应该小得多吗?(我将它们缩小到[-2,2]并使用minmaxscaler对所有数据进行归一化后再输入到网络中,也尝试过[0,1])
这是我用于应用离散余弦变换从Melfilter bank提取MFCC特征的代码(我从这里获得:stackoverflow):
def freqToMel(freq):
'''
Calculate the Mel frequency for a given frequency
'''
return 1127.01048 * math.log(1 + freq / 700.0)
def melToFreq(mel):
'''
Calculate the frequency for a given Mel frequency
'''
return 700 * (math.exp(freq / 1127.01048 - 1))
def melFilterBank(blockSize):
numBands = int(mfccFeatures)
maxMel = int(freqToMel(maxHz))
minMel = int(freqToMel(minHz))
# Create a matrix for triangular filters, one row per filter
filterMatrix = numpy.zeros((numBands, blockSize))
melRange = numpy.array(xrange(numBands + 2))
melCenterFilters = melRange * (maxMel - minMel) / (numBands + 1) + minMel
# each array index represent the center of each triangular filter
aux = numpy.log(1 + 1000.0 / 700.0) / 1000.0
aux = (numpy.exp(melCenterFilters * aux) - 1) / 22050
aux = 0.5 + 700 * blockSize * aux
aux = numpy.floor(aux) # Arredonda pra baixo
centerIndex = numpy.array(aux, int) # Get int values
for i in xrange(numBands):
start, centre, end = centerIndex[i:i + 3]
k1 = numpy.float32(centre - start)
k2 = numpy.float32(end - centre)
up = (numpy.array(xrange(start, centre)) - start) / k1
down = (end - numpy.array(xrange(centre, end))) / k2
filterMatrix[i][start:centre] = up
filterMatrix[i][centre:end] = down
return filterMatrix.transpose()
我该如何获得更好的预测结果?