ANN/ORE #2 – Construction du réseau de neurones avec nnet
Une fois les données du dataset MNIST chargées en base, il est possible de les utiliser pour construire un ANN. Le problème est que le volume de ces dernières combiné aux besoins de calcul de la construction du modèle exclut l’utilisation de mon PC de bureau.
Je vais donc délocaliser le traitement sur le serveur de base de données dont les specs sont nettement plus avantageuses: HP ProLiant BL460c en 2s 24c 48t (processeur Xeon E5-2695v2 à 2.40GHz) avec 256GB de RAM.
Pour cela, je vais utiliser ORE afin de construire un ANN dans une session R instanciée sur le serveur de base de données (via extproc).
A l’instar des billets précédents, je vais utiliser le package standard nnet pour construire le réseau de neurones. Ce package est disponible en standard avec la distribution R.
En revanche, pour mesurer la durée des traitements, je vais utiliser le package tictoc. Ce dernier doit donc au préalable être chargé sur le serveur:
oracle@psu888: /home/oracle [HODBA04D1_1]# ORE CMD INSTALL /tmp/tictoc_1.0.tar.gz * installing to library ‘/soft/oracle/product/rdbms/12.2.0.1/R/library’ * installing *source* package ‘tictoc’ ... ** package ‘tictoc’ successfully unpacked and MD5 sums checked ** R ** inst ** preparing package for lazy loading ** help *** installing help indices converting help for package ‘tictoc’ finding HTML links ... done Stack html tic html tictoc html ** building package indices ** testing if installed package can be loaded * DONE (tictoc) oracle@psu888: /home/oracle [HODBA04D1_1]#
Dans l’absolu, je pourrai travailler directement sur le serveur de base de données mais je trouve plus confortable d’utiliser RStudio depuis mon PC et donc d’invoquer les commandes via les API ORE.
> ore.connect(user="c##rafa", password="Password1#", conn_string="//clorai2-scan:1521/pdb_hodba08") > > ore.doEval(function() { + library(ORE) + library(nnet) + library(tictoc) + set.seed(7777) + ore.sync(table = "MNIST_TRAINING_SET") + mnist_train <- ore.pull(ore.get("MNIST_TRAINING_SET")) + tic() + nn_nnet <- nnet(IMG_LBL ~ . - IMG_ID, data=mnist_train, size=100, maxit=100, MaxNWts=80000) + exectime <- toc() + exectime <- exectime$toc - exectime$tic + ore.save(list=c("nn_nnet"),name="DS NeuralNet", append = TRUE) + print(paste(" -> Duree :", exectime, "secondes"))}, ore.connect = TRUE) [1] " -> Duree : 49865.035 secondes" >
Ci-dessus j’utilise ore.doEval pour lancer la construction d’un ANN avec un hidden layer de 100 neurones sur le serveur Oracle. Une fois le modèle créé, je le sauvegarde dans un datastore ORE via ore.save. Le champ IMG_LBL étant convertit sous la forme de facteur lors de sa récupération, la commande nnet construit un ANN multiclasse (via un encodage one-hot implicite):
On peut voir que la création du modèle a duré extrêmement longtemps – quasiment 14 heures!
Le taille du modèle généré est d’environ 400MB:
> ore.datastore() datastore.name object.count size creation.date description 1 DS NeuralNet 1 407018410 2017-08-04 23:55:24 > ore.datastoreSummary("DS NeuralNet") object.name class size length row.count col.count 1 nn_nnet nnet.formula 407018410 19 NA NA >
En revanche, pour le scoring, je vais travailler sur mon poste de travail – il me faut donc rapatrier localement le modèle et les données de validation croisée:
> ore.attach() > ore.sync(table="MNIST_TEST_SET") > mnist_test <- ore.pull(MNIST_TEST_SET) > > library(nnet) > > ore.load("DS NeuralNet", list = c("nn_nnet")) [1] "nn_nnet" > > pred <- predict(nn_nnet, newdata=mnist_test, supplemental_cols=c("IMG_ID","IMG_LBL"), type="class") >
On peut voir via une table de contingence que l’essentiel des images sont correctement catégorisées:
> table(mnist_test$IMG_LBL,pred) pred 0 1 2 3 4 5 6 7 8 9 0 962 1 2 0 0 4 4 1 4 2 1 0 1124 3 0 0 1 2 2 2 1 2 3 2 992 13 4 0 4 6 8 0 3 0 0 9 974 0 14 0 4 3 6 4 0 0 5 1 950 1 3 4 1 17 5 4 2 1 17 3 855 4 0 3 3 6 4 2 2 2 9 5 929 1 4 0 7 1 2 12 9 2 0 0 992 3 7 8 6 0 4 14 2 5 2 3 935 3 9 1 3 0 6 7 5 2 6 3 976 >