[PYTHON] La musique de fond est automatiquement sélectionnée en fonction du contenu de la conversation

1. 1. introduction

Relancez le deuxième concours de développement de l'IA "Neural Network Console Challenge" prévu par Sony et Ledge. En analysant les données audio (BGM) et la bibliographie (description de la chanson) d'Audiostock, nous travaillerons sur la ** tâche gratuite "Créer un lecteur qui sélectionne automatiquement BGM en fonction du contenu de la conversation quotidienne" **. Considérez un système dans lequel des haut-parleurs intelligents tels que Google Home jouent automatiquement la musique de fond en fonction du contenu de conversation des personnes dans la pièce (bien que l'obstacle pour une utilisation pratique semble être élevé du point de vue de la confidentialité ...).

2. Environnement expérimental et données

・ Google Colaboratory (python3) ・ Neural Network Console (version Windows)

Travail Non. Nom des données Explication en une ligne marque
42554 audiostock_42554.wav C'est la chanson parfaite pour l'ouverture ouverture
42555 audiostock_42555.wav C'est une chanson autoritaire Bosanova
42556 audiostock_42556.wav Comique à l'écoute facile réconfortant comique,mignonne,chaud,Réconfortant,écoute facile
42557 audiostock_42557.wav C'est une chanson étrange Battement étrange

3. 3. Classification automatique BGM

À l'aide des données vocales BGM (WAV), créez un modèle de classification automatique à l'aide de NNC. En raison de contraintes de temps, nous avons construit un modèle qui peut être classé en 3 classes cette fois.

3-1. Annotations et données d'entraînement

Pour déterminer quel type de classe est souhaitable, étudiez d'abord les mots contenus dans «l'explication en une ligne» ci-dessus en utilisant «KHcoder» qui peut analyser statistiquement les données textuelles. Les meilleurs résultats sont les suivants. image.png À partir de ceux-ci, il semble que vous puissiez classer tout en écoutant la musique de fond (le tempo, le ton, etc. sont différents) Pour utiliser des chansons qui contiennent des "rock", "pop" et "ballad" comme données d'entraînement. Nous avons créé 1468 données d'entraînement et 105 données d'évaluation. De plus, les sources sonores (jingles) telles que les effets sonores ont été exclues de la création car la longueur de la chanson est courte.

3-2. Convertir en coefficient de Keptram de fréquence Mel

Nous convertirons les données WAV de BGM en coefficient Keptram de fréquence Mel et les déposerons dans un vecteur à 40 dimensions (j'omettrai les détails, mais cette page / 34161f2facb80edd999f) a été décrit en détail). La moyenne a été prise pour chaque pas sur l'axe vertical et transformée en un tableau (1,40), utilisé comme données d'entraînement.

Wav_to_Mel.py


import pandas as pd
import numpy as np
import librosa

y, sr = librosa.load(file_name)
#Extraction de caractéristiques en 40 dimensions
mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=40)
#Calculez la moyenne sur l'axe vertical et la sortie
S_A = np.mean(mfcc, axis = 1)
np.savetxt(output_filename, S_A.reshape(1, -1), delimiter=',', fmt="%s")

3-3. Créer un modèle de classification avec NNC

J'ai formé un modèle qui classe les vecteurs avec NNC. Il semble que la solution avec CNN soit courante, mais après avoir essayé divers réseaux et fonctions d'activation, le résultat est que les paramètres suivants sont les plus précis. Si j'ai le temps, j'aimerais refaire l'expérience. À propos, l'avantage de NNC est qu'il est très facile car l'interface graphique est préparée pour les essais et erreurs tels que la modification de la fonction. Vous pouvez comprendre intuitivement de quel type de réseau il s'agit, et je pense que c'est l'une des attractions par rapport à Google Colab. image.png Depuis que j'ai entraîné des vecteurs de faible dimension, la quantité de traitement était suffisante avec le processeur (version Windows) cette fois, mais les résultats d'apprentissage avec la version cloud apprise avec presque les mêmes paramètres seront publiés pour le moment. Après 30 périodes de formation, la courbe d'apprentissage était la suivante (la meilleure validation était la 9e époque). image.png Ensuite, en utilisant le modèle créé, évaluez-le avec des données de test et essayez de mesurer la précision. image.png image.png Bien qu'il s'agisse d'un problème à trois classes, la précision semble avoir des caractéristiques de 0,8. Le taux de précision moyen est d'environ 80% ou plus, et il semble être un modèle précieux pour la tâche de sélection d'un BGM approprié.

4. Analysez la conversation quotidienne

En utilisant le modèle entraîné de Bert, sélectionnez une musique de fond proche du contenu de la conversation dans l'explication en une ligne. Calcule le vecteur de conversation (texte) et sélectionne le BGM avec la description sur une ligne la plus proche en similitude cosinus. Tout d'abord, recherchez un BGM approprié sur une base de texte, puis 3. Nous sélectionnerons les chansons en fonction de la classification basée sur la musique de fond créée dans. Je ne pouvais pas penser à une implémentation de BERT dans NNC, alors je l'ai traitée avec Google colab et des transformateurs qui ont des connaissances (Personnellement, NNC a beaucoup de champs d'image, donc la prochaine fois je vais renforcer autour du langage naturel. Je suis content de mon travail).

