[DOCKER] (Remarque) Application Web qui utilise TensorFlow pour déduire les noms de morceaux recommandés [Apprentissage automatique]

introduction

Cet article est ** (Remarque) Une application Web qui utilise TensorFlow pour déduire les noms de chansons recommandés. [Créer un environnement d'exécution avec docker-compose] ** est une continuation. La dernière fois, j'ai créé l'environnement TensorFlow et Flask avec docker-compose, donc Cette fois, je souhaite organiser l'apprentissage automatique à l'aide de TensorFlow + Keras. Veuillez noter que c'est un article que j'ai fait pour moi-même, donc il peut être difficile à comprendre, les informations et la technologie peuvent être obsolètes: arc: J'espère également que cela sera utile pour ceux qui souhaitent créer eux-mêmes une sorte d'application Web.

L'application Web réelle ressemble au GIF ci-dessous. ezgif.com-crop.gif Lorsque j'ai tapé une phrase dans le champ de recherche, M. Hamburg Hambird a répondu "même histoire": clap: $ \ tiny {* Puisqu'il y a peu de données d'apprentissage, seules quelques chansons seront frappées. .. C'est minable} $: bow_tone1: $ \ tiny {* Cliquez sur le lien de la partition pour voir une partie de la partition, mais cela sort du cadre de l'article} $: no_good_tone1:

Les références

Je l'ai utilisé comme référence lors de la création de cet article: bow_tone1:

Carte de TODO

** (Remarque) Une application Web qui utilise TensorFlow pour déduire les noms de chansons recommandées. [Création d'un environnement d'exécution avec docker-compose] ** Cette fois, c'est ** l'apprentissage automatique **.

chapitre Classification Statut Contenu Langue, FW, environnement, etc.
Préface Commun Déjà Aperçu de l'application Python
TensorFlow
Keras
Google Colaboratory
chapitre un Web API Déjà Construction de l'environnement (environnement d'exécution) docker-compose
Flask
Nginx
gunicorn
Chapitre II Web API Déjà (Cette fois) Apprentissage automatique Python
TensorFlow
Keras
Flask
chapitre 3 écran pas encore commencé Environnement Python
Django
Nginx
gunicorn
PostgreSQL
virtualenv
Chapitre 4 écran pas encore commencé Affichage, partie d'appel d'API Web Python
Django
Chapitre 5 AWS pas encore commencé Déploiement automatique AWS Github
EC2
CodeDeploy
CodePipeline

environnement

* Je pense que cela fonctionnera même si ce n'est pas la version suivante, mais veuillez noter qu'elle est ancienne: no_good_tone2: </ sup>

OS:Ubuntu 18.04.4 LTS
---------------------- -----------
Flask                  1.1.0
gunicorn               19.9.0
Keras                  2.3.1
Keras-Applications     1.0.8
Keras-Preprocessing    1.1.2
matplotlib             3.1.1
mecab-python3          0.996.2
numpy                  1.16.4
pandas                 0.24.2
Pillow                 7.1.2
pip                    20.1
Python                 3.6.9
requests               2.22.0
scikit-learn           0.21.2
sklearn                0.0
tensorflow             2.2.0

Flux de la partie qui déduit les chansons recommandées

Tout d'abord, je voudrais créer les fonctions suivantes. C'est une API Web qui renvoie le titre de chanson recommandé lorsque vous le saisissez et lui donnez une phrase (ambiance de chanson, etc.). L'API Web réelle est la suivante. Peek 2020-05-16 14-30.gif

Dans l'exemple, le paramètre de la méthode GET est "une chanson qui est triste et souhaite le bonheur de quelqu'un". J'ai pu obtenir le titre de la chanson "Clouds go" en JSON. [(Exemple) Lien API Web](http://52.192.175.215:8888/recommend/api/what-music/ Une chanson qui souhaite le bonheur de quelqu'un)

Le flux de traitement à l'intérieur de cette API Web est le suivant. image.png Le titre de la chanson est renvoyé à la fin comme un flux, mais les données de poids sont lues au milieu. Il s'agit d'un modèle pré-entraîné créé par apprentissage automatique. Alors organisons comment créer un modèle entraîné.

