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. 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:
Je l'ai utilisé comme référence lors de la création de cet article: bow_tone1:
** (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 |
* 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
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.
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. 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é.
Le flux suivant est du point de vue du développeur et correspond au flux jusqu'à l'apprentissage automatique. 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.
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 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.
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
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.
Le dictionnaire pour le calcul TF-IDF est la conversion des mots utilisés dans le calcul en ID comme suit.
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:
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))
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.
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:
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 |