您需要用Java做什么才能完全支持机器学习

大家好!

从关于ML / DL领域即将进行的创新的最新新闻:

Nishant Shakla,“ 使用Tensorflow进行机器学习 ”-一本布局的书,预计在一月份在商店中发售

Delip Rao,Brian McMahan,“ PyTorch中的自然语言处理 ”-合同已签订,我们计划在一月开始翻译。

在这种情况下,我们再次想回到一个痛苦的话题-对Java的ML / DL主题进行的深入研究。 由于这些Java解决方案和算法显然不成熟,我们曾经决定放弃Gibson和Patterson的DL4J书,而今天出版的Humphrey Sheil的文章暗示我们可能是正确的。 我们向您提供作者关于Java语言如何最终在机器学习中与Python竞争的想法

最近,我做了一个关于企业中机器和深度学习(ML / DL)的现状和未来的演讲 。 在大型企业中,与研究会议相比,应用的主题和问题更为重要-例如,我和我的团队如何开始使用ML,以及如何最好地将ML与我们运营的系统集成在一起。 然后开始了有关Java和机器学习的小组讨论。

机器学习部分实际上不存在Java语言。 几乎没有用Java编写的ML框架(有DL4J ,但是就我个人而言,我不知道有人会使用它, MXNet在Scala中有一个API,但不是用Java编写,并且该框架本身不是用Java编写的) 。 Tensorflow 在Java中的API并不完整 ,但是Java在企业开发中占有很大的份额,在过去的20年中,几乎在所有可能的主题领域中,对该语言进行了数万亿美元的投资:金融服务,电子交易,在线商店,电信-列表可以永远继续下去 在机器学习中,“首屈一指”是Python,而不是Java。 就个人而言,我真的很喜欢用Python和Java进行编程,但是Frank Greco提出了一个有趣的问题,促使我思考:
Java为什么要在ML中与Python竞争? 为什么不承担起认真考虑ML支持的任务呢?

重要吗?

让我们为这个话题辩护。 自1998年以来,Java语言就一直存在于英超联赛中,没有它,企业中就不会发生进化和革命事件。 我们谈论的是Web技术和移动技术,关于比较浏览器和本机解决方案,关于消息传递系统,i18n和l10n全球化支持,对您可以想象的任何企业信息的水平扩展和存储支持-从关系数据库到弹性搜索

这种无条件的支持提供了一种非常健康的文化,这种文化已经在Java命令中发展出来:“我们可以”,“袖手旁观并编写代码”。 优秀的Java开发人员团队无法补充或替代这种神奇的组件或API。

但是该原理在机器学习中不起作用。 Java命令在这里有两个选项:

  1. 在Python中进行重新训练。
  2. 使用第三方API将机器学习功能添加到您现有的企业系统中。

这些选项都不能称为真正无害。 首先,它需要大量时间和预先投资,加上持续的支持费用。 在第二种选择中,我们冒着变得变得依赖于供应商,失去供应商支持以及必须与第三方组件一起工作(同时为网络过渡付出代价),迁移到可能存在关键安全要求并必须与之共享信息的系统的风险。由组织外部的人。 在某些情况下,这是不可接受的。

在我看来,这种情况下最具破坏性的是文化恶化的可能性-团队无法更改他们不理解或无法维护的代码,因此责任模糊了,主要工作必须委派给其他人。 仅由Java开发人员组成的团队冒着错过下一波浪潮的风险,这波浪潮将泛滥到企业计算领域-机器学习浪潮。

因此,对机器学习的一流支持以该语言和Java平台出现是重要且合乎需要的。 否则,存在在未来5-10年内Java将被更好地支持ML的其他语言取代的风险。

为什么Python在ML中如此占主导地位?

首先,让我们讨论为什么Python成为机器学习和深度学习的领导者。

我怀疑这一切始于一个完全无害的功能-支持列表切片。 这种支持是可扩展的:使用该语法可以剪切实现__getitem____setitem__方法的所有Python类。 以下清单展示了Python的这一功能多么简单自然。

 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] (    ) 

当然,这还不是全部。 与“旧” Java代码相比,Python代码更加紧凑和简洁。 支持但不检查异常,并且开发人员可以轻松编写适合作为消耗品的Python脚本-尝试“其工作方式”而不会陷入Java世界观的“一切都是一类”。 Python很容易参与。

