[PYTHON] J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker

J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker

En février 2017, Yahoo! A publié une bibliothèque qui distribue TensorFlow avec Spark. http://yahoohadoop.tumblr.com/post/157196317141/open-sourcing-tensorflowonspark-distributed-deep

Personnellement, j'ai joué avec Docker, mais qu'en est-il de Keras? Donc, cette fois, je vais exécuter Dist-Keras, qui distribue Keras avec Spark, avec Docker.

L'objectif est d'utiliser la bibliothèque d'apprentissage en profondeur de manière évolutive. En utilisant GPGPU, je pense que l'apprentissage en profondeur se concentre sur la mise à l'échelle.

Cependant, si nous combinons la mise à l'échelle, qui nécessite les performances des dispositifs informatiques pour accélérer le traitement, et la montée en charge, qui nécessite le nombre de dispositifs informatiques, nous devrions être en mesure d'effectuer un traitement plus rapide. De plus, je pense personnellement que les pauvres qui n'ont pas de GPU feront de leur mieux à la montée en puissance (celui-ci est plus urgent (rires)). Par conséquent, j'ai installé Keras, une bibliothèque d'apprentissage en profondeur, dans le conteneur Docker, démarré plusieurs conteneurs et essayé de distribuer la charge par montée en puissance parallèle. Comme il n'est pas possible de monter en charge avec Keras normal, cette fois, nous utiliserons une bibliothèque qui exécute Keras avec Spark.

Keras on Spark

Il semble qu'il existe deux bibliothèques qui distribuent Keras avec Spark.

Le premier est Elephas, qui semble exister depuis environ un an. http://maxpumperla.github.io/elephas/

L'autre est Dist-Keras, qui est publié par le CERN (Organisation européenne de recherche nucléaire!). http://joerihermans.com/work/distributed-keras/ https://db-blog.web.cern.ch/blog/joeri-hermans/2017-01-distributed-deep-learning-apache-spark-and-keras

CERN est l'histoire originale de SERN de STEINS; GATE. Le CERN semble connaître Rintaro Okabe. http://gigazine.net/news/20140623-ama-cern/

Que faire cette fois

Cette fois, je vais exécuter Dist-Keras du CERN avec Docker et exécuter MNIST. J'ai choisi Dist-Keras simplement parce qu'il a été mis à jour récemment et que cela a fonctionné.

J'ai aussi touché Elephas à mi-chemin, donc je vais peut-être recommencer bientôt.

La raison pour laquelle Dist-Keras s'exécute sur Docker est que les conteneurs sont plus faciles à configurer que les machines virtuelles. Il est normal d'avoir plusieurs EC2, mais c'est un problème si le coût est élevé, j'ai donc démarré 3 conteneurs de Docker dans une machine virtuelle. L'un est un maître / travailleur Spark (esclave) et les autres sont des travailleurs. Il sera configuré comme ceci.

14.jpg

Dist-Keras Le CERN est enthousiasmé par Dist-Keras, alors lisez la suite.

https://db-blog.web.cern.ch/blog/joeri-hermans/2017-01-distributed-deep-learning-apache-spark-and-keras

Je vais traduire certains d'entre eux.


Distributed Keras Distributed Keras est un framework d'apprentissage en profondeur distribué créé à l'aide d'Apache Spark et de Keras. Le but est d'améliorer considérablement le temps d'apprentissage de l'apprentissage automatique et de permettre d'analyser des ensembles de données qui dépassent la capacité de la mémoire. Le projet a démarré en août 2016 en collaboration avec CMS.

Architecture Fondamentalement, le processus d'apprentissage est transmis au worker Spark par la fonction Lambda. Cependant, lors du passage de plusieurs paramètres, tels que le numéro de port du serveur de paramètres, nous les avons tous enveloppés dans des objets et les avons transformés en fonctions d'apprentissage qui pourraient utiliser les paramètres nécessaires à Spark. Pour avoir une vue d'ensemble de l'ensemble, expliquons-nous avec la figure suivante. L'objet d'apprentissage démarre d'abord le serveur de paramètres avec le pilote Spark. Ensuite, démarrez le processus de travail. Il contient tous les paramètres et processus nécessaires pour entraîner le modèle Keras. En outre, afin de préparer un nombre nécessaire de travailleurs pour un traitement parallèle, l'ensemble de données est divisé par une capacité prédéterminée. Cependant, lors du traitement de Big Data, il est souhaitable d'augmenter les éléments du traitement parallèle. Ce faisant, vous pouvez éviter une situation dans laquelle un travailleur est inactif alors qu'un autre travailleur moins capable n'a pas fini de tourner le lot (c'est ce qu'on appelle le problème de la difficulté). Dans ce cas, accédez à la Documentation Spark En tant que tel, il est recommandé de définir l'élément de distribution sur 3.

