Ce que vous devez faire en Java pour prendre pleinement en charge l'apprentissage automatique

Bonjour collègues!

Des dernières nouvelles sur nos prochaines innovations dans le domaine du ML / DL:

Nishant Shakla, " Machine Learning with Tensorflow " - un livre en mise en page, attendu dans les magasins en janvier

Delip Rao, Brian McMahan, " Natural Language Processing in PyTorch " - le contrat est signé, nous prévoyons de commencer la traduction en janvier.

Dans ce contexte, nous voulions une fois de plus revenir sur un sujet douloureux - une mauvaise étude du thème ML / DL dans le langage Java. En raison de l'immaturité apparente de ces solutions et algorithmes Java, nous avons déjà décidé d'abandonner le livre DL4J de Gibson et Patterson, et l'article de Humphrey Sheil publié aujourd'hui suggère que nous avions probablement raison. Nous vous invitons à vous familiariser avec les réflexions de l'auteur sur la manière dont Java pourrait enfin rivaliser avec Python dans l'apprentissage automatique

Récemment, j'ai donné une conférence sur le présent et l'avenir de la machine et du deep learning (ML / DL) en entreprise. Dans le contexte d'une grande entreprise, plus de sujets et de problèmes appliqués sont pertinents que lors d'une conférence de recherche - par exemple, comment mon équipe et moi pouvons commencer à utiliser ML, et comment mieux intégrer ML avec les systèmes que nous avons en fonctionnement. Puis a commencé une table ronde sur Java et l'apprentissage automatique.

Le langage Java est pratiquement absent dans le segment d'apprentissage automatique. Il n'y a presque aucun framework ML qui serait écrit en Java (il y a DL4J , mais personnellement, je ne connais personne qui l'utiliserait, MXNet a une API en Scala, mais pas en Java, et ce framework lui-même n'est pas écrit en Java) . Tensorflow a une API incomplète en Java , cependant, Java a une part énorme dans le développement des entreprises, au cours des 20 dernières années, des milliards de dollars ont été investis dans ce langage dans presque tous les domaines imaginables: services financiers, transactions électroniques, magasins en ligne, télécommunications - liste peut durer éternellement. Dans l'apprentissage automatique, le «premier parmi ses pairs» est Python, pas Java. Personnellement, j'aime vraiment programmer en Python et en Java, mais Frank Greco a formulé une question intéressante qui m'a poussé à penser:
Pourquoi Java devrait-il rivaliser avec Python en ML? Pourquoi ne pas penser à vous apporter un soutien sérieux en matière de BC?

Est-ce important?

Justifions ce sujet. Depuis 1998, le langage Java est en Premier League, sans lui, il n'y a eu aucun événement évolutif et révolutionnaire dans l'entreprise. Nous parlons des technologies Web et mobiles, de la comparaison des navigateurs et des solutions natives, des systèmes de messagerie, de la prise en charge de la mondialisation i18n et l10n, de la mise à l'échelle horizontale et de la prise en charge du stockage pour toutes les informations d'entreprise que vous pouvez imaginer - des bases de données relationnelles aux Elasticsearch

Ce niveau de support inconditionnel fournit une culture très saine qui s'est développée dans les commandes Java: «nous pouvons», «retrousser vos manches et écrire du code». Il n'y a pas un tel composant magique ou API qui ne pourrait pas être complété ou remplacé par une bonne équipe de développeurs Java.

Mais ce principe ne fonctionne pas dans l'apprentissage automatique. Ici, les commandes Java ont deux options:

  1. Se recycler / se recycler en Python.
  2. Utilisez une API tierce pour ajouter des capacités d'apprentissage automatique à votre système d'entreprise existant.

Aucune de ces options ne peut être qualifiée de vraiment inoffensive. Le premier nécessite beaucoup de temps et d'investissement à l'avance, ainsi que des coûts de support continus. Dans la deuxième option, nous courons le risque de devenir dépendants du fournisseur, de perdre le support du fournisseur, ainsi que de devoir travailler avec des composants tiers (en payant le prix de la transition réseau en même temps), en migrant vers un système dans lequel il peut y avoir des exigences de sécurité critiques et nous devrons partager des informations avec par quelqu'un en dehors de votre organisation. Dans certaines situations, cela est inacceptable.

Le plus destructeur dans ce cas (à mon avis) est le potentiel de détérioration culturelle - les équipes ne peuvent pas changer le code qu'elles ne comprennent pas ou ne peuvent pas maintenir, donc les responsabilités sont floues et le travail principal doit être délégué à quelqu'un d'autre. Les équipes composées uniquement de développeurs Java courent le risque de passer à côté de la prochaine grande vague, qui envahira l'informatique d'entreprise - la vague du machine learning.

Par conséquent, il est important et souhaitable que le support de premier ordre pour l'apprentissage automatique apparaisse dans le langage et sur la plate-forme Java. Sinon, il y a un risque qu'au cours des 5 à 10 prochaines années, Java soit remplacé par d'autres langages où ML est mieux pris en charge.

Pourquoi Python est-il si dominant en ML?

