[PYTHON] J'ai essayé de classer les accords de guitare en temps réel en utilisant l'apprentissage automatique

Objectif

Je jouais de la guitare comme passe-temps et je me demandais si l'IA pouvait identifier correctement le son de la guitare. Cette fois, je vais essayer de classer 9 types de code en temps réel en utilisant un réseau neuronal normal et un simple CNN.

environnement

Utilisez Python. Installez les bibliothèques suivantes. ・ Pyaudio ・ Chainer ・ Keras ・ Sklearn ・ Pandas

ordre du jour

  1. Acquisition de la forme d'onde sonore, transformation de Fourier
  2. Neural Network
  3. CNN
  4. Problèmes futurs

1. Acquisition de la forme d'onde sonore, transformation de Fourier

Un programme qui acquiert des formes d'onde vocales en temps réel, effectue une conversion de Fourier, normalise et écrit les résultats dans un fichier csv. Je suis désolé, mais je ne connais pas très bien la transformation de Fourier car je ne suis pas un spécialiste. Il vaut mieux étudier et utiliser le programme car je me suis référé à d'autres articles, mais il semble que cela puisse être facilement fait avec numpy. Après avoir enregistré les formes d'onde de tous les codes dans le fichier csv, étiquetez-les et combinez-les en un seul fichier. Cette fois, nous classons 10 types de spectres de C, D, G, A, Am, F, Fm, B, Bm et l'état silencieux.

data-kakikomi.py


import pyaudio
import numpy as np
import matplotlib.pyplot as plt
import math
import csv
CHUNK = 1024
RATE = 44100 #Fréquence d'échantillonnage
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)

#Normalisation
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') #Changer le fichier pour chaque code
writer = csv.writer(o, lineterminator=',\n')
while stream.is_active():
    try:
        input = stream.read(CHUNK, exception_on_overflow=False)
        #Convertir de tampon en ndarray
        ndarray = np.frombuffer(input, dtype='int16')

        #Transformée de Fourier
        f = np.fft.fft(ndarray)
        
        #la fréquence
        freq = np.fft.fftfreq(CHUNK, d=44100/CHUNK)
        Amp = np.abs(f/(CHUNK/2))**2
        Amp = min_max(Amp)
        writer.writerow(Amp)
        print(Amp)

        #Afficher le spectre après la transformation de Fourier
        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')

La forme d'onde après la conversion de Fourier est affichée comme indiqué dans la figure ci-dessous. スクリーンショット 2020-11-19 0.29.58.png スクリーンショット 2020-11-19 0.30.18.png

  1. Neural Network Ensuite, créez un modèle d'apprentissage à l'aide de 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

#Classe de réseau neuronal par 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

#Lecture des données
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


#La partie requise lors de la lecture des données avec chainer
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)))

#Nombre d'unités et d'époques dans chaque couche
n_in_units = 1024
n_out_units = 10
n_hidden_units = 100
n_epoch = 3000


#Refléter le nombre déterminé d'unités dans le réseau neuronal,
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)

#Partie formation
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"))) #Sortie journal toutes les 10 époques
trainer.extend(extensions.PrintReport( ["epoch", "main/loss", "validation/main/loss", "main/accuracy", "validation/main/accuracy"])) 
#Époque, perte d'apprentissage, perte de test, taux de réponse correcte d'apprentissage, taux de réponse correcte au test, temps écoulé
trainer.extend(extensions.ProgressBar()) #Sortie de la barre de progression
trainer.run()

#Enregistrez le modèle entraîné créé dans la partie formation
serializers.save_npz("model.npz", model)


#Partie test, sortie des résultats
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)

Les résultats appris sont indiqués ci-dessous.

0.6749311294765841

Le NN normal n'est pas très précis.

  1. CNN Ensuite, créez un modèle d'apprentissage à l'aide de keras (CNN)

CNN.py


import numpy as np
#Lecture et prétraitement des données
from keras.utils import np_utils
#Construisez CNN avec des 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'

#Mesure du temps
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]))
#temps de traitement
print("time:{0:.3f}sec".format(time.time() - startTime))

json_string = model.to_json()

model.save('model_CNN.h5')

Les résultats d'apprentissage sont présentés ci-dessous

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

Le taux de réponse correcte était de 94,8%, ce qui était bien meilleur.

Enfin, essayez de classer le code en temps réel avec CNN

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 #Fréquence d'échantillonnage
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)
        #Convertir de tampon en 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')

Lors de la lecture de l'accord C

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

Lors de la lecture de l'accord D

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

Lors de la lecture de l'accord Am

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

Lors de la lecture de l'accord F

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

Lors de la lecture de l'accord Fm

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

Tâches futures

Personnellement, j'ai été surpris que F et Fm puissent être distingués. Actuellement, les données audio ne sont acquises que par la guitare principale, de sorte que la précision diminue en raison des autres guitares et joueurs. Est-ce une tâche future de créer un modèle en augmentant le nombre de données?