Cependant, il peut arriver que vous deviez envisager d'utiliser des éléments distribués plus volumineux. Fondamentalement, le traitement distribué est proportionnel au nombre de partitions (nombre de divisions). Par exemple, supposons que vous affectiez 20 travailleurs à une tâche et que vous définissiez l'élément de distribution sur 3. Spark divise l'ensemble de données en 60 fragments. Et avant que les travailleurs puissent commencer à traiter les partitions, ils doivent d'abord charger toutes les bibliothèques Python nécessaires pour traiter la tâche, puis désérialiser et compiler le modèle Keras. Ce processus représente une surcharge importante. En tant que telle, cette technique n'est utile que lorsqu'il s'agit de grands ensembles de données sur des systèmes non hétérogènes qui nécessitent une longue surcharge de préchauffage (c'est-à-dire que chaque travailleur a une charge de matériel ou une valeur différente).

11.JPG


Dist-Keras Instrallation Dist-Keras est publié sur Github. https://github.com/cerndb/dist-keras

Spark et Keras doivent être installés avant d'installer Dist-Keras. La méthode d'installation de ceux-ci est la suivante. https://spark.apache.org/docs/latest/index.html https://keras.io/ja/

Pour installer Dist-Keras, utilisez la commande suivante.

## if you need git, run "yum -y install git" beforehand
git clone https://github.com/JoeriHermans/dist-keras
cd dist-keras
pip install -e .

Je l'ai essayé sur la machine virtuelle CentOS 7.3 et le conteneur Docker (CentOS 7.3), et j'ai pu l'installer sans me coincer.

Que faire cette fois encore

Eh bien, cela fait longtemps, mais ce que nous faisons cette fois-ci, c'est d'exécuter Dist-Keras dans un conteneur Docker et de distribuer l'apprentissage du modèle Keras parmi les conteneurs. Nous déploierons à nouveau la configuration suivante.

14.jpg

Dist-Keras on Docker Dist-Keras n'a ni fichier Docker ni image Docker, donc je l'ai fait moi-même. https://github.com/shibuiwilliam/distkeras-docker

git clone téléchargera le Dockerfile et spark_run.sh.

git clone https://github.com/shibuiwilliam/distkeras-docker.git

Accédez au répertoire distkeras-docker et effectuez une construction de docker.

cd distkeras-docker
docker build -t distkeras .

Cela prendra du temps, mais attendons lentement. Les principales choses que fait docker build sont:

--Installation des outils nécessaires --Installation et configuration de Python et Jupyter Notebook --Installation et configuration de Standalone Spark --Installation de Dist keras

Le conteneur de base est CentOS. Spark est 2.1.0 et Keras est 2.0.2, tous deux utilisant la dernière version.

Déplaçons-le dès que la construction du docker est terminée. Cette fois, nous allons démarrer 3 conteneurs Docker pour évoluer.

# docker dist-keras for spark master and slave
docker run -it -p 18080:8080 -p 17077:7077 -p 18888:8888 -p 18081:8081 -p 14040:4040 -p 17001:7001 -p 17002:7002 \
 -p 17003:7003 -p 17004:7004 -p 17005:7005 -p 17006:7006 --name spmaster -h spmaster distkeras /bin/bash

# docker dist-keras for spark slave1
docker run -it --link spmaster:master -p 28080:8080 -p 27077:7077 -p 28888:8888 -p 28081:8081 -p 24040:4040 -p 27001:7001 \
-p 27002:7002 -p 27003:7003 -p 27004:7004 -p 27005:7005 -p 27006:7006 --name spslave1 -h spslave1 distkeras /bin/bash

# docker dist-keras for spark slave2
docker run -it --link spmaster:master -p 38080:8080 -p 37077:7077 -p 38888:8888 -p 38081:8081 -p 34040:4040 -p 37001:7001 \
-p 37002:7002 -p 37003:7003 -p 37004:7004 -p 37005:7005 -p 37006:7006 --name spslave2 -h spslave2 distkeras /bin/bash


Il se compose de Spark master / worker (spmaster), worker 1 (spslave1) et worker 2 (spslave2). Exécutez le maître et le nœud de calcul Spark avec spmaster, et joignez spslave1 et spslave2 en tant que nœuds de calcul (esclave) au cluster Spark.

Les scripts de démarrage Spark Master et Worker sont fournis respectivement sous la forme /opt/spark_master.sh et /opt/spark_slave.sh. Puisqu'il est déplacé vers le répertoire / opt / lorsque chaque conteneur est démarré, le maître et le travailleur peuvent être démarrés en y exécutant des commandes.

