[PYTHON] J'ai essayé d'identifier la langue en utilisant CNN + Melspectogram

Qu'est-ce que l'identification de la langue?

En un mot, pour identifier la langue à partir des données vocales. Par exemple, des données vocales "Bonjour, beau temps" à "Ces données vocales sont en japonais!" D'après les données vocales "Buenas Tardes", on a l'impression que "Ces données vocales sont en espagnol!".

L'utilisation prévue est d'identifier la langue d'une personne qui ne sait pas quelle langue elle parle. Il semble que les traducteurs automatiques existants doivent essentiellement donner des informations telles que «anglais» et «espagnol» à l'avance. Par conséquent, il n'y a aucun moyen de le traduire pour quelqu'un qui ne sait pas quelle langue il parle. (Je pense.)

Donc pour ceux qui ne savent pas quelle langue ils parlent Identifier la langue à l'aide de l'identification de la langue → Traduire Il est utilisé comme ça. (Je pense.)

Raisons d'utiliser CNN

Il existe différentes méthodes d'identification de la langue, mais cette fois j'ai essayé d'utiliser CNN. La raison en est que j'ai trouvé un article en anglais facile à comprendre. (http://yerevann.github.io/2015/10/11/spoken-language-identification-with-deep-convolutional-networks/)

Cet article semble avoir été classé 10e au concours d'identification linguistique organisé en 2015 par le meilleur codeur, alors je l'ai essayé après mes études.

Ensemble de données utilisé

Dans l'article ci-dessus, le problème était de classer 66 176 fichiers MP3 de 10 secondes préparés à l'avance dans 176 langues.

Mais cette fois, je suis VoxForge (http://www.voxforge.org/) J'ai utilisé des fichiers audio au format wav en anglais, français et espagnol, dont je me suis procuré. Vous pouvez télécharger chacun à partir de l'URL suivante. Je l'ai obtenu avec la commande wget en raison de la grande quantité de données audio.

http://www.repository.voxforge1.org/downloads/SpeechCorpus/Trunk/Audio/Main/16kHz_16bit/
http://www.repository.voxforge1.org/downloads/fr/Trunk/Audio/Main/16kHz_16bit/
http://www.repository.voxforge1.org/downloads/es/Trunk/Audio/Main/16kHz_16bit/

Prétraitement

Puisqu'il utilise CNN, il convertit le fichier audio au format wav de chaque langue obtenue ci-dessus en une image.

Cette fois, j'ai utilisé un "melspectogramme", où l'axe horizontal indique le temps, l'axe vertical indique la fréquence et l'ombre de l'image indique l'intensité. Vous pouvez facilement obtenir le melspectogramme à partir du fichier wav en utilisant une bibliothèque appelée librosa.

Vous trouverez ci-dessous le code pour convertir un fichier wav en une image spectrogramme mel. (Je pense que le même code fonctionne pour les fichiers mp3)

#contribution:Chemin du fichier audio
#production:Image Melspectogram des données audio(192×192)

import librosa as lr

def wav_to_img(path, height=192, width=192):
    signal, sr = lr.load(path, res_type='kaiser_fast')
    if signal.shape[0] < sr: #Si le fichier wav dure moins de 3 secondes
        return False, False
    else:
        signal = signal[:sr*3] #Extraire uniquement les 3 premières secondes
        hl = signal.shape[0]//(width*1.1)
        spec = lr.feature.melspectrogram(signal, n_mels=height, hop_length=int(hl))
        img = lr.amplitude_to_db(spec)**2
        start = (img.shape[1] - width)  // 2 
        return True, img[:, start:start+width] 

Le jeu de données précédent contient des données de quelques secondes à quelques dizaines de secondes. Cette fois, j'ai extrait et utilisé uniquement les 3 premières secondes des données de 3 secondes ou plus dans les données. Les données de moins de 3 secondes ne seront pas utilisées.

Toutes les données audio du dossier spécifié par la fonction suivante sont converties en une image de melspectogramme et enregistrées.

#Convertit tous les fichiers audio du dossier spécifié en images spectrogrammes et les enregistre dans le dossier spécifié

import os
import glob
import imageio

def process_audio(in_folder, out_folder):
    os.makedirs(out_folder, exist_ok=True)
    files = glob.glob(in_folder)
    start = len(in_folder)
    files = files[:]
    for file in files:
        bo, img = mp3_to_img(file)
        if bo == True:
            imageio.imwrite(out_folder + '.jpg', img)

Comme indiqué ci-dessous, sélectionnez le dossier pour les données audio de chaque langue dans le premier argument et le dossier de destination de sortie dans le deuxième argument, et exécutez. Faites-le pour toutes les langues et convertissez tous les fichiers audio en melspectogrammes.

#Ce qui suit spécifie le chemin pour enregistrer le fichier audio et le chemin vers la sortie
process_audio('data/voxforge/english/*wav', 'data/voxforge/english_3s_imgp/')

Répartition des données

Enregistrez le dossier Melspectogram pour chaque langue obtenue ci-dessus dans un fichier HDF5 pour votre commodité. C'est un peu maladroit, mais enregistrez l'image Melspectogram pour chaque langue enregistrée ci-dessus au format HDF5 dans le chemin suivant. Chemin de destination: 'data / voxforge / 3sImg.h5'

import dask.array.image
import h5py
dask.array.image.imread('data/voxforge/english_3s_img/*.jpg').to_hdf5('data/voxforge/3sImg.h5', english)
dask.array.image.imread('data/voxforge/french_3s_img/*.jpg').to_hdf5('data/voxforge/3sImg.h5', french)
dask.array.image.imread('data/voxforge/spanish_3s_img/*.jpg').to_hdf5('data/voxforge/3sImg.h5', spanish)

Divisez en données d'entraînement, données de validation et données de test.

import h5py
#Veuillez décider vous-même de la taille des données, etc. en tenant compte de l'image de spectogramme obtenue, etc.
data_size = 60000
tr_size = 50000
va_size = 5000
te_size = 5000

x_english = h5py.File('data/voxforge/3sImg.h5')['english']
x_french = h5py.File('data/voxforge/3sImg.h5')['french']
x_spanish =  h5py.File('data/voxforge/3sImg.h5')['spanish']

x = np.vstack((x_english[:20000], x_french[:20000], x_spanish[:20000]))

del x_french
del x_english
del x_spanish

x = da.from_array(x, chunks=1000)

#Préparation pour les bonnes réponses
y = np.zeros(data_size)
#0 étiquettes respectivement pour l'anglais, le français et l'espagnol,1,2
y[0:20000] = 0
y[20000:40000] = 1
y[40000:60000] = 2

#Mélanger et fractionner les données
import numpy as np

shfl = np.random.permutation(data_size)
training_size = tr_size
validation_size = va_size
test_size = te_size

#Un index shfl préparé aléatoirement est attribué à chaque division des données d'entraînement, de l'évaluation et de la taille du test.
train_idx = shfl[:training_size] 
validation_idx = shfl[training_size:training_size+validation_size] 
test_idx = shfl[training_size+validation_size:] 

#Créer des données d'entraînement, une évaluation et une taille de test avec l'index attribué
x_train = x[train_idx]
y_train = y[train_idx]
x_vali = x[validation_idx]
y_vali = y[validation_idx]
x_test = x[test_idx]
y_test = y[test_idx]

#Normalisation d'image
x_train = x_train/255
x_vali = x_vali/255
x_test = x_test/255

#Transformation de forme pour l'apprentissage
x_train = x_train.reshape(tr_size, 192, 192, 1)
x_vali = x_vali.reshape(va_size, 192, 192, 1)
x_test = x_test.reshape(te_size, 192, 192, 1)

#Un vecteur chaud de données sur les enseignants
y_train = y_train.astype(np.int)
y_vali = y_vali.astype(np.int)
y_test = y_test.astype(np.int)

Avec le traitement ci-dessus, il peut être divisé en données d'entraînement, données de validation et données de test.

Structure de CNN utilisée

La structure de réseau utilisée est la suivante. Vous pouvez le modifier librement ici. Le cadre utilisait des keras.

import tensorflow as tf
from tensorflow.python import keras
from tensorflow.python.keras import backend as K
from tensorflow.python.keras.models import Model, Sequential, load_model
from tensorflow.python.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout, Input, BatchNormalization,  Activation
from tensorflow.python.keras.preprocessing.image import load_img, img_to_array, array_to_img, ImageDataGenerator

i = Input(shape=(192,192,1))
m = Conv2D(16, (7, 7), activation='relu', padding='same', strides=1)(i)
m = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(m)
m = BatchNormalization()(m)

m = Conv2D(32, (5, 5), activation='relu', padding='same', strides=1)(m)
m = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(m)
m = BatchNormalization()(m)

m = Conv2D(64, (3, 3), activation='relu', padding='same', strides=1)(m)
m = MaxPooling2D()(m)
m = BatchNormalization()(m)

m = Conv2D(128, (3, 3), activation='relu', padding='same', strides=1)(m)
m = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(m)
m = BatchNormalization()(m)

m = Conv2D(128, (3, 3), activation='relu', padding='same', strides=1)(m)
m = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(m)
m = BatchNormalization()(m)

m = Conv2D(256, (3, 3), activation='relu', padding='same', strides=1)(m)
m = MaxPooling2D(pool_size=(3, 3), strides=2, padding='same')(m)
m = BatchNormalization()(m)

m = Flatten()(m)
m = Activation('relu')(m)
m = BatchNormalization()(m)
m = Dropout(0.5)(m)

m = Dense(512, activation='relu')(m)

m = BatchNormalization()(m)
m = Dropout(0.5)(m)

o = Dense(3, activation='softmax')(m)

model = Model(inputs=i, outputs=o)
model.summary()

J'ai appris ci-dessous. Parce qu'il y avait une tendance à surapprendre rapidement, que le nombre de données d'entraînement soit petit ou que le modèle soit mauvais. Environ 5 époques suffisent. Je suis désolé de ne pas avoir pu y penser du tout.

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=32, epochs=5, verbose=1, validation_data=(x_vali, y_vali), shuffle = True)

résultat

C'est le résultat des données de test.

model.evaluate(x_test, y_test)

[0.2763474455833435, 0.8972]

Il semble que vous pouvez le prédire correctement à environ 90%.

Cependant, en fait, les données d'entraînement et les données de test contiennent beaucoup des mêmes données vocales humaines, donc je pense que la précision est élevée.

Si vous souhaitez vérifier la précision plus précisément 'data/voxforge/english_3s_imgp/' Données non utilisées dans les données avant la lecture aléatoire, dans cet exemple,

x_english = h5py.File('data/voxforge/3sImg.h5')['english']
x_french = h5py.File('data/voxforge/3sImg.h5')['french']
x_spanish =  h5py.File('data/voxforge/3sImg.h5')['spanish']

x = np.vstack((x_english[20000:], x_french[20000:], x_spanish[20000:]))

Je pense que vous pouvez vérifier l'exactitude plus précisément en utilisant les données de. À propos, le taux de réponse correct pour chaque langue à ce moment-là était le suivant.

Anglais: 0.8414201183431953 Français: 0.7460106382978723 Espagnol: 0.8948035487959443

Je ne peux pas très bien identifier le français.

Résumé

Cette fois, après avoir étudié, j'ai essayé la reconnaissance vocale en utilisant CNN. Je suis désolé qu'il puisse y avoir des endroits où l'explication est insuffisante en raison d'une précipitation sur le chemin. J'ai présenté l'idée de base au début, mais vous pouvez la vérifier à partir de l'URL suivante, donc si vous êtes bon en anglais, vous voudrez peut-être y regarder. (http://yerevann.github.io/2015/10/11/spoken-language-identification-with-deep-convolutional-networks/)

Merci d'avoir lu jusqu'au bout.

Recommended Posts

J'ai essayé d'identifier la langue en utilisant CNN + Melspectogram
765 J'ai essayé d'identifier les trois familles professionnelles par CNN (avec Chainer 2.0.0)
J'ai essayé d'approcher la fonction sin en utilisant le chainer
J'ai essayé de compléter le graphe de connaissances en utilisant OpenKE
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
J'ai essayé de déplacer le ballon
J'ai essayé d'utiliser l'API checkio
J'ai essayé d'estimer la section.
J'ai essayé de simuler l'optimisation des publicités à l'aide de l'algorithme Bandit
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
J'ai essayé d'approcher la fonction sin en utilisant chainer (re-challenge)
J'ai essayé de sortir le journal d'accès au serveur en utilisant Node.js
J'ai essayé d'utiliser Azure Speech to Text.
J'ai essayé de résumer la commande umask
J'ai essayé d'obtenir l'index de la liste en utilisant la fonction énumérer
J'ai essayé de reconnaître le mot de réveil
J'ai essayé de classer le texte en utilisant TensorFlow
J'ai essayé de résumer la modélisation graphique.
J'ai essayé d'estimer le rapport de circonférence π de manière probabiliste
J'ai essayé de toucher l'API COTOHA
J'ai essayé d'utiliser l'API BigQuery Storage
J'ai essayé de transformer l'image du visage en utilisant sparse_image_warp de TensorFlow Addons
J'ai essayé d'obtenir les résultats de Hachinai en utilisant le traitement d'image
J'ai essayé d'estimer la similitude de l'intention de la question en utilisant Doc2Vec de gensim
J'ai essayé de résoudre 100 traitements linguistiques Knock version 2020 [Chapitre 3: Expressions régulières 25-29]
J'ai essayé de contrôler plusieurs servomoteurs MG996R en utilisant le servomoteur PCA9685.
J'ai essayé de résumer diverses phrases à l'aide de l'API de synthèse automatique "summpy"
J'ai essayé d'extraire et d'illustrer l'étape de l'histoire à l'aide de COTOHA
J'ai essayé l'histoire courante de l'utilisation du Deep Learning pour prédire la moyenne Nikkei
En utilisant COTOHA, j'ai essayé de suivre le cours émotionnel de la course aux meros.
J'ai implémenté le modèle VGG16 avec Keras et essayé d'identifier CIFAR10
J'ai essayé d'analyser la carte du Nouvel An par moi-même en utilisant python
J'ai essayé de programmer la bulle de tri par langue
J'ai essayé Web Scraping pour analyser les paroles.
vprof - J'ai essayé d'utiliser le profileur pour Python
J'ai essayé d'optimiser le séchage du linge
J'ai essayé de sauvegarder les données avec discorde
J'ai essayé de synthétiser des fichiers WAV en utilisant Pydub.
J'ai essayé d'utiliser PyCaret à la vitesse la plus rapide
J'ai essayé d'utiliser l'API Google Cloud Vision
J'ai essayé de corriger la forme trapézoïdale de l'image
Qiita Job J'ai essayé d'analyser le travail
J'ai essayé d'utiliser le filtre d'image d'OpenCV
LeetCode j'ai essayé de résumer les plus simples
J'ai essayé d'utiliser la bibliothèque de programmation fonctionnelle toolz
J'ai essayé de mettre en œuvre le problème du voyageur de commerce
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
J'ai essayé d'utiliser paramétré
J'ai essayé d'utiliser argparse
J'ai essayé d'utiliser la mimesis
J'ai essayé d'utiliser aiomysql
J'ai essayé d'utiliser Summpy
J'ai essayé d'utiliser Pipenv
J'ai essayé d'utiliser matplotlib
J'ai essayé d'utiliser ESPCN