[PYTHON] Ich habe versucht, Gitarrenakkorde in Echtzeit mithilfe von maschinellem Lernen zu klassifizieren

Zweck

Ich habe als Hobby Gitarre gespielt und mich gefragt, ob AI den Gitarrensound richtig identifizieren kann. Dieses Mal werde ich versuchen, 9 Codetypen in Echtzeit mithilfe eines normalen neuronalen Netzwerks und eines einfachen CNN zu klassifizieren.

Umgebung

Verwenden Sie Python. Installieren Sie die folgenden Bibliotheken. ・ Pyaudio ・ Chainer ・ Keras ・ Sklearn ・ Pandas

Agenda

  1. Erfassung der Schallwellenform, Fourier-Transformation
  2. Neural Network
  3. CNN
  4. Zukünftige Probleme

1. Erfassung der Schallwellenform, Fourier-Transformation

Ein Programm, das Sprachwellenformen in Echtzeit erfasst, eine Fourier-Konvertierung durchführt, normalisiert und die Ergebnisse in eine CSV-Datei schreibt. Es tut mir leid, aber ich bin mit der Fourier-Transformation nicht sehr vertraut, weil ich kein Spezialist bin. Es ist besser, das Programm zu studieren und zu verwenden, weil ich auf andere Artikel verwiesen habe, aber es scheint, dass es leicht mit Numpy gemacht werden kann. Beschriften Sie die Wellenformen aller Codes in der CSV-Datei und kombinieren Sie sie zu einer Datei. Dieses Mal klassifizieren wir 10 Arten von Spektren von C, D, G, A, Am, F, Fm, B, Bm und dem stillen Zustand.

data-kakikomi.py


import pyaudio
import numpy as np
import matplotlib.pyplot as plt
import math
import csv
CHUNK = 1024
RATE = 44100 #Abtastfrequenz
P = pyaudio.PyAudio()

stream = P.open(format=pyaudio.paInt16, channels=1, rate=RATE, frames_per_buffer=CHUNK, input=True, output=False)
x = np.arange(1,1025,1)
freq = np.linspace(0, RATE, CHUNK)

#Normalisierung
def min_max(x, axis=None):
    min = x.min(axis=axis, keepdims=True)
    max = x.max(axis=axis, keepdims=True)
    result = (x-min)/(max-min)
    return result

o = open('fmcode.csv','a') #Ändern Sie die Datei für jeden Code
writer = csv.writer(o, lineterminator=',\n')
while stream.is_active():
    try:
        input = stream.read(CHUNK, exception_on_overflow=False)
        #Konvertieren Sie von Puffer zu ndarray
        ndarray = np.frombuffer(input, dtype='int16')

        #Fourier-Transformation
        f = np.fft.fft(ndarray)
        
        #Frequenz
        freq = np.fft.fftfreq(CHUNK, d=44100/CHUNK)
        Amp = np.abs(f/(CHUNK/2))**2
        Amp = min_max(Amp)
        writer.writerow(Amp)
        print(Amp)

        #Anzeigespektrum nach Fourier-Transformation
        line, = plt.plot(freq[1:int(CHUNK/2)], Amp[1:int(CHUNK/2)], color='blue')
        plt.pause(0.01)
        plt.ylim(0,1)
        ax = plt.gca()
        ax.set_xscale('log')
        line.remove()
    except KeyboardInterrupt:
        break

stream.stop_stream()
stream.close()
P.terminate()
f.close()

print('Stop Streaming')

Die Wellenform nach der Fourier-Konvertierung wird wie in der folgenden Abbildung dargestellt angezeigt. スクリーンショット 2020-11-19 0.29.58.png スクリーンショット 2020-11-19 0.30.18.png

  1. Neural Network Erstellen Sie als Nächstes ein Lernmodell mit Chainer (NN).

chainer_NN.py