#Exécuter sur Spark Master
#Le maître et le travailleur démarrent, le travailleur rejoint le cluster
sh spark_master.sh

# Spark spslave1,Courir en 2
#Le travailleur démarre et rejoint le cluster principal
sh spark_slave.sh

Vous avez maintenant un maître et trois nœuds de calcul dans votre cluster Spark. Vous pouvez le vérifier sur la console Spark Master. http://<spark master>:18080

18.JPG

Dans ce domaine, j'aimerais démarrer plusieurs unités à la fois avec Docker compose ou Swarm, mais c'est aussi mon devoir à une date ultérieure.

MNIST à Keras sur Spark

Essayons MNIST avec Dist-Keras. L'exemple de code MNIST est fourni par Dist-Keras. Le répertoire est / opt / dist-keras / examples, qui contient les exemples de données et programmes suivants.

[root@spm examples]# tree
.
|-- cifar-10-preprocessing.ipynb
|-- data
|   |-- atlas_higgs.csv
|   |-- mnist.csv
|   |-- mnist.zip
|   |-- mnist_test.csv
|   `-- mnist_train.csv
|-- example_0_data_preprocessing.ipynb
|-- example_1_analysis.ipynb
|-- kafka_producer.py
|-- kafka_spark_high_throughput_ml_pipeline.ipynb
|-- mnist.ipynb
|-- mnist.py
|-- mnist_analysis.ipynb
|-- mnist_preprocessing.ipynb
|-- spark-warehouse
`-- workflow.ipynb

Cette fois, mnist.py est exécuté, mais certains codes doivent être modifiés en fonction de l'environnement.

Copiez le fichier d'origine, sauvegardez-le et appliquez les modifications suivantes.

cp mnist.py mnist.py.bk

Modifier 1 importation de la session Spark

Ajoutez ce qui suit au début.

from pyspark.sql import SparkSession

Modification 2 Réglage des paramètres

Modifiez les paramètres Spark pour cet environnement. L'intention du changement est la suivante.

--Utilisation de Spark2 --Utilisation de l'environnement local --Définir l'URL principale dans l'environnement local

# Modify these variables according to your needs.
application_name = "Distributed Keras MNIST"
using_spark_2 = True  # False→True
local = True  # False→True
path_train = "data/mnist_train.csv"
path_test = "data/mnist_test.csv"
if local:
    # Tell master to use local resources.
#     master = "local[*]"   comment out
    master = "spark://spm:7077"  # add
    num_processes = 1
    num_executors = 3  # 1→3
else:
    # Tell master to use YARN.
    master = "yarn-client"
    num_executors = 20
    num_processes = 1
Modifier la mémoire de 3 Worker

Changez la mémoire du travailleur de 4G à 2G. Ce n'est pas un changement obligatoire car il est simplement adapté à votre environnement.

conf = SparkConf()
conf.set("spark.app.name", application_name)
conf.set("spark.master", master)
conf.set("spark.executor.cores", `num_processes`)
conf.set("spark.executor.instances", `num_executors`)
conf.set("spark.executor.memory", "2g") # 4G→2G
conf.set("spark.locality.wait", "0")
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");

Vous êtes maintenant prêt. Déplaçons MNIST.

python mnist.py

Vous pouvez vérifier l'état d'exécution sur la console Spark Master. http://<spark master>:18080

10.JPG

Bien sûr, vous pouvez également ouvrir des détails tels que Jobs et Executer.

Écran des travaux 12.JPG

Écran de l'exécuteur 13.JPG

Les données sont chargées dans 3 travailleurs et MNIST est en cours de formation. À propos, le modèle de MNIST est le suivant.

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_1 (Conv2D)            (None, 26, 26, 32)        320
_________________________________________________________________
activation_1 (Activation)    (None, 26, 26, 32)        0
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 24, 24, 32)        9248
_________________________________________________________________
activation_2 (Activation)    (None, 24, 24, 32)        0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 12, 12, 32)        0
_________________________________________________________________
flatten_1 (Flatten)          (None, 4608)              0
_________________________________________________________________
dense_1 (Dense)              (None, 225)               1037025
_________________________________________________________________
activation_3 (Activation)    (None, 225)               0
_________________________________________________________________
dense_2 (Dense)              (None, 10)                2260
_________________________________________________________________
activation_4 (Activation)    (None, 10)                0
=================================================================
Total params: 1,048,853.0
Trainable params: 1,048,853.0
Non-trainable params: 0.0
_________________________________________________________________