Conversation_to_BGM.py


import pandas as pd
import numpy as np
import torch
import transformers

from transformers import BertJapaneseTokenizer
from tqdm import tqdm
tqdm.pandas()

class BertSequenceVectorizer:
    def __init__(self):
        self.device = 'cuda' if torch.cuda.is_available() else 'cpu'
        self.model_name = 'cl-tohoku/bert-base-japanese-whole-word-masking'
        self.tokenizer = BertJapaneseTokenizer.from_pretrained(self.model_name)
        self.bert_model = transformers.BertModel.from_pretrained(self.model_name)
        self.bert_model = self.bert_model.to(self.device)
        self.max_len = 128
            
    def vectorize(self, sentence : str) -> np.array:
        inp = self.tokenizer.encode(sentence)
        len_inp = len(inp)

        if len_inp >= self.max_len:
            inputs = inp[:self.max_len]
            masks = [1] * self.max_len
        else:
            inputs = inp + [0] * (self.max_len - len_inp)
            masks = [1] * len_inp + [0] * (self.max_len - len_inp)

        inputs_tensor = torch.tensor([inputs], dtype=torch.long).to(self.device)
        masks_tensor = torch.tensor([masks], dtype=torch.long).to(self.device)
        
        seq_out, pooled_out = self.bert_model(inputs_tensor, masks_tensor)

        if torch.cuda.is_available():    
            return seq_out[0][0].cpu().detach().numpy()
        else:
            return seq_out[0][0].detach().numpy()

if __name__ == '__main__':
    #Lire les données originales
    df_org = pd.read_csv('./drive/NNC/Liste de données BGM.csv')
    #Concentrez-vous uniquement sur les morceaux dans les données d'entraînement
    df_org = df_org.dropna(subset=["Explication en une ligne"])
    df_org = df_org[~df_org['Explication en une ligne'].str.contains("Tinter")]
    df_org = df_org[~df_org['marque'].str.contains("Tinter")]
    df_org = df_org.head(5000)
    word = ["Fermer à clé", "pop", "Ballard"]
    df = df_org.iloc[0:0]
    for w in word:
      df_detect = df_org[df_org["Explication en une ligne"].str.contains(w)]
      df = pd.concat([df, df_detect])
    df = df.reset_index(drop=True)
    BSV = BertSequenceVectorizer()
    #Calculer le vecteur d'entités à partir de la bibliographie
    df['text_feature'] = df['Explication en une ligne'].progress_apply(lambda x: BSV.vectorize(x))
    #Rechercher des vecteurs similaires (BGM) à partir du texte d'entrée
    nn = NearestNeighbors(metric='cosine')
    nn.fit(df["text_feature"].values.tolist())
    vec = BSV.vectorize("Bonjour. Il fait beau aujourd'hui. Ouais. On dirait qu'il fait beau toute la journée.")
    ##Calculer la similitude cosinus
    dists, result = nn.kneighbors([vec], n_neighbors=1)
    print(df["Nom des données"][r], df["Explication en une ligne"][r])