import chainer
from chainer import Chain, optimizers, iterators, training, datasets, Variable
from chainer.training import extensions
import chainer.functions as F
import chainer.links as L
import numpy as np
import pandas as pd
from chainer import serializers
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

#Neuronale Netzklasse von Chainer
class NN(Chain):
    def __init__(self, in_size, hidden_size, out_size):
        super(NN, self).__init__(
            xh = L.Linear(in_size, hidden_size),
            hh = L.Linear(hidden_size, hidden_size),
            hy = L.Linear(hidden_size, out_size)
        )
    
    def __call__(self, x):
        h1 = F.sigmoid(self.xh(x))
        #h1 = F.dropout(F.relu(self.xh(x)), train=train)
        h2 = F.sigmoid(self.hh(h1))
        y = F.softmax(self.hy(h2))
        return y

#Daten gelesen
data1 = pd.read_csv("data.csv")
X = data1.iloc[:, 0:1024] #140 #no_outline:106
Y = data1.iloc[:, 1025] #↑+2
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.1, random_state = 0)

X_train = X_train.values
Y_train = Y_train.values

X_test = X_test.values
Y_test = Y_test.values


#Der Teil, der beim Lesen von Daten mit Chainer benötigt wird
X_train = np.array(X_train.astype(np.float32))
Y_train = np.ndarray.flatten(np.array(Y_train.astype(np.int32)))

X_test = np.array(X_test.astype(np.float32))
Y_test = np.ndarray.flatten(np.array(Y_test.astype(np.int32)))

#Anzahl der Einheiten und Epochen in jeder Schicht
n_in_units = 1024
n_out_units = 10
n_hidden_units = 100
n_epoch = 3000


#Reflektieren Sie die bestimmte Anzahl von Einheiten im neuronalen Netzwerk.
model = L.Classifier(NN(in_size = n_in_units, hidden_size = n_hidden_units, out_size = n_out_units))
optimizer = optimizers.Adam()
optimizer.setup(model)

#Trainingsteil
print("Train")
train, test = datasets.split_dataset_random(datasets.TupleDataset(X_train, Y_train), int(len(Y_train)*0.9))
train_iter = iterators.SerialIterator(train, int(len(Y_train)*0.9))
test_iter = iterators.SerialIterator(test, int(len(Y_train)*0.1), False, False)
updater = training.StandardUpdater(train_iter, optimizer, device=-1)
trainer = training.Trainer(updater, (n_epoch, "epoch"), out="result")
trainer.extend(extensions.Evaluator(test_iter, model, device=-1))
trainer.extend(extensions.LogReport(trigger=(10, "epoch"))) #Protokollausgabe alle 10 Epochen
trainer.extend(extensions.PrintReport( ["epoch", "main/loss", "validation/main/loss", "main/accuracy", "validation/main/accuracy"])) 
#Epoche, Lernverlust, Testverlust, Lernen der richtigen Antwortrate, Testen der richtigen Antwortrate, verstrichene Zeit
trainer.extend(extensions.ProgressBar()) #Fortschrittsbalkenausgabe
trainer.run()

#Speichern Sie das im Trainingsteil erstellte trainierte Modell
serializers.save_npz("model.npz", model)


#Testteil, Ergebnisausgabe
C_list1 = []
print("Test")
print("y\tpredict")
for i in range(len(X_test)):
    x = Variable(X_test[i])
    y_ = np.argmax(model.predictor(x=x.reshape(1,len(x))).data, axis=1)
    y = Y_test[i]
    print(y+2, "\t", y_+2)
    C = y_ - y
    C_list1 = np.append(C_list1,C)
A = np.count_nonzero(C_list1 == 0)
p = A / (len(C_list1))
print(p)

Die gelernten Ergebnisse sind unten gezeigt.

0.6749311294765841

Normales NN ist nicht sehr genau.

  1. CNN Erstellen Sie als Nächstes ein Lernmodell mit Keras (CNN).

CNN.py