Pour commencer, voyons pourquoi Python est devenu un leader de l'apprentissage automatique et du deep learning.

Je soupçonne que tout a commencé avec une fonctionnalité complètement innocente - la prise en charge du découpage de liste. Ce support est extensible: toute classe Python qui implémente les méthodes __getitem__ et __setitem__ peut être coupée en utilisant cette syntaxe. La liste suivante montre à quel point cette fonctionnalité de Python est simple et naturelle.

 a = [1, 2, 3, 4, 5, 6, 7, 8] print(a[1:4]) # [2, 3, 4] –      print(a[1:-1]) #  [2, 3, 4, 5, 6, 7] -  0-    print(a[4:]) # [5, 6, 7, 8] –      print(a[:4]) # [1, 2, 3, 4] –      print(a[:4:2]) # [1, 3] (    ) 

Bien sûr, ce n'est pas tout. Le code Python est beaucoup plus compact et concis que le "vieux" code Java. Les exceptions sont prises en charge, mais non vérifiées, et les développeurs peuvent facilement écrire des scripts Python qui conviennent comme élément consommable - essayez «comment cela fonctionne» sans se noyer dans la vision du monde Java «tout est une classe». Python est facile à impliquer.

Cependant, à mon avis, le facteur de supériorité le plus important (ce qui ne m'empêche pas de reconnaître le travail acharné de la communauté Python pour maintenir la connexion entre Python 2.7 et Python 3) est qu'ils ont réussi à créer une bibliothèque beaucoup mieux conçue et plus rapide pour les opérations. avec des nombres - NumPy. Numpy est construit autour de ndarray , un objet qui est un tableau à N dimensions. Je cite la documentation: « L'objet principal de NumPy est un tableau multidimensionnel homogène. Il s'agit d'un tableau d'éléments (généralement des nombres), tous du même type, indexés par un tuple d'entiers positifs. » Tout le travail NumPy est basé sur l'écriture de vos données dans ndarray et les opérations ultérieures sur celles-ci. NumPy prend en charge une variété d'options d'indexation, de diffusion et de vectorisation pour la vitesse et permet généralement aux développeurs de créer et de manipuler facilement de grands tableaux numériques.

La liste suivante montre en pratique l'indexation et la diffusion dans ndarray - ce sont des opérations clés en ML / DL.

 import numpy as np #    a = np.array([1.0, 2.0, 3.0]) b = 2.0 c = a * b print(c) #  [ 2. 4. 6.] -  b   /        c #2-d (   2)   NumPy –     - .e.  > 2 y = np.arange(35).reshape(5,7) print(y) # array([[ 0, 1, 2, 3, 4, 5, 6], # [ 7, 8, 9, 10, 11, 12, 13], # [14, 15, 16, 17, 18, 19, 20], # [21, 22, 23, 24, 25, 26, 27], # [28, 29, 30, 31, 32, 33, 34]]) print(y[0,0]) #     –    ,  0 print(y[4,]) #    4: array([28, 29, 30, 31, 32, 33, 34]) print(y[:,2]) #    2: array([ 2, 9, 16, 23, 30]) 

En travaillant avec de grands tableaux numériques multidimensionnels, nous marquons le cœur même de la programmation pour l'apprentissage automatique, et en particulier - l'apprentissage profond. Les réseaux de neurones profonds sont des réseaux de nœuds et de bords modélisés au niveau des nombres. Les opérations d'exécution lors de la formation d'un réseau ou de l'exécution de sorties basées sur celui-ci nécessitent une multiplication matricielle rapide.

Grâce à NumPy, beaucoup plus a été fait - scipy , pandas et bien d'autres bibliothèques basées sur NumPy. Les principales bibliothèques d'apprentissage en profondeur ( Tensorflow de Google, PyTorch de Facebook) développent sérieusement Python. Tensorflow possède d'autres API pour Go, Java et JavaScript, mais elles sont incomplètes et sont considérées comme instables. PyTorch a été écrit à l'origine en Lua, et a connu une véritable montée en popularité quand, en 2017, il est passé de ce langage de niche franchement à l'écosystème principal ML Python en 2017.

Défauts en python

Python n'est pas un langage idéal, ni le runtime le plus populaire, CPython. Il a un verrou d'interpréteur global ( GIL ), donc la mise à l'échelle n'est pas facile. De plus, les frameworks d'apprentissage profond Python tels que PyTorch et Tensorflow transmettent toujours des méthodes clés à des implémentations opaques. Par exemple, la bibliothèque cuDNN de NVidia a eu un impact majeur sur la portée de la mise en œuvre de PyTorch RNN / LSTM . RNN et LSTM (réseaux neuronaux récurrents et mémoire à court terme à long terme) sont des outils DL très importants pour les applications commerciales, en particulier parce qu'ils se spécialisent dans la classification et la prévision de séries successives de longueurs variables - par exemple. navigation sur le Web, analyse des clics, analyse des fragments de texte, événements utilisateur, etc.

Dans un souci d'impartialité vis-à-vis de Python, il convient de noter qu'une telle opacité / limitation s'applique à presque tous les frameworks pour ML / DL sauf ceux écrits en C ou C ++. Pourquoi? Parce que pour atteindre des performances maximales pour des opérations basiques et très chargées, comme la multiplication matricielle, les développeurs se rapprochent le plus possible du métal.

De quoi Java a-t-il besoin pour être compétitif dans ce domaine?

Je suppose que la plate-forme Java a besoin de trois ajouts majeurs. S'il est mis en œuvre, un écosystème sain et prospère d'apprentissage automatique commencera à se répandre:

  1. Ajoutez une prise en charge native de l'indexation / du découpage au cœur du langage afin de pouvoir rivaliser avec Python avec toute sa facilité d'utilisation et son expressivité. Il est possible que de telles capacités soient construites en Java autour d'une collection ordonnée existante, l'interface List <E> . Pour un tel soutien, il sera également nécessaire de reconnaître le besoin de surcharge - il est nécessaire de remplir le point # 2.
  2. Créez une implémentation du tenseur - probablement dans le package java.math , mais aussi avec une sortie vers l'API Collections. Cet ensemble de classes et d'interfaces pourrait fonctionner de manière équivalente à ndarray et fournir un support supplémentaire pour l'indexation, en particulier, les trois types d'indexation disponibles dans NumPy: accès aux champs, tranches simples et indexation avancée nécessaires à la programmation.
  3. Fournir la diffusion - scalaires et tenseurs de dimensions arbitraires (mais compatibles).

Si ces trois tâches pouvaient être exécutées au cœur du langage Java et du runtime, nous aurions ouvert la voie à la création de «NumJava» , équivalent à NumPy. Le projet Panama pourrait également être utile pour fournir un accès vectorisé de bas niveau à des opérations de tenseur rapides effectuées sur des CPU, GPU, TPU et pas seulement pour que Java ML puisse devenir le plus rapide de son genre.

Je ne dis pas du tout que ces modules complémentaires sont triviaux - non, loin de là, mais leurs avantages potentiels pour l'ensemble de la plate-forme Java sont énormes.

La liste suivante montre à quoi pourrait ressembler notre exemple de diffusion et d'indexation de NumPy dans NumJava avec la classe Tensor , avec la prise en charge de la syntaxe de découpage basée sur la langue et les restrictions actuelles sur la surcharge des opérateurs.

 //      Java    //  var-  Java 10   //  Java    ,      "a * b" //       ? var a = new Tensor([1.0, 2.0, 3.0]); var b = 2.0; var c = a.mult(b); /** *    , ,      Tensor  Java. */ import static java.math.Numeric.arange; //arange   ,  reshape    var y = arange(35).reshape(5,7); System.out.println(y); // tensor([[ 0, 1, 2, 3, 4, 5, 6], // [ 7, 8, 9, 10, 11, 12, 13], // [14, 15, 16, 17, 18, 19, 20], // [21, 22, 23, 24, 25, 26, 27], // [28, 29, 30, 31, 32, 33, 34]]) System.out.println(y[0,0]); //     –    ,  0 System.out.println(y[4,]); //    4-  (5-     0): tensor([28, 29, 30, 31, 32, 33, 34]) System.out.println(y[:,2]); //    2-  (3-     0): tensor([ 2, 9, 16, 23, 30]) 

Perspective et appel à l'action

Nous savons tous que l'apprentissage automatique transformera le monde des affaires au moins à son époque - les bases de données relationnelles, Internet et les technologies mobiles. Il y a beaucoup de battage médiatique autour de lui, mais certains articles et conclusions très convaincants apparaissent. Par exemple, cet article décrit l'avenir lorsque le système pourra apprendre les configurations optimales du serveur de base de données, du serveur Web et du serveur d'applications, en arrière-plan, à l'aide de l'apprentissage automatique. Vous n'avez même pas besoin de déployer ML vous-même dans votre propre système. Certainement, l'un de vos fournisseurs pourra le faire.

Sur la base des positions pragmatiques présentées dans cet article, vous pouvez écrire en Java pas moins de frameworks pour l'apprentissage automatique et le deep learning (travaillant sur JRE) que les frameworks existants pour le web, le stockage à long terme ou l'analyse XML - imaginez! Vous pouvez imaginer des cadres Java prenant en charge les réseaux de neurones convolutifs (CNN) pour les implémentations de vision par ordinateur de pointe, telles que les implémentations de LSTM de réseaux de neurones récurrents pour les ensembles de données série (qui sont d'une importance clé pour les entreprises), avec les fonctionnalités ML les plus avancées, telles que la différenciation automatique et plus encore. Ensuite, ces cadres aideraient à mettre en œuvre et à alimenter la prochaine génération de systèmes d'entreprise qui pourraient être intégrés de manière transparente aux systèmes Java existants, en utilisant les mêmes outils - IDE, cadres de test, intégration continue. Plus important encore, ils seront rédigés et soutenus par notre peuple. Si vous êtes un fan de Java, vous n'aimez pas cette perspective?

Source: https://habr.com/ru/post/fr429596/


All Articles