###Résultat de sortie
audiostock_45838.wav
Name:Nom des données, dtype: object 188    
Pop occupé mais amusant/Fermer à clé
Name:Explication en une ligne, dtype: object

5. Expérience

Maintenant, essayons quel type de chanson sera sélectionné en entrant la phrase conversationnelle attendue. Le BGM final sélectionné était de 300 chansons qui n'ont pas été utilisées pour l'apprentissage ou l'évaluation et n'incluaient pas les mots «rock», «pop» et «ballad» dans l'explication en une ligne. L'image entière est comme le montre la figure. image.png Pour que les chansons soient finalement sélectionnées, nous avons décidé de jouer les chansons avec la probabilité de prédiction la plus élevée dans l'ordre à partir du fichier "output_result.csv" sorti par NNC (NNC peut définir différentes données pour l'évaluation au moment de l'apprentissage et l'évaluation finale. ). Choisissons des chansons dans divers cas.

** Cas 1) ** ** ◆ Conversation: ** Bonjour. Il fait beau aujourd'hui. Ouais. On dirait qu'il fait beau toute la journée. ** ◆ Une ligne à haute similitude Description: ** Pop / rock occupé mais amusant (audiostock_45838.wav) → Label "Rock"

Que ce soit une chanson du matin ou pas, j'ai pu choisir des chansons qui semblaient énergiques, telles que «puissantes» et «vivantes»! Il semble y avoir une tendance à choisir des chansons de style métal qui utilisent des guitares électriques.

*** Cas 2) *** ** ◆ Conversation: ** Nous prévoyons de camper à Yamanashi le week-end. Vous pouvez passer un moment calme au bord du lac pour la première fois depuis longtemps. Il fait plus frais, alors faites attention. ** ◆ Une ligne à haute similitude Description: ** Pop (audiostock_45997.wav) qui manque soudainement l'amour des parents un jour lointain → Label "Pop" ** ◆ Résultat de la sélection du morceau: ** ・ Audiostock_45254 Musique japonaise pure avec une colonne vertébrale pittoresque qui se fige dans des histoires de fantômes ・ Audiostock_44771 BGM du toucher de document d'horreur ・ Audiostock_46760 Informations de voyage Nostalgique mélancolie solitaire crépuscule ・ Audiostock_46657 Rafraîchissement de la conduite souhaitée Lumière vers l'avant ・ Audiostock_44331 Musique réconfortante des Caraïbes tropicales

Les première et deuxième chansons étaient évidemment de mauvais résultats de sélection (histoire de fantômes ...), mais les quatrième et cinquième chansons sont des BGM pop parfaits pour voyager. De plus, l'explication de la troisième chanson a une atmosphère triste, mais c'était une musique de fond avec "pop" dans l'étiquette, et quand je l'ai écoutée, ce n'était pas si sombre. À partir de là, il semble qu'il y ait une tendance à sélectionner automatiquement des chansons de style pop.

*** Cas 3) *** ** ◆ Conversation: ** J'ai entendu ce drame, une chose émouvante, l'avez-vous vu? .. Une histoire triste et triste. Le dernier a pleuré. ** ◆ Une ligne à haute similitude Description: ** Ballade chauffante, sentiments d'adolescents (audiostock_43810.wav) → Label "ballade" ** ◆ Résultat de la sélection du morceau: ** ・ Audiostock_46013 Environnement frais, mystérieux et spacieux ・ Audiostock_44891 Ambiance de relaxation des étoiles nocturnes ・ Audiostock_44575 Un son doux de style ambi qui élargit le monde des contes de fées ・ Audiostock_45599 Un environnement mystérieux avec une atmosphère matinale fraîche ・ Audiostock_45452 Un classique gracieux avec une élégance artistique dans le jardin

