[DL4J] Premier apprentissage en profondeur Java (reconnaissance de caractères manuscrits à l'aide d'un réseau neuronal entièrement connecté)

Bonjour. Même si c'est un jour de mer, Tokyo est toujours cool.

Aujourd'hui 15 juillet 2019, la température la plus élevée à Tokyo était de 25 ° C et la température la plus basse était de 19 ° C. Selon les archives de l'Agence météorologique, les températures maximales et minimales moyennes à Tokyo de 1981 à 2010 sont les suivantes.

Température maximale moyenne Température minimale moyenne
29.0℃ 21.7℃

(Source: https://www.data.jma.go.jp/obd/stats/etrn/view/nml_sfc_d.php?prec_no=44&block_no=47662&year=0month=7&day=1view=p1)

Personnellement, j'aime le climat actuel car c'est facile à dépenser, mais combien de temps durera-t-il?

Deeplearning4j / DL4J

Maintenant, en changeant l'histoire, cet article présente ** Deeplearning4j **, ou ** DL4J ** pour faire court, développé par ** Skymind **. Comme son nom l'indique, DL4J est un framework de développement d'apprentissage en profondeur ** qui s'exécute dans des ** langages JVM tels que ** Java **, ** Scala ** et ** Kotlin **. Parmi les autres frameworks d'apprentissage profond bien connus, citons TensorFlow de Google, Keras qui y est intégré, PyTorch de FaceBook et Chainer de Preferred Networks. Ces frameworks sont fondamentalement supposés être développés en Python, et vous pouvez facilement rechercher et développer avec un petit nombre de codes.

DL4J se distingue comme un ** framework d'entreprise ** car il peut être écrit dans le langage JVM largement utilisé dans les systèmes d'entreprise. ** L'un des arguments de vente est la possibilité de se lier nativement avec des plates-formes d'analyse de Big Data telles que Hadoop et Spark **.

Jetons un coup d'œil à un exemple de construction d'un réseau de neurones à l'aide de DL4J.

Exemple de code DL4J

L'exemple de code DL4J est disponible en abondance dans le référentiel officiel. https://github.com/deeplearning4j/dl4j-examples

L'échelle est trop grande pour essayer, donc clonez le référentiel suivant, qui n'a dérivé que du code cette fois.

python


$ git clone https://github.com/kmotohas/oreilly-book-dl4j-examples-ja

Il s'agit de la version japonaise de "Deep Learning - A Practitioner's Approach" écrite par Adam Gibson et al., L'auteur de DL4J lui-même. Explication détaillée Approche de l'apprentissage profond pour les praticiens "](https://www.amazon.co.jp/dp/4873118808/) est un référentiel public d'exemples de code.

À titre d'exemple simple, l'ensemble de données numériques manuscrites MNIST standard est reconnu par un perceptron multicouche (MLP, également un réseau de neurones entièrement connecté dans une définition lâche) MLPMnistTwoLayerExample.java Jetons un coup d'œil au contenu de -dl4j-examples-ja / blob / master / dl4j-examples / src / main / java / org / deeplearning4j / examples / feedforward / mnist / MLPMNistTwoLayerExample.java).

Il est recommandé d'exécuter l'exemple à l'aide d'un environnement de développement intégré tel qu'Intellij IDEA, mais il est également possible de l'exécuter sur la ligne de commande à l'aide d'un outil de génération tel que Maven.

Vue d'ensemble de MLPMnistTwoLayerExample.java

Le code suivant est le code entier sans l'instruction d'ouverture ʻimport`.

python


public class MLPMnistTwoLayerExample {

    private static Logger log = LoggerFactory.getLogger(MLPMnistSingleLayerExample.class);

    public static void main(String[] args) throws Exception {
        //number of rows and columns in the input pictures
        final int numRows = 28;
        final int numColumns = 28;
        int outputNum = 10; // number of output classes
        int batchSize = 64; // batch size for each epoch
        int rngSeed = 123; // random number seed for reproducibility
        int numEpochs = 15; // number of epochs to perform
        double rate = 0.0015; // learning rate

        //Get the DataSetIterators:
        DataSetIterator mnistTrain = new MnistDataSetIterator(batchSize, true, rngSeed);
        DataSetIterator mnistTest = new MnistDataSetIterator(batchSize, false, rngSeed);


        log.info("Build model....");
        MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
            .seed(rngSeed) //include a random seed for reproducibility
            .activation(Activation.RELU)
            .weightInit(WeightInit.XAVIER)
            .updater(new Nesterovs(rate, 0.98)) //specify the rate of change of the learning rate.
            .l2(rate * 0.005) // regularize learning model
            .list()
            .layer(0, new DenseLayer.Builder() //create the first input layer.
                    .nIn(numRows * numColumns)
                    .nOut(500)
                    .build())
            .layer(1, new DenseLayer.Builder() //create the second input layer
                    .nIn(500)
                    .nOut(100)
                    .build())
            .layer(2, new OutputLayer.Builder(LossFunction.NEGATIVELOGLIKELIHOOD) //create hidden layer
                    .activation(Activation.SOFTMAX)
                    .nIn(100)
                    .nOut(outputNum)
                    .build())
            .build();

        MultiLayerNetwork model = new MultiLayerNetwork(conf);
        model.init();
        model.setListeners(new ScoreIterationListener(5));  //print the score with every iteration

        log.info("Train model....");
        for( int i=0; i<numEpochs; i++ ){
        	log.info("Epoch " + i);
            model.fit(mnistTrain);
        }


        log.info("Evaluate model....");
        Evaluation eval = new Evaluation(outputNum); //create an evaluation object with 10 possible classes
        while(mnistTest.hasNext()){
            DataSet next = mnistTest.next();
            INDArray output = model.output(next.getFeatures()); //get the networks prediction
            eval.eval(next.getLabels(), output); //check the prediction against the true class
        }

        log.info(eval.stats());
        log.info("****************Example finished********************");
    }
}

La méthode «main» de cette classe est grossièrement divisée en quatre parties.

  1. Préparation de «DataSetIterator»

J'expliquerai chaque partie à tour de rôle.

1. Préparation de «DataSetIterator»

L'entraînement d'un modèle en apprentissage en profondeur consiste à entrer un ensemble de données dans le modèle et à mettre à jour les paramètres pour minimiser la différence entre la sortie attendue et réelle.

Dans DL4J, [DataSetIterator](https://github.com/eclipse/deeplearning4j/blob/master/nd4j/nd4j-backends/nd4j-api-parent/nd4j] est utilisé comme itérateur pour alimenter le modèle de manière itérative. -Une classe appelée api / src / main / java / org / nd4j / linalg / dataset / api / iterator / DataSetIterator.java) est fournie. (En fait [implémenté] dans la bibliothèque ND4J, qui peut également être appelée la version JVM Numpy (https://github.com/eclipse/deeplearning4j/blob/master/nd4j/nd4j-backends/nd4j-api-parent/nd4j-api/src/main /java/org/nd4j/linalg/dataset/api/iterator/DataSetIterator.java). Il hérite de java.util.Iterator et java.io.Serializable.)

Le jeu de données MNIST de numéros de texte manuscrite contient 70 000 images numérotées manuscrites et des étiquettes correctes (numéros dessinés sur les images. Informations sur 0,1,2,3, ..., 9). En règle générale, ils sont divisés et 60 000 sont utilisés comme ensembles de données d'entraînement et 10 000 sont utilisés comme ensembles de données de test d'évaluation des performances.

image.png

(Source: https://weblabo.oscasierra.net/python/ai-mnist-data-detail.html)

Comme le montre la figure ci-dessous, il peut être en outre divisé en données de vérification pour un réglage d'hyper paramètre tel que la vitesse d'apprentissage, mais cette fois, il ne sera pas traité.

image.png

(Source: https://www.procrasist.com/entry/10-cross-validation)

Comme d'autres frameworks, DL4J dispose d'un itérateur dédié à MNIST. Il existe également des itérateurs pour d'autres ensembles de données bien connus tels que CIFAR-10 et Tiny ImageNet. Consultez la documentation officielle (https://deeplearning4j.org/docs/latest/deeplearning4j-nn-iterators) pour plus d'informations.

Des informations telles que «RecordReaderDataSetIterator» pour les propres images et ensembles de données tels que CSV et «SequenceRecordReaderDataSetIterator» pour les données de séquence sont également sur la même page.

python


        //Get the DataSetIterators:
        DataSetIterator mnistTrain = new MnistDataSetIterator(batchSize, true, rngSeed);
        DataSetIterator mnistTest = new MnistDataSetIterator(batchSize, false, rngSeed);

Ici, nous avons un itérateur pour la formation et un itérateur pour les tests. [Code source pour MnistDataSetIterator](https://github.com/eclipse/deeplearning4j/blob/master/deeplearning4j/deeplearning4j-data/deeplearning4j-datasets/src/main/java/org/deeplearning4jator/datas/org/deeplearning4jator De /MnistDataSetIterator.java), je citerai le constructeur utilisé cette fois.

python


public MnistDataSetIterator(int batchSize, boolean train, int seed)

Les arguments sont les suivants.

--ʻInt batchSize: La taille du mini-lot, c'est-à-dire le nombre d'échantillons à entrer dans le modèle en une itération d'apprentissage --boolean train: valeur booléenne indiquant s'il s'agit de données d'entraînement ou de données de test --ʻInt seed: graine aléatoire lors de la lecture aléatoire d'un ensemble de données

2. Configuration de MultiLayerConfiguration

C'est la partie où le réseau neuronal est conçu. Utilisez MultiLayerConfiguration pour empiler les couches séquentiellement pour Keras.

Si vous voulez construire un réseau avec des branches compliquées, utilisez ComputationGraphConfiguration. C'est comme l'API fonctionnelle de Keras. Pour plus de détails, reportez-vous à ce document.

python


        MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
            .seed(rngSeed) //include a random seed for reproducibility
            .activation(Activation.RELU)
            .weightInit(WeightInit.XAVIER)
            .updater(new Nesterovs(rate, 0.98)) //specify the rate of change of the learning rate.
            .l2(rate * 0.005) // regularize learning model
            .list()
            .layer(0, new DenseLayer.Builder() //create the first input layer.
                    .nIn(numRows * numColumns)
                    .nOut(500)
                    .build())
            .layer(1, new DenseLayer.Builder() //create the second input layer
                    .nIn(500)
                    .nOut(100)
                    .build())
            .layer(2, new OutputLayer.Builder(LossFunction.NEGATIVELOGLIKELIHOOD) //create hidden layer
                    .activation(Activation.SOFTMAX)
                    .nIn(100)
                    .nOut(outputNum)
                    .build())
            .build();

MultiLayerConfiguration est implémenté dans le soi-disant modèle Builder. Vous pouvez personnaliser votre réseau en spécifiant des paramètres sous la forme «. <Paramètre>».

python


        MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
            .seed(rngSeed) //include a random seed for reproducibility
            .activation(Activation.RELU)
            .weightInit(WeightInit.XAVIER)
            .updater(new Nesterovs(rate, 0.98)) //specify the rate of change of the learning rate.
            .l2(rate * 0.005) // regularize learning model
            .list()

La moitié supérieure définit les paramètres pour l'ensemble du réseau. Plus précisément, les paramètres suivants sont définis.

python


            .layer(0, new DenseLayer.Builder() //create the first input layer.
                    .nIn(numRows * numColumns)
                    .nOut(500)
                    .build())
            .layer(1, new DenseLayer.Builder() //create the second input layer
                    .nIn(500)
                    .nOut(100)
                    .build())
            .layer(2, new OutputLayer.Builder(LossFunction.NEGATIVELOGLIKELIHOOD) //create hidden layer
                    .activation(Activation.SOFTMAX)
                    .nIn(100)
                    .nOut(outputNum)
                    .build())
            .build();

La moitié inférieure spécifie la structure de couche du réseau neuronal.

La 0ème connexion utilise une «couche dense» avec une entrée de 28 $ \ fois 28 = 784 $ de dimensions et une sortie de 500 dimensions. L'image MNIST a une hauteur de 28 pixels, une largeur de 28 pixels et en noir et blanc, le nombre de canaux est donc de 1. Pour entrer cela dans la couche entièrement connectée, il est généralement nécessaire de convertir une matrice $ 28 \ fois 28 $ en un vecteur. Cependant, ce travail est inutile car il est déjà enregistré à plat dans l'itérateur pour MNIST de DL4J. Le nombre de 500 dimensions dans la sortie n'a ici aucune signification et est un hyperparamètre qui peut être réglé librement. Ce nombre n'est pas toujours la valeur optimale.

De même, la première connexion a un "DenseLayer" avec une entrée de 500 dimensions (la même valeur que la 0ème sortie) et une sortie de 100 dimensions. Cela semble gênant, mais le nombre à 100 dimensions est une valeur décidée par non et n'a aucune signification.

La deuxième connexion est spéciale et utilise ʻOutputLayer. L'entrée est de 100 dimensions comme dans la connexion précédente et la sortie spécifie 10 étiquettes (0 à 9) pour les données. La fonction d'activation est remplacée par ʻActivation.SOFTMAX et LossFunction.NEGATIVELOGLIKELIHOOD est défini comme fonction de perte. La fonction softmax est une fonction utilisée pour convertir la valeur d'entrée sous forme de probabilité (une valeur positive avec un total de 1) et est un ensemble avec une vraisemblance logarithmique négative (probabilité logarithmique négative) lors de la résolution d'un problème de classification multiclasse. C'est utilisé.

L'image du modèle défini ici est la suivante.

image.png

3. Construisez un MultiLayerNetwork

Créez une instance de MultiLayerNetwork avec MultiLayerConfiguration comme argument pour créer un réseau neuronal!

python


        MultiLayerNetwork model = new MultiLayerNetwork(conf);
        model.init();

4. Formation du modèle de réseau neuronal construit

python


        model.setListeners(new ScoreIterationListener(5));  //print the score with every iteration
        for( int i=0; i<numEpochs; i++ ){
        	log.info("Epoch " + i);
            model.fit(mnistTrain);
        }

Après cela, vous pouvez entraîner le réseau neuronal en appelant fit (DataSetIterator iterator) of MultiLayerNetwork avec l'itérateur des données d'entraînement comme argument. Les données d'entraînement ne sont pas utilisées une seule fois, mais sont essentiellement répétées plusieurs fois. Cette unité répétitive est appelée une époque.

Il est également possible de définir un auditeur pour surveiller l'état de la formation. Ceci est une image du rappel de Keras. ScoreIterationListener (int printIterations) imprime le score (valeur de la fonction de perte) dans la sortie standard après chaque nombre d'itérations spécifié (dans la terminologie DL4J, une itération du paramètre de poids est une itération). ..

Les termes ici se trouvent dans le glossaire officiel (https://skymind.ai/wiki/glossary). Notez que lors de la formation d'un ensemble de données contenant 1000 échantillons avec une taille de mini-lot de 100, 1 époque correspond à 10 itérations. Lorsque vous vous entraînez pendant 30 époques, cela équivaut à 300 itérations.

Vous pouvez utiliser CheckpointListener lorsque vous souhaitez enregistrer le modèle non seulement lorsque la formation est terminée mais également au milieu, ou vous pouvez utiliser ʻEvaluativeListener` lorsque vous voulez évaluer les performances au milieu. Pour les autres écouteurs, consultez la documentation officielle (https://deeplearning4j.org/docs/latest/deeplearning4j-nn-listeners).

5. Évaluation des performances du modèle formé

python


        Evaluation eval = new Evaluation(outputNum); //create an evaluation object with 10 possible classes
        while(mnistTest.hasNext()){
            DataSet next = mnistTest.next();
            INDArray output = model.output(next.getFeatures()); //get the networks prediction
            eval.eval(next.getLabels(), output); //check the prediction against the true class
        }

        log.info(eval.stats());

Pour l'évaluation des performances du modèle à l'aide de données de test, [Public Evaluation (int num Classes)](https://github.com/eclipse/deeplearning4j/blob/master/deeplearning4j/deeplearning4j-nn/src/main/java/ Utilisez une instance de org / deeplearning4j / eval / Evaluation.java). Tournez l'itérateur de test mnistTest, obtenez le vecteur de données avec la méthode getFeatures () et inférez le modèle entraîné [sortie publique INDArray (entrée INDArray)](https://github.com/ eclipse / deeplearning4j / blob / master / deeplearning4j / deeplearning4j-nn / src / main / java / org / deeplearning4j / nn / multilayer / MultiLayerNetwork.java). Étiquetez ce résultat d'inférence et testez les données [public void eval (INDArray realOutcomes, INDArray Guesses)](https://github.com/eclipse/deeplearning4j/blob/master/nd4j/nd4j-backends/nd4j-api- parent / nd4j-api / src / main / java / org / nd4j / evaluation / classification / Evaluation.java) En comparant avec la méthode et en affichant le résultat avec ʻeval.stats () `, le score de précision / précision / rappel / F1 Vous pouvez vérifier la valeur.

Consultez la documentation officielle (https://deeplearning4j.org/docs/latest/deeplearning4j-nn-evaluation) pour plus d'informations.

en conclusion

Cela fait longtemps, mais maintenant [MLPMnistTwoLayerExample.java](https://github.com/kmotohas/oreilly-book-dl4j-examples-ja/blob/master/dl4j-examples/src/main/java/org/ L'explication de deeplearning4j / examples / feedforward / mnist / MLPMNistTwoLayerExample.java) est terminée.

  1. Préparation de «DataSetIterator»

En prenant des mesures telles que, vous pouvez facilement former et évaluer l'apprentissage en profondeur, même avec Java ou Scala. Si vous avez des questions ou des commentaires, veuillez utiliser la section des commentaires ci-dessous ou le canal deeplearning4j-jp de Gitter.

Pour des informations plus détaillées, nous vous recommandons [Approche détaillée d'apprentissage en profondeur pour les praticiens] d'O'Reilly Japan (https://www.amazon.co.jp/dp/4873118808/).

Recommended Posts

[DL4J] Premier apprentissage en profondeur Java (reconnaissance de caractères manuscrits à l'aide d'un réseau neuronal entièrement connecté)
Apprendre pour la première fois java [Introduction]
Mémo d'apprentissage lors de l'apprentissage de Java pour la première fois (mémo d'apprentissage personnel)
Introduction à Java pour la première fois # 2
Premiers pas pour l'apprentissage profond en Java
Deep Learning from scratch Java Chapter 4 Apprentissage des réseaux de neurones
[Deep Learning from scratch] dans Java 3. Réseau neuronal
Impressions et doutes sur l'utilisation de Java pour la première fois dans Android Studio
[Deep Learning from scratch] en Java 1. Pour le moment, différenciation et différenciation partielle
Apprentissage pour la première fois des expressions et opérateurs Java # 3
Résumé des points que les programmeurs Java trouvent glissants lorsqu'ils lisent la source Kotlin pour la première fois
[Rails] J'ai essayé d'utiliser la méthode button_to pour la première fois
Backpropagation Neural Network Java Code pour l'apprentissage du modèle de porte XOR
Modéliser Digimon avec DDD pour la première fois Partie 1
Spring Boot pour la première fois
Spring AOP pour la première fois
[First Java] Créez quelque chose qui fonctionne avec Intellij pour le moment
[Communication Socket (Java)] Impressions de la mise en œuvre de la communication Socket dans la pratique pour la première fois
Première programmation de ma vie Java 1st Hello World
L'histoire de l'utilisation intentionnelle de Try catch pour la première fois de ma vie
L'histoire d'un super débutant participant pour la première fois au concours AtCoder (AtCoder Beginner Contest 140)