import numpy as np
#Lesen und Vorverarbeiten von Daten
from keras.utils import np_utils
#Baue CNN mit Keras
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split
import pandas as pd
import time

f_model = './model'

#Zeitmessung
import time
correct = 10
data = pd.read_csv("data.csv")
X = data.iloc[:, 0:1024]
Y = data.iloc[:, 1025]

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.1, random_state = 0)
X_train = X_train.to_numpy()
X_train = X_train.reshape(3264,32,32,1)
X_train = X_train.astype('float32')

Y_train = Y_train.to_numpy()
Y_train = np_utils.to_categorical(Y_train, correct)

X_test = X_test.to_numpy()
X_test = X_test.reshape(363,32,32,1)
X_test = X_test.astype('float32')

Y_test = Y_test.to_numpy() 
Y_test = np_utils.to_categorical(Y_test, correct)

model = Sequential()

model.add(Conv2D(filters=10, kernel_size=(3,3),padding='same', input_shape=(32,32,1), activation='relu'))
model.add(Conv2D(32,1,activation='relu'))
model.add(Conv2D(64,1,activation='relu'))
model.add(Flatten())
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])

startTime = time.time()

history = model.fit(X_train, Y_train, epochs=200, batch_size=100, verbose=1, validation_data=(X_test, Y_test))
 
score = model.evaluate(X_test, Y_test, verbose=0)

print('Test Loss:{0:.3f}'.format(score[0]))
print('Test accuracy:{0:.3}'.format(score[1]))
#Verarbeitungszeit
print("time:{0:.3f}sec".format(time.time() - startTime))

json_string = model.to_json()

model.save('model_CNN.h5')

Die Lernergebnisse sind unten aufgeführt

Test Loss:0.389
Test accuracy:0.948
time:327.122sec

Die korrekte Rücklaufquote lag bei 94,8%, was viel besser war.

Versuchen Sie schließlich, den Code in Echtzeit mit CNN zu klassifizieren

code_detector.py


from keras.models import load_model
import pyaudio
import numpy as np
import matplotlib.pyplot as plt
import math

CHUNK = 1024
RATE = 44100 #Abtastfrequenz
P = pyaudio.PyAudio()

stream = P.open(format=pyaudio.paInt16, channels=1, rate=RATE, frames_per_buffer=CHUNK, input=True, output=False)

def min_max(x, axis=None):
    min = x.min(axis=axis, keepdims=True)
    max = x.max(axis=axis, keepdims=True)
    result = (x-min)/(max-min)
    return result

model = load_model('model_CNN.h5')

def detect(pred):
    a = ["C","D","G","Bm","B","","A","Am","F","Fm"]
    pred_label = a[np.argmax(pred[0])]
    score = np.max(pred)
    if pred_label != "":
        print(pred_label,score)

while stream.is_active():
    try:
        input = stream.read(CHUNK, exception_on_overflow=False)
        #Konvertieren Sie von Puffer zu ndarray
        ndarray = np.frombuffer(input, dtype='int16')
        line, = plt.plot(ndarray, color='blue')
        plt.pause(0.01)
        f = np.fft.fft(ndarray)
        Amp = np.abs(f/(CHUNK/2))**2
        Amp = min_max(Amp)
        Amp = Amp.reshape(1,32,32,1)
        Amp = Amp.astype('float32')
        pred = model.predict(Amp)
        
        detect(pred)
        plt.ylim(-200,200)
        line.remove()
    except KeyboardInterrupt:
        break

stream.stop_stream()
stream.close()
P.terminate()
print('Stop Streaming')

Beim Spielen des C-Akkords

C 1.0
C 1.0
C 1.0
C 1.0
C 1.0
C 1.0
C 1.0
C 1.0
C 1.0
C 0.99999833
C 1.0
C 0.9999988
C 1.0
C 1.0
C 1.0
G 0.98923177

Beim Spielen des D-Akkords