Flux d'apprentissage automatique

Le flux suivant est du point de vue du développeur et correspond au flux jusqu'à l'apprentissage automatique. image.png Tout d'abord, préparez les données à apprendre. Ceci est fait avec un texte qui peut être compris par les humains. Ensuite, un prétraitement est effectué pour que la machine (ordinateur) puisse le comprendre. Dans cet exemple, les données de source d'apprentissage sont converties en un vecteur numérique par une méthode appelée TF-IDF. Enfin, l'apprentissage automatique est réalisé avec MLP (Multilayer Perceptron). Les détails de chacun seront décrits plus loin.

Création de données source d'apprentissage

Les données qui constituent la source d'apprentissage sont séparées par des virgules, comme indiqué ci-dessous. Données originales de l'apprentissage automatique image.png Contient des informations sur la chanson (atmosphère, nom de l'artiste, etc.) pour le titre de la chanson à déduire. Il est séparé par "|" (tuyau), mais ça va sans lui.

Prétraitement (TF-IDF)

Convertissez en un vecteur numérique avec TF-IDF. Commencez par charger les données de source d'apprentissage créées ci-dessus. Puis divisez la phrase en mots pour le calcul TF-IDF (écriture séparée) Ce processus utilise MeCab pour l'analyse morphologique. Pour référence, la source de la division est la suivante.

Vous trouverez ci-dessous le code à coller dans Google Colaboratory. $ \ tiny {* Ne le fixez pas} $: no_good_tone1: Veuillez coller et exécuter dans l'ordre du haut. ..

Installez les bibliothèques requises


#Installez les bibliothèques requises
!apt-get install mecab libmecab-dev mecab-ipadic-utf8
!pip3 install mecab-python3

Partie séparée (extrait partiel)


import MeCab

#Initialisation MeCab
tagger = MeCab.Tagger()

def tokenize(text):
    '''Effectuer une analyse morphologique avec MeCab''' 
    result = []
    word_s = tagger.parse(text)
    for n in word_s.split("\n"):
        if n == 'EOS' or n == '': continue
        p = n.split("\t")[1].split(",")
        h, h2, org = (p[0], p[1], p[6])
        if not (h in ['nom', 'verbe', 'adjectif']): continue
        if h == 'nom' and h2 == 'nombre': continue
        result.append(org)
    return result

#Tester le module
if __name__ == '__main__':
    print(tokenize("films|Tetsuya Takeda|douloureux|Je souhaite à quelqu'un qui ne connaît pas le bonheur"))

Lorsque vous l'exécutez, vous devriez voir quelque chose comme ceci sur la console:

['films', '*', 'Takeda', 'Tetsuya', '*', 'douloureux', '*', 'connaître', 'qui', 'bonheur', 'Souhait']

Séparé par mot. L'exemple ci-dessus n'est qu'une phrase, Dans le programme réel, ce processus est répété pour le nombre de phrases (lignes) dans le fichier.

Si vous pouvez l'écrire séparément, calculez TF-IDF. En ce qui concerne TF-IDF, je vais le citer car il y avait une explication facile à comprendre. Source: TF-IDF

Il s'agit de la valeur utilisée pour extraire les mots caractéristiques du document du document. Lorsqu'il y a plusieurs documents, d'après les mots qui y figurent et leur fréquence, Quantifier ce qui est un mot important pour un document

TF-IDF est exprimé par la formule suivante.

\textrm{TF_IDF}(t) = \textrm{tf}(t,d) × \textrm{idf}(t)

De plus, $ \ textrm {tf} (t, d) $ et $ \ textrm {idf} (t) $ sont exprimés par les formules suivantes.

\textrm{tf}(t,d) = \frac{n_{t,d}}{\sum_{s \in d}n_{s,d}} \textrm{  , } \textrm{idf}(t) = \log{\frac{N}{df(t)}} + 1

$ n_ {t, d} $: Nombre d'occurrences d'un mot $ t $ dans le document $ d $ $ \ sum_ {s \ in d} n_ {s, d} $: Somme du nombre d'occurrences de tous les mots du document $ d $ $ N $: nombre total de documents $ df (t) $: Nombre de documents dans lesquels un mot $ t $ apparaît

La formule ci-dessus peut être convertie en programme comme suit.

TF-Calcul IDF(Extrait)


def calc_files():
    '''Calculer le fichier ajouté'''
    global dt_dic
    result = []
    doc_count = len(files)
    dt_dic = {}
    #Compter la fréquence d'occurrence des mots
    for words in files:
        used_word = {}
        data = np.zeros(word_dic['_id'])
        for id in words:
            data[id] += 1
            used_word[id] = 1
        #Dt si le mot t est utilisé_Ajouter un dic
        for id in used_word:
            if not(id in dt_dic): dt_dic[id] = 0
            dt_dic[id] += 1
        #Convertir le nombre d'apparitions en pourcentage--- (*10)
        data = data / len(words) 
        result.append(data)
    # TF-Calculer IDF
    for i, doc in enumerate(result):
        for id, v in enumerate(doc):
            idf = np.log(doc_count / dt_dic[id]) + 1
            doc[id] = min([doc[id] * idf, 1.0])
        result[i] = doc
    return result

* Cette [Référence](https://www.amazon.co.jp/%E3%81%99%E3%81%90%E3%81%AB%E4%BD%BF%E3%81 % 88% E3% 82% 8B-% E6% A5% AD% E5% 8B% 99% E3% 81% A7% E5% AE% 9F% E8% B7% B5% E3% 81% A7% E3% 81% 8D% E3% 82% 8B-Python% E3% 81% AB% E3% 82% 88% E3% 82% 8B-AI% E3% 83% BB% E6% A9% 9F% E6% A2% B0% E5% AD% A6% E7% BF% 92% E3% 83% BB% E6% B7% B1% E5% B1% A4% E5% AD% A6% E7% BF% 92% E3% 82% A2% E3% 83% 97% E3% 83% AA% E3% 81% AE% E3% 81% A4% E3% 81% 8F% E3% 82% 8A% E6% 96% B9-% E3% 82% AF% E3% 82% B8 % E3% 83% A9% E9% A3% 9B% E8% A1% 8C% E6% 9C% BA / dp / 4802611641) la source de l'échantillon [^ 1] est presque détournée, mais cette fois sur Github Je vous donne la source. </ sup> (source) </ sup> [^ 1]: [Source de détournement: prêt à l'emploi! Peut être pratiqué en entreprise! Exemple de code pour créer des applications d'IA / d'apprentissage automatique / d'apprentissage en profondeur avec Python](https://github.com/kujirahand/book-mlearn- gyomu)

La source de calcul et de sortie de TF-IDF à partir de la lecture du fichier source d'apprentissage est la suivante. La source de calcul du TF-IDF essentiel étant longue, elle est modulaire et se lit: suer: Il lit également les données de la source d'apprentissage. Il est stocké ci-dessous, veuillez donc le télécharger. tfidfWithIni.py ← Module pour calculer TF-IDF ans_studyInput_fork.txt ← Fichier source d'apprentissage

Procédure de création de vecteur TF-IDF

Vous trouverez ci-dessous le code à coller dans Google Colaboratory pour votre référence. $ \ tiny {* Ne le fixez pas} $: no_good_tone1: Veuillez coller et exécuter dans l'ordre du haut. ..

étape 1_Téléverser un fichier


#Télécharger le fichier ("tfidfWithIni".py」、「ans_studyInput_fork.txt」)
from google.colab import files
uploaded = files.upload()

Étape 2_Installez les bibliothèques requises


#Créer un répertoire pour enregistrer les fichiers
!mkdir text
#Installez les bibliothèques requises
!apt-get install mecab libmecab-dev mecab-ipadic-utf8
!pip3 install mecab-python3

Étape 3_TF-Convertir en vecteur IDF


import os, csv, glob, pickle
import tfidfWithIni
import importlib

#Rechargement du module (tfidfWithIni)
importlib.reload(tfidfWithIni)

#Initialisation variable
y = []
x = []

#Dictionnaire de conversion de code d'étiquette
labelToCode = {}

#Lire le fichier csv
def read_file(path):
    '''Ajouter un fichier texte pour l'apprentissage''' # --- (*6)
    with open(path, "r", encoding="utf-8") as f:
        reader = csv.reader(f)   
        label_id = 0  
        for row in reader:
            #Création de code d'étiquette
            if row[2] not in labelToCode:
                labelToCode[row[2]] = label_id
                label_id += 1
                
            y.append(labelToCode[row[2]])  #Définir l'étiquette
            tfidfWithIni.add_text(row[3])  #Définir des phrases
           # print("étiquette: ", row[2], "(", labelToCode[row[2]], ")",  "Phrase: ", row[3])

#Tester le module--- (*15)
if __name__ == '__main__':
    # TF-Initialiser le vecteur IDF(Fichiers vides)
    tfidfWithIni.iniForOri()
    
    #Lire la liste des fichiers--- (*2)
    read_file("ans_studyInput_fork.txt")

    # TF-Convertir en vecteur IDF--- (*3)
    x = tfidfWithIni.calc_files()

    #sauvegarder--- (*4)
    pickle.dump([y, x], open('text/genre.pickle', 'wb'))
    tfidfWithIni.save_dic('text/genre-tdidf.dic')
    pickle.dump(labelToCode, open('text/label_to_code.pickle', 'wb'))

Une fois exécutés, les dossiers et fichiers seront créés comme indiqué ci-dessous. image.png

Le dictionnaire pour le calcul TF-IDF est la conversion des mots utilisés dans le calcul en ID comme suit. image.png

Apprentissage automatique (MLP)

Avec le prétraitement, nous sommes prêts pour l'apprentissage automatique. Sur la base des données d'apprentissage ci-dessus, l'apprentissage sera effectué afin que le titre de la chanson puisse être correctement identifié. MLP (Multilayer Perceptron) est utilisé comme méthode d'apprentissage. MLP est un type de réseau neuronal qui imite les nerfs humains. Il semble qu'il se compose d'une couche de trois nœuds ou plus. MLP utilise une certaine méthode pour apprendre en fonction des données d'apprentissage (données correctes). Même si des données inconnues (l'atmosphère de la chanson dans cet exemple) entrent, il sera possible de déterminer correctement (le titre de la chanson dans cet exemple). Pour ce faire, nous utilisons le framework d'apprentissage automatique TensorFlow + Keras. Et cette fois, nous allons créer un réseau de neurones avec la structure suivante * Ceci est une image </ sub>: sueur: image.png

La modélisation avec TensorFlow + Keras pour créer ce réseau neuronal ressemble à ceci [^ 1].

#Définir la structure du modèle MLP
model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(in_size,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(nb_classes, activation='softmax'))

La couche utilise ce qu'on appelle Dense de Keras. Avec cela, chaque Perceptron sera sur la couche suivante Il semble que tout sera connecté à Perceptron. De plus, le nombre d'entrées est de x1 à xt dans le diagramme d'image, mais cela est défini par l'argument input_shape. Il ne s'agit que de quelques minutes d'un mot en divisant la phrase entière. Dans l'exemple de fichier de formation, il y a 144 (dimensions). La sortie est de y1 à yclass, qui est le nombre de titres de chanson dans le fichier d'apprentissage, et est spécifiée par l'argument nb_classes. Il y a 10 (chansons) dans l'échantillon.

Ensuite, définissez comment effectuer la formation afin qu'elle puisse être correctement déterminée (compiler). RMSprop, en tant qu'algorithme d'optimisation basé sur Keras Documentation Multiclass Classification Problem Disons catégorical_crossentropy comme fonction de perte. * (Image des mots) Fonction de perte: Indice de mesure de l'écart d'apprentissage, algorithme d'optimisation: Méthode de correction pour se rapprocher de la bonne réponse </ sub>

#Compilez le modèle
model.compile(
    loss='categorical_crossentropy',
    optimizer=RMSprop(),
    metrics=['accuracy'])

Enfin, la partie exécution de l'apprentissage. La formation est effectuée par la méthode fit. Entrée (atmosphère de chanson, etc.) et sortie (titre de chanson) Vous pouvez apprendre en donnant le tableau Numpy de à la méthode d'ajustement du modèle de séquence.

hist = model.fit(x_train, y_train,
          batch_size=16, #Nombre de données à calculer à la fois
          epochs=150,    #Quelque chose comme le nombre de répétitions d'apprentissage
          verbose=1,
          validation_data=(x_test, y_test))

Exécution de l'apprentissage automatique

Vous trouverez ci-dessous le code à coller dans Google Colaboratory pour votre référence.

Après avoir exécuté jusqu'à l'étape 3 de [la procédure de création de vecteur TF-IDF ci-dessus](procédure de création de vecteur # tf-idf) Vous devriez pouvoir effectuer un apprentissage automatique en procédant comme suit:

Étape 4_Exécution de l'apprentissage automatique (MLP)


import pickle
from sklearn.model_selection import train_test_split
import sklearn.metrics as metrics
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop
import matplotlib.pyplot as plt
import numpy as np
import h5py

#Nombre d'étiquettes à classer
labelToCode = pickle.load(open("text/label_to_code.pickle", "rb"))
nb_classes = len(labelToCode) 

#Lire la base de données
data = pickle.load(open("text/genre.pickle", "rb"))
y = data[0] #Code d'étiquette
x = data[1] # TF-IDF
#Étiqueter les données un-Convertir en vecteur chaud
y = keras.utils.np_utils.to_categorical(y, nb_classes)
in_size = x[0].shape[0] #Entrée x[0]Nombre d'éléments de

#Séparé pour l'apprentissage et les tests
x_train, x_test, y_train, y_test = train_test_split(
        np.array(x), np.array(y), test_size=0.2)

#Définir la structure du modèle MLP
model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(in_size,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(nb_classes, activation='softmax'))

#Compilez le modèle
model.compile(
    loss='categorical_crossentropy',
    optimizer=RMSprop(),
    metrics=['accuracy'])

#Effectuer l'apprentissage
hist = model.fit(x_train, y_train,
          batch_size=16, #Nombre de données à calculer à la fois
          epochs=150,    #Quelque chose comme le nombre de répétitions d'apprentissage
          verbose=1,
          validation_data=(x_test, y_test))

#évaluer
score = model.evaluate(x_test, y_test, verbose=1)
print("Taux de réponse correct=", score[1], 'loss=', score[0])

#Enregistrer les données de poids
model.save_weights('./text/genre-model.hdf5')

#Dessinez l'état de l'apprentissage sur un graphique
plt.plot(hist.history['val_accuracy'])
plt.title('Accuracy')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

Lorsque l'exécution est terminée, le graphique suivant sera affiché et le fichier (/content/text/genre-model.hdf5) sera affiché. Il aurait dû être créé en plus. C'est la fin de l'apprentissage automatique. image.png

Devinez le titre de la chanson en utilisant le modèle entraîné

Dans la partie analogie, nous définissons le même modèle que dans l'apprentissage automatique. Chargez le modèle entraîné, le dictionnaire TF-IDF et le dictionnaire d'étiquettes de résultat. Ensuite, le document inconnu (l'atmosphère de la chanson) est converti en un vecteur TF-IDF. Enfin, si vous donnez le vecteur TF-IDF à la méthode de prédiction de Sequencial, le titre de la chanson sera déduit.

Vous trouverez ci-dessous le code à coller dans Google Colaboratory pour votre référence.

Après avoir exécuté jusqu'à l'étape 4 de [Exécution de l'apprentissage automatique ci-dessus](# Exécution de l'apprentissage automatique) Vous devriez être capable de deviner le titre de la chanson en procédant comme suit.

Par analogie du titre de la chanson



import pickle, tfidfWithIni
import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop
from keras.models import model_from_json
import importlib

#Rechargement du module (tfidfWithIni)
importlib.reload(tfidfWithIni)

def inverse_dict(d):
    return {v:k for k,v in d.items()}

#Jugement en spécifiant du texte
def getMusicName(text):
    # TF-Convertir en vecteur IDF
    data = tfidfWithIni.calc_text(text)
    #Prédite par MLP
    pre = model.predict(np.array([data]))[0]
    n = pre.argmax()
    print("Nom de chanson recommandé: " + label_dic[n], "(", pre[n], ")")
    

#Définition d'étiquette
labelToCode = pickle.load(open("text/label_to_code.pickle", "rb"))
nb_classes = len(labelToCode) 
label_dic = inverse_dict(labelToCode)

#Recherchez le nombre d'éléments d'entrée dans le dictionnaire.
in_size_hantei = pickle.load(open("text/genre-tdidf.dic", "rb"))[0]['_id']

# TF-Lire le dictionnaire IDF
tfidfWithIni.load_dic("text/genre-tdidf.dic")

#Définir le modèle Keras et lire les données de poids
model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(in_size_hantei,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(nb_classes, activation='softmax'))
model.compile(
    loss='categorical_crossentropy',
    optimizer=RMSprop(),
    metrics=['accuracy'])
model.load_weights('./text/genre-model.hdf5')
    
if __name__ == '__main__':
    requestParam = """
Une chanson qui est triste et souhaite le bonheur de quelqu'un
    """
    getMusicName(requestParam)

Il peut changer en fonction du résultat d'apprentissage, mais il sera affiché comme suit.

Nom de chanson recommandé:Les nuages s'en vont( 0.99969995 )

Dernière fois Je fais une petite analogie du titre de la chanson avec l'API Web en utilisant Flask, donc j'aimerais l'omettre: sueur:

À propos du futur

Cette fois, j'ai pu organiser un peu le machine learning. Aussi, j'espère pouvoir le rafraîchir et l'organiser petit à petit quand j'en ai le temps: sanglot: C'est indécis, mais la prochaine fois, j'aimerais organiser la construction de l'environnement côté écran.

chapitre Classification Statut Contenu Langue, FW, environnement, etc.
Préface Commun Déjà Aperçu de l'application Python
TensorFlow
Keras
Google Colaboratory
chapitre un Web API Déjà Construction de l'environnement (environnement d'exécution) docker-compose
Flask
Nginx
gunicorn
Chapitre II Web API Déjà Apprentissage automatique Python
TensorFlow
Keras
Flask
chapitre 3 écran pas encore commencé (Prochaine fois) Construction de l'environnement Python
Django
Nginx
gunicorn
PostgreSQL
virtualenv
Chapitre 4 écran pas encore commencé Affichage, partie d'appel d'API Web Python
Django
Chapitre 5 AWS pas encore commencé Déploiement automatique AWS Github
EC2
CodeDeploy
CodePipeline

Recommended Posts

(Remarque) Application Web qui utilise TensorFlow pour déduire les noms de morceaux recommandés [Apprentissage automatique]
(Remarque) Une application Web qui utilise TensorFlow pour déduire les noms de morceaux recommandés.
(Remarque) Une application Web qui utilise TensorFlow pour déduire les noms de morceaux recommandés [Créer un environnement d'exécution avec docker-compose]
Je souhaite créer une application WEB en utilisant les données de League of Legends ①
Notez que j'étais accro à accéder à la base de données avec mysql.connector de Python en utilisant une application Web
J'ai créé une application Web en Python qui convertit Markdown en HTML
[Python] Conception d'applications Web pour l'apprentissage automatique
Version gratuite de DataRobot! ?? Introduction à «PyCaret», une bibliothèque qui automatise l'apprentissage automatique
Une histoire sur l'apprentissage automatique simple avec TensorFlow
Étapes pour développer une application Web en Python
Installation de TensorFlow, une bibliothèque d'apprentissage automatique de Google
Créer un environnement de développement d'applications d'apprentissage automatique avec Python
Les débutants en apprentissage automatique essaient de créer un arbre de décision
Introduction à l'apprentissage automatique à partir de Simple Perceptron
MALSS (introduction), un outil qui prend en charge l'apprentissage automatique en Python
Une note qui déploie une application Python de Circle CI vers Elastic Beanstalk et avertit Slack
Création d'un outil qui facilite la définition des paramètres des modèles d'apprentissage automatique