Ich habe versucht, die Stimme eines Synchronsprechers in der Praxis des maschinellen Lernens zu identifizieren. Schreiben Sie die Prozedur als Memo auf.
Lassen Sie uns zunächst die Stimme des Synchronsprechers (die Stimme des Radios usw.) lernen und überprüfen, wie genau sie bestimmt werden kann, indem Sie die Stimme als Testdaten einbeziehen. Als nächstes möchte ich testen, ob die Stimme der Animation aus der Stimme des Synchronsprechers vorhergesagt werden kann.
Dieses Mal habe ich ein Radio-Video von 5 Lady Go-Sprachschauspielern auf Nico Nico Video heruntergeladen. Da es sich um .mp4 handelt, konvertieren Sie dies in wav.
ffmpeg -i hoge.mp4 -map 0:1 hoge.wav
Das ist in Ordnung!
Dann wurde diese WAV-Datei in jeweils 30 Sekunden unterteilt.
sox hoge.wav hogehoge.wav trim 0 30 : newfile : restart
Es ist noch nicht vorbei. Von hier aus habe ich den Teil der Eckwechselszene, die Ecke, in der Musik gespielt wurde, und den Teil, in dem die Stimmen anderer Leute enthalten waren, manuell gelöscht. Ich kann jedoch nicht anders, als die Tatsache zu ignorieren, dass immer kleine Musik im Hintergrund abgespielt wird. Wie kann ich den Einfluss dieses Hintergrunds minimieren oder eliminieren?
Die Datenerfassung ist vorerst abgeschlossen!
Sollte die Frequenzintensität nicht die Merkmalsgröße sein? Schnelle Fourier-Transformation! Jedoch, Es ist besser, den Mel-Frequenz-Keptram-Koeffizienten (MFCC) für das praktische maschinelle Lernsystem von O'Reilly zu verwenden! Ich habe das geschrieben, also werde ich es dieses Mal verwenden.
Betrachtet man verschiedene Dinge, so scheint es, dass MFCC als typische Merkmalsgröße in der aktuellen Spracherkennung verwendet wird und die Merkmale der menschlichen Sprachwahrnehmung berücksichtigt werden. Das MFCC scheint jedoch keine Tonhöheninformationen zu enthalten. Es scheint, dass Kepstram die Tonhöhenkomponente extrahieren kann. Vielleicht ist dies eine bessere Feature-Menge, aber ich habe mich vorerst für MFCC entschieden.
Eine Bibliothek namens Takalbox Scikit wird zur Berechnung des MFCC verwendet. Speichern Sie das berechnete Ergebnis als Cache und verwenden Sie es erneut.
from scikits.talkbox.features import mfcc
import scipy
from scipy import io
from scipy.io import wavfile
import glob
import numpy as np
import os
def write_ceps(ceps,fn):
base_fn,ext = os.path.splitext(fn)
data_fn = base_fn + ".ceps"
np.save(data_fn,ceps)
def create_ceps(fn):
sample_rate,X = io.wavfile.read(fn)
ceps,mspec,spec = mfcc(X)
isNan = False
for num in ceps:
if np.isnan(num[1]):
isNan = True
if isNan == False:
write_ceps(ceps,fn)
Irgendwie habe ich die Ursache nicht verstanden, da einige WAV-Dateien von io.wavfile.read (fn) nicht gut gelesen werden konnten. .. Wenn Sie MFCC berechnen, ohne es gut zu lesen, ist das Ergebnis Nan, also ignoriere ich dies.
Der Code zum Lesen der gespeicherten Daten lautet wie folgt. name_list ist eine Liste von Verzeichnisnamen. Dieses Mal habe ich ein Verzeichnis mit den Namen von fünf Lady Go-Sprachschauspielern erstellt und die Daten dort gespeichert.
def read_ceps(name_list,base_dir = BASE_DIRE):
X,y = [],[]
for label,name in enumerate(name_list):
for fn in glob.glob(os.path.join(base_dir,name,"*.ceps.npy")):
ceps = np.load(fn)
num_ceps = len(ceps)
X.append(np.mean(ceps[:],axis=0))
y.append(label)
return np.array(X),np.array(y)
Dieses Mal wurde die Support Vector Machine (SVM) für das Training unter Verwendung der in 2 erstellten Merkmalsmenge verwendet. Der Code ist unten.
import MFCC #Das habe ich in 2 gemacht
from matplotlib.pyplot import specgram
from sklearn.metrics import confusion_matrix
from sklearn.svm import LinearSVC
from sklearn.utils import resample
from matplotlib import pylab
import numpy as np
name_list = ["Uesaka_Sumire","Komatsu_Mikako","Okubo_Rumi","Takamori_Natsumi","Mikami_Shiori"]
x,y = MFCC.read_ceps(name_list)
svc = LinearSVC(C=1.0)
x,y = resample(x,y,n_samples=len(y))
svc.fit(x[150:],y[150:])
prediction = svc.predict(x[:150])
cm = confusion_matrix(y[:150],prediction)
Nachdem ich die Daten gelesen hatte, mischte ich sie mit resample () und versuchte die 151. und nachfolgenden Daten als Lehrerdaten und die 150. und nachfolgenden Daten als Testdaten.
confusion_matrix ist eine gemischte Matrix. Die Verteilung der vorhergesagten Ergebnisse für jedes Etikett wird für die Testdaten angezeigt. Zeichnen wir das Diagramm damit.
Zeichnen wir die korrekte Antwortrate unter Verwendung der gemischten Matrix der in 3 erhaltenen Vorhersageergebnisse. Normalisieren Sie die Werte in der gemischten Matrix, um die richtige Antwortrate zu erhalten.
def normalisation(cm):
new_cm = []
for line in cm:
sum_val = sum(line)
new_array = [float(num)/float(sum_val) for num in line]
new_cm.append(new_array)
return new_cm
Zeichnen Sie das Diagramm.
def plot_confusion_matrix(cm,name_list,name,title):
pylab.clf()
pylab.matshow(cm,fignum=False,cmap='Blues',vmin=0,vmax=1.0)
ax = pylab.axes()
ax.set_xticks(range(len(name_list)))
ax.set_xticklabels(name_list)
ax.xaxis.set_ticks_position("bottom")
ax.set_yticks(range(len(name_list)))
ax.set_yticklabels(name_list)
pylab.title(title)
pylab.colorbar()
pylab.grid(False)
pylab.xlabel('Predict class')
pylab.ylabel('True class')
pylab.grid(False)
pylab.show()
Ergebnis.
Die richtige Antwortrate war 100% und fast 100%, egal wie oft ich es versucht habe.
Versuchen Sie als nächstes die Animationsstimme als Testdaten. Es war jedoch schwierig, Daten zu sammeln, und es wurden nur ein oder zwei Zeichen für jeden Sprachschauspieler gesammelt, und die Anzahl der Daten selbst ist gering (etwa 90 Muster für insgesamt 5 Personen).
Das Ergebnis ist unten.
Es hat überhaupt nicht funktioniert!
Außerdem habe ich die Originalstimme mit der Stimme der Animation als Lehrerdaten getestet.
Das ist natürlich auch nutzlos.
Overlearning ist der Grund, warum die Genauigkeit bei der Unterscheidung der Anime-Stimme sehr schlecht wurde. Standardmäßig hat die Funktion mfcc () nur 13 Koeffizienten im Audio-Frame, was sehr groß ist. Daher wird der Wert, der durch Mitteln jedes Koeffizienten in allen Frames erhalten wird, als Merkmalsgröße verwendet. Mit anderen Worten, die Anzahl der Merkmalsvektoren beträgt 13, und es ist unwahrscheinlich, dass dies zu Überlernen führte.
Daher dachte ich, dass die Verzerrung der verwendeten Daten zu einer Verringerung der Generalisierungsfähigkeit geführt haben könnte. Da alle verwendeten Daten Stimmen im Radio sind, gibt es keinen großen Unterschied in den Frequenzkomponenten, die in jedem Sprachakteur enthalten sind, was möglicherweise zu einer Verringerung der Generalisierungsfähigkeit geführt hat.
Daher habe ich den Lehrerdaten einen Teil der entsprechenden Anime-Stimme hinzugefügt und sie an der verbleibenden Anime-Stimme getestet. Bei den Lehrerdaten ist 2/3 die Stimme des Radios und 1/3 die Stimme der Animation.
Zuerst habe ich die Stimme des Radios getestet.
Die Erkennungsgenauigkeit beträgt nach wie vor fast 100%, und es geht darum, egal wie oft dies durchgeführt wird.
Als nächstes testen wir die Stimme des Anime.
Die Erkennungsgenauigkeit hat sich dramatisch verbessert! Immerhin scheint die Generalisierungsfähigkeit stark eingeschränkt zu sein, weil ich nur mit der Stimme des Radios gelernt habe.
Es stellt sich heraus, dass wir beim maschinellen Lernen immer über die Gefahren des Überlernens nachdenken müssen. Darüber hinaus ist es notwendig, die Generalisierungsfähigkeit genau zu messen. Insofern ist es nicht gut, dass der Klassifikator diesmal nur mit der richtigen Antwortrate bewertet wird. Verwenden Sie zur Bewertung des Klassifikators die Präzisionsrückrufratenkurve oder die ROC-Kurve (wie im Buch angegeben).
O'Reilly Japan Praktisches maschinelles Lernsystem
Recommended Posts