D 0.9921374
D 1.0
D 1.0
D 1.0
D 1.0
D 1.0
D 0.99915206
Bm 0.9782265
D 1.0
D 0.967693
Bm 0.43872046
D 0.5228199
D 0.9998678
D 0.99264586

Beim Spielen des Am-Akkords

A 0.7428425
Am 0.98781455
Am 1.0
Am 1.0
Am 1.0
Am 1.0
Am 0.99081403
Am 0.9998661
Am 0.98926556
Am 0.9721039
Am 0.9999999
Am 0.99899584
A 0.7681879
Am 0.59727216
Am 0.77573067

Beim Spielen des F-Akkords

Fm 0.54534096
F 1.0
F 0.4746885
F 0.99983275
F 0.9708171
F 1.0
F 0.9999441
F 0.99999964
C 0.50546944
F 0.9999746
F 1.0
F 1.0
F 0.9999999
F 0.966004
C 0.79529727
F 1.0
F 0.99999976

Beim Spielen des FM-Akkords

Fm 0.9999492
Fm 1.0
Fm 1.0
Fm 0.99058926
Fm 1.0
Fm 0.99991775
Fm 0.9677996
F 0.96835506
Fm 1.0
Fm 0.9965939
Am 0.63923794
C 0.8398564
Fm 0.91774964
Am 0.9995415

Zukünftige Aufgaben

Persönlich war ich überrascht, dass F und Fm unterschieden werden konnten. Derzeit werden die Audiodaten nur von der Hauptgitarre erfasst, sodass die Genauigkeit aufgrund anderer Gitarren und Player abnimmt. Ist es eine zukünftige Aufgabe, ein Modell zu erstellen, indem die Anzahl der Daten erhöht wird?

Recommended Posts