Le programme sera terminé dans environ 30 minutes.

Résultats MNIST

Le résultat d'essayer avec 3 ouvriers est le suivant.

Training time: 1497.86584091
Accuracy: 0.9897
Number of parameter server updates: 3751

Avec un temps d'apprentissage de moins de 25 minutes, la précision était de 0,9897. Comme ci comme ça.

À propos, le résultat d'essayer avec un seul travailleur est le suivant.

Training time: 1572.04011703
Accuracy: 0.9878
Number of parameter server updates: 3751

~~ ・ ・ ・ 3 ouvriers ou 1 ouvrier ne peuvent prendre qu'environ 1 minute (-_-;) ~~

~~ Est-ce le choix de Steins Gate ... ~~ 17.jpg

Perspectives d'avenir

Cette fois, j'ai démarré le conteneur Docker sur le même serveur, mais je pense que la répartition de charge d'origine est réalisée sur les serveurs. À l'avenir, j'aimerais démarrer le conteneur Dist-Keras sur plusieurs serveurs et ECS, configurer un cluster Spark et répartir la charge.

[PostScript 2017/04/16] Nous avons vérifié comment améliorer les performances. http://qiita.com/cvusk/items/f54ce15f8c76a396aeb1

[PostScript du 26/05/2017] Clustered avec Kubernetes. http://qiita.com/cvusk/items/42a5ffd4e3228963234d

Recommended Posts

J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker
J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker 2 Multi-host edition
J'ai essayé d'écrire dans un modèle de langage profondément appris
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 16) J'ai essayé de créer SimpleConvNet avec Keras
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 17) J'ai essayé de créer DeepConvNet avec Keras
J'ai essayé de faire d'Othello AI que j'ai appris 7,2 millions de mains par apprentissage profond avec Chainer
J'ai essayé le deep learning
J'ai essayé de déplacer GAN (mnist) avec keras
J'ai essayé d'intégrer Keras dans TFv1.1
J'ai essayé de mettre en œuvre un apprentissage en profondeur qui n'est pas profond avec uniquement NumPy
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
J'ai essayé d'extraire le dessin au trait de l'image avec Deep Learning
J'ai essayé d'implémenter Cifar10 avec la bibliothèque SONY Deep Learning NNabla [Nippon Hurray]
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
J'ai essayé de créer une application OCR avec PySimpleGUI
[Deep Learning from scratch] J'ai essayé d'expliquer le décrochage
J'ai essayé de faire une simulation de séparation de source sonore en temps réel avec l'apprentissage automatique Python
Mayungo's Python Learning Episode 3: J'ai essayé d'imprimer des nombres
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai capturé le projet Toho avec Deep Learning ... je le voulais.
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
J'ai essayé d'implémenter Perceptron Part 1 [Deep Learning from scratch]
Faites de l'art ASCII avec l'apprentissage en profondeur
J'ai essayé l'apprentissage automatique avec liblinear
J'ai essayé l'apprentissage en profondeur avec Theano
Faites sourire les gens avec le Deep Learning
J'ai essayé d'apprendre LightGBM avec Yellowbrick
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé l'apprentissage par renforcement profond (Double DQN) avec ChainerRL
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
J'ai essayé de créer une application todo en utilisant une bouteille avec python
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
J'ai essayé de créer un mécanisme de contrôle exclusif avec Go
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé de visualiser AutoEncoder avec TensorFlow
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Introduction ~
J'ai essayé de commencer avec Hy
J'ai essayé d'apprendre avec le Titanic de Kaggle (kaggle②)
J'ai essayé d'implémenter CVAE avec PyTorch
J'ai créé une API Web
J'ai essayé de résoudre TSP avec QAOA
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Implémentation ~
J'ai créé un capteur d'ouverture / fermeture (lien Twitter) avec TWE-Lite-2525A
[Deep Learning from scratch] J'ai essayé d'implémenter la couche sigmoïde et la couche Relu
Mayungo's Python Learning Episode 2: J'ai essayé de mettre des caractères avec des variables
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai écrit un diagramme de configuration du système avec des diagrammes sur Docker
[AWS] [GCP] J'ai essayé de rendre les services cloud faciles à utiliser avec Python
J'ai essayé de faire un signal avec Raspeye 4 (édition Python)
(Apprentissage automatique) J'ai essayé de comprendre attentivement la régression linéaire bayésienne avec l'implémentation
J'ai essayé de faire la reconnaissance de caractères manuscrits de Kana Partie 2/3 Création et apprentissage de données
J'ai essayé de visualiser le modèle avec la bibliothèque d'apprentissage automatique low-code "PyCaret"