音声信号を音声から感情に分類しようとしています。この目的のために、オーディオ信号の MFCC 機能を抽出し、それらを単純なニューラル ネットワーク (PyBrain の BackpropTrainer でトレーニングされた FeedForwardNetwork) にフィードします。残念ながら、結果は非常に悪いです。5 つのクラスから、ネットワークはほとんどの場合、結果として同じクラスを思いつくようです。
私は感情の 5 つのクラスと約 7000 のラベル付きオーディオ ファイルを持っています。これを分割して、各クラスの 80% をネットワークのトレーニングに使用し、20% をネットワークのテストに使用します。
アイデアは、小さなウィンドウを使用し、それらから MFCC 機能を抽出して、多くのトレーニング サンプルを生成することです。評価では、1 つのファイルのすべてのウィンドウが評価され、多数決によって予測ラベルが決定されます。
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] も試しました)
これは、MFCC 機能を抽出するために離散コサイン変換の直前に適用する Melfilter バンクに使用するコードです (ここから取得しました: 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()
より良い予測結果を得るにはどうすればよいですか?