最近几年,深度学习的爆发带来了一个让很多人未曾预料到的结果:Python 这个曾经小众的语言突然间变得炙手可热了。无论资深开发者、计算机专业学生、编程入门新手,甚至地产大佬,都对这个语言表示出极大的热忱。
究其原因,在 Python 生态中我们可以容易地找到各类实用资源。例如用于数据计算的 NumPy、用于数据可视化的 Matplotlib,以及 MXNet、PyTorch、TensorFlow 等一众深度学习框架。相比之下,尽管 Java 仍是最流行的语言之一,拥有为数众多的开发者,尤其在企业市场拥有最广泛的应用基础,但实际上我们很难找到合适的,用于深度学习的 Java 工具或框架。现有为数不多的工具仍存在诸多不足,例如易用性不高,使用的仍是「低级」API,绑定于具体的深度学习框架,缺乏框架无关的特性等。
2020年2月的 TIOBE 程序语言指数(来源:https://www.tiobe.com/tiobe-i... )
2019年 StackOverflow 开发人员调查结果(来源https://insights.stackoverflo... )
那么深度学习领域就和 Java 这个前浪彻底无缘了?那也未必!
Deep Java Library(简称 DJL)是一个于2019年12月初的 AWS re:Invent 大会上首次发布的新项目。简单来说,DJL 是一个使用 Java API 简化模型训练、测试、部署和使用深度学习模型进行推理的开源库深度学习工具包,开源的许可协议是 Apache-2.0。
对于 Java 开发者而言,可以在 Java 中开发及应用原生的机器学习和深度学习模型,同时简化了深度学习开发的难度。通过 DJL 提供的直观、高级的 API,Java 开发人员可以训练自己的模型,或利用数据科学家用 Python 预先训练好的模型来进行推理。如果您恰好是对学习深度学习感兴趣的 Java 开发者,那么 DJL 无疑将是开始深度学习应用的一个最好的起点。
DJL 是在现有深度学习框架的基础上使用原生 Java 概念构建的的开发库。它为开发者提供了深度学习的最新创新和使用前沿硬件的能力,例如GPU、MKL 等。简单的 API 抽象并简化了开发深度学习模型所涉及的复杂性,使得这个新的框架更易于学习和应用。有了 Model-zoo 中绑定的预训练模型集,开发者可以立即开始将深度学习的 SOTA 成果集成到 Java 应用当中。
总所周知,Java 的设计思想有这样的一句:“Write once, run anywhere”(WORE)。同样,DJL 的设计目标也设定为不依赖于具体的引擎和深度学习框架,可以随时切换框架。原则上,开发人员可以基于 DJL 编写能在任何引擎上运行的代码。DJL 目前提供了 Apache MXNet 的实现,预期 TensorFlow 与 PyTorch 的支持也将在不久后发布。从目前的实现来看,DJL 使用了 JNA(Java Native Access)来实现 Apache MXNet 操作的调用。
DJL 提供了对于基础环境的管理。为了保证最佳的性能,提供了基于硬件配置的自动 CPU/GPU 选择。DJL 提供了对多 GPU 的支持,可以自动检测是否有可用的 GPU。如果 GPU 可用,它将默认运行在一个 GPU 上,除非程序中制定使用的 GPU 数量。
在模型的训练期间,如果希望在多个 GPU 上进行训练,或希望限制使用 GPU 的数量(对于较小的数据集,可能希望限制 GPU 的数量),则必须通过设置设备来配置 TrainingConfig。例如,如果有8个可用 GPU,并且希望训练器在5个 GPU 上进行训练,可进行如下配置:
int maxNumberOfGpus = 5; TrainingConfig config = new DefaultTrainingConfig(initializer, loss) .setOptimizer(optimizer) .addEvaluator(accuracy) .setBatchSize(batchSize) // Set the devices to run on multi-GPU .setDevices(Device.getDevices(numberOfGpus));
对于 Java 开发者而言,DJL 的 API 抽象了用于开发模型的常用函数,使得 Java 开发人员能够利用现有的知识简化向机器学习以及深度学习的转换。相信这一点应该是 Java 开发者最希望看到的。关于 DJL 的抽象架构我们可以通过下图进行理解:
来源:https://miro.medium.com/max/3472/1*ju6OsZqhpAHTnhFHDp4DXQ.png
计算机视觉(CV)是目前深度学习发展最为成熟的领域。其中,目标检测是一种与计算机视觉和图像处理相关的计算机技术,用于在数字图像和视频中检测某一类语义对象(如人、建筑物或汽车)的实例。目标检测在计算机视觉的许多领域都有应用,包括图像检索和视频监控。
接下来,我们将展示一个目标检测的例子,体验一下 DJL 的实际表现。该模型使用来自 DJL 的 Model-zoo 的预先训练 Single Shot Detector(SSD)模型,可帮助我们从图像中识别西雅图海鹰队(一支职业美式橄榄球球队)的队员。
要将DJL用于应用程序项目,可以使用 IntelliJ IDEA 创建 gradle 项目,并将以下内容添加到 build.gradle 配置中。
源代码:https://gist.github.com/vrake...
接下来我们就用这张含橄榄球员的图片进行处理。
来源:Offered under Apache-2.0 license on Gluon-CV
针对这张图片使用下面的这段代码来进行推理。这段代码从 Model-zoo 加载一个 SSD 模型,然后从模型中创建一个预测器,并使用 predict 函数来识别图像中的对象。然后通过一个 helper utility 函数在检测到的对象周围画上框线。
源代码:https://gist.github.com/vrakesh/0faacec9e9f8d88c4cb96c8ae812493a#file-simplessdinference-java
这段代码标识出图像中的三个橄榄球运动员,并将结果保存为工作目录下的图片文件 ssd.png。
代码本身并不长,理解起来也比较容易。我们可以很容易地进行调整,可以测试来自 Model-zoo 的其他模型或针对自己的需要作出改变。但是 DJL 带来的但乐趣远不止如此。我们还可以使用问题问答模型来训练自己的智能化应用,或者使用图像分类模型来识别杂货架上的商品等等。在 DJL 的 GitHub 上有更多有意思的例子。
最后,如果本文能让你对 DJL 产生兴趣,也别忘了 DJL 的三个最有趣的特性:
感兴趣的童鞋可以点击这里进一步了解 DJL。另外在实际体验时需要注意:DJL 需要 JDK 8(或更高版本)。建议使用 JDK8,因为 JDK 11 +存在一些已知的问题,包括 SpotBugs 与 JDK 11 +不兼容等。如果使用 JDK 11+,SpotBugs 将无法执行。另外还请注意,目前 DJL 尚不支持分布式模型训练。