Ich habe versucht, Gitarrenakkorde in Echtzeit mithilfe von maschinellem Lernen zu klassifizieren
Ich habe versucht, das Bild mithilfe von maschinellem Lernen zu komprimieren
Ich habe versucht, Text mit TensorFlow zu klassifizieren
Ich habe versucht, den Datenverkehr mit WebSocket in Echtzeit zu beschreiben
Ich habe versucht, die Lernfunktion im neuronalen Netzwerk sorgfältig zu verstehen, ohne die Bibliothek für maschinelles Lernen zu verwenden (zweite Hälfte).
Ich habe versucht, die beim maschinellen Lernen verwendeten Bewertungsindizes zu organisieren (Regressionsmodell).
Ich habe versucht, die Veränderung der Schneemenge für 2 Jahre durch maschinelles Lernen vorherzusagen
Ich habe versucht, verschiedene Methoden für maschinelles Lernen (Vorhersagemodell) mithilfe von Scicit-Learn zu implementieren
Ich habe versucht, maschinelles Lernen (Objekterkennung) mit TouchDesigner zu verschieben
Ich habe versucht, Tensorboard zu verwenden, ein Visualisierungstool für maschinelles Lernen
Ich habe versucht, durch maschinelles Lernen Sätze in den XX-Stil umzuwandeln
Ich habe versucht, die Zeit und die Zeit der C-Sprache zu veranschaulichen
[TF] Ich habe versucht, das Lernergebnis mit Tensorboard zu visualisieren
[Maschinelles Lernen] Ich habe versucht, die Theorie von Adaboost zusammenzufassen
Ich habe eine Stoppuhr mit tkinter mit Python gemacht
Ich habe maschinelles Lernen mit liblinear versucht
Ich habe versucht, die Genauigkeit von Modellen für maschinelles Lernen mit Kaggle als Thema zu vergleichen.
Ich habe versucht, mit PyBrain verstärkt zu lernen
Ich habe versucht, mit Theano tief zu lernen
[Maschinelles Lernen] Ich habe versucht, so etwas wie Bilder weiterzugeben
Ich habe versucht, das überwachte Lernen des maschinellen Lernens auch für Serveringenieure auf leicht verständliche Weise zu verstehen 2
Ich habe versucht, PLSA in Python zu implementieren
Ich habe versucht, Azure Speech to Text zu verwenden.
Ich habe versucht, Permutation in Python zu implementieren
Ich habe Python 3.5.1 installiert, um maschinelles Lernen zu studieren
Ich habe versucht, PLSA in Python 2 zu implementieren
[Kaggle] Ich habe versucht, Ensemble mit LightGBM zu lernen
Ich habe versucht, die Bayes'sche Optimierung von Python zu verwenden
Ich habe versucht, ADALINE in Python zu implementieren
Ich habe versucht, PPO in Python zu implementieren
Wie man offline in Echtzeit schreibt Ich habe versucht, E11 mit Python zu lösen
(Maschinelles Lernen) Ich habe versucht, die Bayes'sche lineare Regression bei der Implementierung sorgfältig zu verstehen
Ich habe versucht, die Anzahl der Mnisten durch unbeaufsichtigtes Lernen zu klassifizieren [PCA, t-SNE, k-means]
Ich habe versucht, das Modell mit der Low-Code-Bibliothek für maschinelles Lernen "PyCaret" zu visualisieren.
Ich habe versucht, Oba Hanana und Otani Emiri durch tiefes Lernen zu klassifizieren
Ich habe die übliche Geschichte ausprobiert, Deep Learning zu verwenden, um den Nikkei-Durchschnitt vorherzusagen
Wie man offline in Echtzeit schreibt Ich habe versucht, E12 mit Python zu lösen
9 Schritte, um in kürzester Zeit Experte für maschinelles Lernen zu werden [Völlig kostenlos]
Datenversorgungstricks mit deque beim maschinellen Lernen
Ich habe versucht, Keras in TFv1.1 zu integrieren
Ich habe versucht, WAV-Dateien mit Pydub zu synthetisieren.
[Python] Deep Learning: Ich habe versucht, Deep Learning (DBN, SDA) ohne Verwendung einer Bibliothek zu implementieren.
Hinweise zum maschinellen Lernen (von Zeit zu Zeit aktualisiert)
[Azure] Ich habe versucht, eine virtuelle Linux-Maschine mit Azure von Microsoft Learn zu erstellen
Ich habe versucht, TOPIC MODEL in Python zu implementieren
Ich habe versucht, das Vorhandensein oder Nichtvorhandensein von Schnee durch maschinelles Lernen vorherzusagen.
Ich habe versucht, das Bild zu verarbeiten und zu transformieren und die Daten für maschinelles Lernen zu erweitern
Ich möchte maschinelles Lernen auch ohne Server durchführen - Time Series Edition -
[Ich möchte Bilder mit Tensorflow klassifizieren] (2) Lassen Sie uns Bilder klassifizieren
Ich habe versucht, die Lernfunktion im neuronalen Netzwerk sorgfältig zu verstehen, ohne die Bibliothek für maschinelles Lernen zu verwenden (erste Hälfte).
Ich habe versucht, eine selektive Sortierung in Python zu implementieren
Ein Anfänger des maschinellen Lernens versuchte an einem Tag, eine Sheltie-Urteils-KI zu erstellen
Ich habe versucht, Hanana Oba und Emiri Otani durch tiefes Lernen zu klassifizieren (Teil 2)
GTUG Girls + PyLadiesTokyo Meetup Ich ging zum ersten maschinellen Lernen
Ich habe versucht, Drachenkugeln nach Adalin zu klassifizieren
Ich habe ein ○ ✕ Spiel mit TensorFlow gemacht
[Für Anfänger] Einführung in die Vektorisierung beim maschinellen Lernen
(Python: OpenCV) Ich habe versucht, einen Wert auszugeben, der den Abstand zwischen Regionen angibt, während das Video in Echtzeit binärisiert wurde.
[Keras] Ich habe versucht, das Problem der Klassifizierung des Donut-Typ-Bereichs durch maschinelles Lernen zu lösen. [Studie]