Recommended Posts

J'ai essayé de classer les accords de guitare en temps réel en utilisant l'apprentissage automatique
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
J'ai essayé de classer le texte en utilisant TensorFlow
J'ai essayé de décrire le trafic en temps réel avec WebSocket
J'ai essayé de comprendre attentivement la fonction d'apprentissage dans le réseau de neurones sans utiliser la bibliothèque d'apprentissage automatique (deuxième moitié)
J'ai essayé d'organiser les index d'évaluation utilisés en machine learning (modèle de régression)
J'ai essayé de prédire l'évolution de la quantité de neige pendant 2 ans par apprentissage automatique
J'ai essayé d'implémenter diverses méthodes d'apprentissage automatique (modèle de prédiction) en utilisant scicit-learn
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
J'ai essayé d'utiliser Tensorboard, un outil de visualisation pour l'apprentissage automatique
J'ai essayé l'apprentissage automatique pour convertir des phrases en style XX
J'ai essayé d'illustrer le temps et le temps du langage C
[TF] J'ai essayé de visualiser le résultat de l'apprentissage en utilisant Tensorboard
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
J'ai fait un chronomètre en utilisant tkinter avec python
J'ai essayé l'apprentissage automatique avec liblinear
J'ai essayé de comparer la précision des modèles d'apprentissage automatique en utilisant kaggle comme thème.
J'ai essayé l'apprentissage par renforcement avec PyBrain
J'ai essayé l'apprentissage en profondeur avec Theano
[Apprentissage automatique] J'ai essayé de faire quelque chose comme passer des images
J'ai essayé de comprendre l'apprentissage supervisé de l'apprentissage automatique d'une manière facile à comprendre, même pour les ingénieurs serveurs 2
J'ai essayé d'implémenter PLSA en Python
J'ai essayé d'utiliser Azure Speech to Text.
J'ai essayé d'implémenter la permutation en Python
J'ai installé Python 3.5.1 pour étudier l'apprentissage automatique
J'ai essayé d'implémenter PLSA dans Python 2
[Kaggle] J'ai essayé l'apprentissage d'ensemble avec LightGBM
J'ai essayé d'utiliser l'optimisation bayésienne de Python
J'ai essayé d'implémenter ADALINE en Python
J'ai essayé d'implémenter PPO en Python
Comment écrire hors ligne en temps réel J'ai essayé de résoudre E11 avec python
(Apprentissage automatique) J'ai essayé de comprendre attentivement la régression linéaire bayésienne avec l'implémentation
J'ai essayé de classer les nombres de mnist par apprentissage non supervisé [PCA, t-SNE, k-means]
J'ai essayé de visualiser le modèle avec la bibliothèque d'apprentissage automatique low-code "PyCaret"
J'ai essayé de classer Oba Hanana et Otani Emiri par apprentissage profond
J'ai essayé l'histoire courante de l'utilisation du Deep Learning pour prédire la moyenne Nikkei
Comment écrire en temps réel hors ligne J'ai essayé de résoudre E12 avec python
9 étapes pour devenir un expert en apprentissage automatique dans les plus brefs délais [Entièrement gratuit]
Astuces de fourniture de données utilisant deque dans l'apprentissage automatique
J'ai essayé d'intégrer Keras dans TFv1.1
J'ai essayé de synthétiser des fichiers WAV en utilisant Pydub.
[Python] Deep Learning: J'ai essayé d'implémenter Deep Learning (DBN, SDA) sans utiliser de bibliothèque.
Notes sur l'apprentissage automatique (mises à jour de temps en temps)
[Azure] J'ai essayé de créer une machine virtuelle Linux avec Azure de Microsoft Learn
J'ai essayé d'implémenter TOPIC MODEL en Python
J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique.
J'ai essayé de traiter et de transformer l'image et d'élargir les données pour l'apprentissage automatique
Je veux faire du machine learning même sans serveur - Time Series Edition -
[Je veux classer les images à l'aide de Tensorflow] (2) Classifions les images
J'ai essayé de comprendre attentivement la fonction d'apprentissage dans le réseau de neurones sans utiliser la bibliothèque d'apprentissage automatique (première moitié)
J'ai essayé d'implémenter le tri sélectif en python
Un débutant en apprentissage automatique a tenté de créer une IA de jugement Sheltie en un jour
J'ai essayé de classer Hanana Oba et Emiri Otani par apprentissage profond (partie 2)
GTUG Girls + PyLadiesTokyo Meetup Je suis allé au premier machine learning
J'ai essayé de classer les boules de dragon par adaline
J'ai créé un jeu ○ ✕ avec TensorFlow
[Pour les débutants] Introduction à la vectorisation dans l'apprentissage automatique
(Python: OpenCV) J'ai essayé de générer une valeur indiquant la distance entre les régions tout en binarisant la vidéo en temps réel.
[Keras] J'ai essayé de résoudre le problème de classification des zones de type beignet par apprentissage automatique [Étude]