J'ai réussi à extraire des BGM silencieux tels que des chansons et des classiques mystérieux et lâches.

Les trois catégories ont été automatiquement sélectionnées uniquement sur la base des fonctionnalités BGM, mais il semble que nous ayons pu extraire des chansons qui étaient presque comme prévu! En regardant les BGM qui n'ont pas été sélectionnés (la probabilité de prédiction était faible), "Titre du programme de variétés BGM" (audiostock_43840), "Style Euro-house à saveur latine" (audiostock_42921), "Récit de voyage mystérieux africain à la mode" (Audiostock_46146) etc., et il a été confirmé que le modèle présente une distinction de BGM inappropriée.

6. Résumé et considération

Pour la tâche de créer un lecteur qui sélectionne automatiquement BGM en fonction du contenu de la conversation quotidienne

J'ai pu m'en rendre compte. Cette fois, je n'ai pu créer qu'un modèle avec un total d'environ 1600 chansons et de petites données d'entraînement, mais en examinant plus en détail les annotations et le nombre de données, on peut s'attendre à une amélioration de la précision et au moins trois classes de classification peuvent être créées. Devrait faire. Il semble y avoir plus de place pour la recherche sur la façon de calculer les caractéristiques de la BGM. La proposition de service était basée sur l'hypothèse de haut-parleurs intelligents, mais elle n'est pas limitée à cela, mais elle peut être utilisée pour de futures propositions telles que la publication de chansons à partir de balises et de textes sur SNS, et la sélection automatique de BGM à partir des données de sous-titres par montage vidéo. Il semble que.

7. Les références

Recommended Posts

La musique de fond est automatiquement sélectionnée en fonction du contenu de la conversation
Point selon l'image
Changer la valeur de paramètre de setting.py en fonction de l'environnement de développement
Tentative d'ajuster automatiquement la vitesse des vidéos accélérées (partie 2)
Changer le volume de Pepper en fonction de l'environnement environnant (son)
Supplément à l'explication de vscode
[Gestion des erreurs Golang] La meilleure façon de diviser le traitement en fonction du type d'erreur
J'ai essayé d'extraire automatiquement les mouvements des joueurs Wiire avec un logiciel
J'ai essayé d'obtenir automatiquement le RSS de la chanson la plus populaire de l'iTunes Store
L'histoire d'essayer de reconnecter le client
10 méthodes pour améliorer la précision de BERT
Comment vérifier la version de Django
L'histoire de la mise en place de MeCab dans Ubuntu 16.04
L'histoire du changement de pep8 en pycodestyle
Test de la différence entre les valeurs moyennes des données de comptage selon la distribution de Poisson
J'ai créé un outil pour sauvegarder automatiquement les métadonnées de l'organisation Salesforce
J'ai essayé d'envoyer automatiquement la littérature du nouveau virus corona à LINE avec Python
Comment calculer la volatilité d'une marque
Comment trouver la zone du diagramme de Boronoi
Constantes Python comme None (selon la référence)
Trouver la main de "Millijan" par l'optimisation des combinaisons
Paramètre pour afficher le journal de l'exécution de cron
L'inexactitude de Tensorflow était due à log (0)
J'ai essayé de corriger la forme trapézoïdale de l'image
De l'introduction de pyethapp à l'exécution du contrat
Essayez de simuler le mouvement du système solaire
Histoire de passer de Pipenv à la poésie
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
Un script qui peut effectuer des tests de résistance en fonction du nombre de cœurs CPU