但是,在我看来,优势的最重要因素(这并不妨碍我认识到Python社区为维护Python 2.7和Python 3之间的联系而付出的辛勤工作)是它们设法创建了一个设计得更好,运行速度更快的库与数字-NumPy。 Numpy围绕ndarray构建 ,该对象是一个N维数组。 我引用文档:“ NumPy中的主要对象是齐次的多维数组。 这是所有相同类型的元素(通常是数字)的表,由一个正整数元组索引。 ” NumPy的所有工作都基于将数据写入ndarray以及对其进行的后续操作。 NumPy支持各种索引,广播,矢量化选项以提高速度,并且通常使开发人员可以轻松创建和操纵大型数值数组。

下面的清单在实践中显示了ndarray的索引编制和广播-这些是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]) 

使用大型多维数值数组,我们标志着机器学习(尤其是深度学习)编程的核心。 深度神经网络是在数字级别建模的节点和边缘的晶格。 训练网络或基于网络执行输出时的运行时操作需要快速矩阵乘法。

多亏了NumPy,已经完成了更多工作-scipypandas和许多其他基于NumPy的库。 领先的深度学习库(来自Google的Tensorflow,来自Facebook的PyTorch )正在认真地开发Python。 Tensorflow还有其他用于Go,Java和JavaScript的API,但它们不完整,被认为是不稳定的。 PyTorch最初是用Lua编写的,并且在2017年从坦率的利基语言转变为主要的ML Python生态系统时,其受欢迎程度真正飙升。

Python缺陷

Python不是理想的语言,也不是最流行的运行时CPython。 它具有全局解释器锁( GIL ),因此扩展并不容易。 此外,Python深度学习框架(如PyTorch和Tensorflow)仍将关键方法传递给不透明的实现。 例如,NVidia的cuDNN库对PyTorch RNN / LSTM实现的范围产生了重大影响。 RNN和LSTM(递归神经网络和长期短期记忆)是用于业务应用程序的非常重要的DL工具,尤其是因为它们专门研究(例如)连续长度可变系列的分类和预测。 网络导航,点击流分析,文本片段分析,用户事件等。

为了使Python公正起见,应注意,这种不透明性/限制几乎适用于ML / DL的任何框架,但用C或C ++编写的除外。 怎么了 因为为了使基本的高负载操作(例如矩阵乘法)获得最佳性能,开发人员请尽可能靠近金属。

Java在该领域需要竞争什么?

我假设Java平台需要增加三个主要功能。 如果实施,则用于机器学习的健康繁荣的生态系统将开始传播:

  1. 在语言的核心中添加本机索引/切片支持,以便您可以与Python竞争,因为它具有易用性和表现力。 此类功能可能应该在Java中围绕现有的有序集合List <E>接口构建。 对于此类支持,还必须认识到过载的必要性-必须满足第2点的要求。
  2. 创建一个张量实现-可能在java.math包中,但还要退出Collections API。 这组类和接口可以等效于ndarray并为索引提供了额外的支持,特别是NumPy中可用的三种索引类型 :对字段的访问,简单的切片以及编程所需的高级索引。
  3. 提供广播-任意(但兼容)尺寸的标量和张量。

如果可以在Java语言的核心和运行时中执行这三个任务,那么我们将为创建“ NumJava” (相当于NumPy)开辟道路。 巴拿马项目对提供对在CPU,GPU,TPU上执行的快速张量操作的矢量化低级访问也很有用,不仅使Java ML成为同类中最快的。

我一点也不说这些附加组件是微不足道的-远非如此,但是它们对整个Java平台的潜在好处是巨大的。

以下清单显示了我们的NumPy广播和索引示例在带有Tensor类的NumJava中的样子,并支持基于语言的切片语法以及当前对运算符重载的限制。

 //      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]) 

观点与行动号召

我们都知道,机器学习将改变商业世界,其时光至少会在它的时代-关系数据库,互联网和移动技术。 他周围有很多炒作,但出现了一些非常令人信服的文章和结论。 例如, 本文描述了将来系统可以使用机器学习在后台学习数据库服务器,Web服务器和应用程序服务器的最佳配置的未来。 您甚至不必自己在自己的系统中部署ML-当然,您的供应商之一将能够做到这一点。

基于本文提出的务实立场,您可以使用Java编写与机器学习和深度学习(在JRE上工作)的框架一样多的Web,长期存储或XML解析的现有框架-想象一下! 您可以想象Java框架支持卷积神经网络 (CNN)以实现最先进的计算机视觉实现,例如用于串行数据集的循环神经网络LSTM的实现(这对业务至关重要),具有最先进的ML功能,例如自动区分等。 然后,这些框架将有助于实施和推动下一代企业系统,这些系统可以使用所有相同的工具(IDE,测试框架,持续集成)与现有Java系统无缝集成。 最重要的是,它们将由我们的员工编写和支持。 如果您是Java迷-您不喜欢那个潜在客户吗?

Source: https://habr.com/ru/post/zh-CN429596/


All Articles