SpringBoot机器学习源码:使用DJL(深度Java库)和Spring Boot实现深度学习 | AWS开源博客


通过 Deep Java Library(DJL)和Spring Boot进行机器学习是一种简单而强大的方法,通过DJL提供的便捷抽象层将现有的微服务技术堆栈Spring Boot与MXNet,PyTorch和Tensorflow等最成熟的深度学习框架相结合。
在此博客文章中,我们将演示Java用户如何使用Spring Boot Starter for Deep Java Library(DJL)将ML集成到他们的Spring应用程序中。我们将回顾如何将这些框架付诸实践,并将ML功能集成到微服务中,展示围绕对象检测和分类的常见深度学习用例。

DJL概述
深度Java库(DJL)是用于深度学习的开源,高级别,与框架无关的Java API。它被设计为易于入门,并且对于Java开发人员来说易于使用。DJL提供了本机Java开发经验和功能,就像其他任何常规Java库一样。
DJL为使用最流行的AI / ML框架(例如Apache MXNetPyTorchTensorFlow)提供了便利的抽象层。但是,这不仅是现有库(其中一些提供Java API /绑定)之上的便利。使用DJL API,您将获得一个统一且一致的层,可以与所有这些框架进行交互,从而使您可以换出您选择的框架,而不会影响客户端代码。
这种独特的功能与相当丰富的模型Zoo仓库(具有预先训练的模型的仓库)相结合,可使ML工程师能够为手头任务找到最佳模型,而无需考虑基础模型的实现。
有关DJL的更多信息,请参考DJL GitHub存储库FAQ

DJL Spring Boot Starter
Spring Boot Starter是您项目中所需的所有Spring和相关技术的一站式商店,而不必搜寻示例代码和依赖描述符的复制粘贴负载。请参阅官方的Spring Boot文档以获取有关启动器的更多信息。
按照此定义,DJL Spring Boot Starter提供了在Spring中作为单个工件开始使用DJL所需的所有依赖项。除了依赖关系管理之外,启动程序还包括一个自动配置,该配置使得可以根据用户提供的配置文件自动关联依赖关系,并使它们在Spring Application上下文中可以作为bean使用。

依赖管理
DJL库是特定于平台的,但是它提供了基于目标操作系统自动查找正确依赖关系的方法。DJL也可以使用不同的基础引擎(例如MXNet,PyTorch或TensorFlow)进行配置;用户应在使用启动器之前做出选择。但是,即使做出选择,也可以通过修改Maven(或Gradle)依赖项来更改基础引擎以及目标操作系统体系结构,而不会影响代码。
起动器依赖性管理的组织方式是为用户提供最大的灵活性。
对于MXNet入门程序,支持以下操作系统分类器:osx-x86_64对于Mac OS X,linux-x86_64对于通用Linux,win-x86_64对于Windows发行版,以及auto用于自动检测目标操作系统。最后一个选项要求在运行时连接到外部工件存储库(例如,Maven Central),这对于具有严格安全约束和受限出口的系统可能是一个问题。
这是一个针对Linux架构的MXNet依赖关系的示例,它针对容器工作负载进行了优化:

<parent>
  <artifactId>spring-boot-starter-parent</artifactId>
  <groupId>org.springframework.boot</groupId>
  <version>2.2.6.RELEASE</version>
</parent>

<properties>
  <java.version>11</java.version> <!-- 11 is the lowest supported java version, however 12 and 13 should work fine -->
  <jna.version>5.3.0</jna.version> <!-- Required to override default JNA version for Spring Boot parent-->
</properties> 

<dependency>
  <groupId>ai.djl.spring</groupId>
  <artifactId>djl-spring-boot-starter-mxnet-linux-x86_64</artifactId>
  <version>${djl.starter.version}</version> <!-- e.g. 0.2 -->
</dependency>

Auto 依赖项,它将在运行时下载正确的工件:

<dependency>
  <groupId>ai.djl.spring</groupId>
  <artifactId>djl-spring-boot-starter-mxnet-auto</artifactId>
  <version>${djl.starter.version}</version> <!-- e.g. 0.2 -->
</dependency>

使用PyTorch作为底层引擎,依赖关系是:

<dependency>
  <groupId>ai.djl.spring</groupId>
  <artifactId>djl-spring-boot-starter-pytorch-auto</artifactId>
  <version>${djl.starter.version}</version> <!-- e.g. 0.2 and above -->
</dependency>

Spring自动配置
一旦在Spring Boot应用程序中正确配置了依赖项,下一步就是配置bean并正确地连接它们以进行注入。配置与DJL相关的bean并使其在Spring应用程序上下文中可用非常容易,但是它需要库的内部知识以及各个类的特殊性才能进行适当的作用域确定-有些bean是线程安全的,而另一些bean应该是线程安全的。范围取决于每个请求/线程。为了帮助进行此配置,DJL Spring Boot启动程序提供了自动配置
该组件与依赖项组件分开,并且需要显式依赖项。我们这样做的原因有两个:

  1. 一些开发人员更喜欢完全控制配置选项,并且可能不希望Spring“自动魔术”。在这种情况下,入门者将仅支持基本的依赖关系集,并允许开发人员显式地连接组件。
  2. 自动配置组件对于所有DJL配置都是通用的:无论基础目标操作系统或实际引擎如何,自动配置组件均保持不变。因此,使用相同的自动配置,开发人员可以将基础依赖项交换为一步操作,而不会对代码产生任何影响。

在Maven中声明对自动配置的依赖:

<dependency>
  <groupId>ai.djl.spring</groupId>
  <artifactId>djl-spring-boot-starter-autoconfigure</artifactId>
  <version>${djl.starter.version}</version>
</dependency>

声明依赖关系后,Spring Boot框架将自动找到配置并连接所需的组件。目前,为了进行推理,它将从模型动物园存储库中查找模型,并创建可随时用于进行推理的预测器。
用户应该提供标准的Spring配置(application.yml或application.properties)模型来使用受支持的应用程序类型之一:

 

QUESTION_ANSWER(NLP.QUESTION_ANSWER),
  TEXT_CLASSIFICATION(NLP.TEXT_CLASSIFICATION),
  IMAGE_CLASSIFICATION(CV.IMAGE_CLASSIFICATION),
  OBJECT_DETECTION(CV.OBJECT_DETECTION),
  ACTION_RECOGNITION(CV.ACTION_RECOGNITION),
  INSTANCE_SEGMENTATION(CV.INSTANCE_SEGMENTATION),
  POSE_ESTIMATION(CV.POSE_ESTIMATION),
  SEMANTIC_SEGMENTATION(CV.SEMANTIC_SEGMENTATION);

例如,为了在图像中运行对象检测,用户可以将应用程序类型设置为OBJECT_DETECTION。与DJL相关的配置应在djl根目录下命名,例如,djl.application-type=OBJECT_DETECTION如果application.properties使用的话。
这是yamlDJL自动配置的配置示例:

djl:
    # Define application type
    application-type: OBJECT_DETECTION
    # Define input data type, a model may accept multiple input data type
    input-class: java.awt.image.BufferedImage
    # Define output data type, a model may generate different out put
    output-class: ai.djl.modality.cv.output.DetectedObjects
    # Define filters that matches your application's need
    model-filter:
      size: 512
      backbone: mobilenet1.0
    # Override default pre-processing/post-processing behavior
    arguments:
      threshold: 0.5 # Display all results with probability of 0.5 and above

配置创建不必完全是手动的-DJL Spring Boot Starter借助Spring IDE插件(已在IntelliJ IDEA上进行了测试,但有望在具有STS和NetBeans IDE的Eclipse中运行)为大多数IDE提供了一个配置内容助手。对于IntelliJ,您可以使用Ctrl + Space来自动完成,并使用Ctrl + J来获取任何属性的快速文档。

简单的应用演练
以下是基于Simple Spring Boot应用程序的代码示例,该示例演示了使用DJL和MXNet进行单次对象检测。
每个Maven依赖项部分都设置了依赖项。配置设置与application.yml示例中的相同。该应用程序是具有单个类的常规控制台Spring Boot应用程序(请注意,不需要其他代码)。
注入预测器以进行对象检测

@Resource private Supplier<Predictor> predictorProvider;

建议在try-with-resources块中使用预测变量以确保每次使用后都将其关闭,因此注入预测变量的供应商以方便实例化。
Java中的对象检测

try (var predictor = predictorProvider.get()) {
    var results = predictor.predict(ImageIO.read(this.getClass()
          .getResourceAsStream("/puppy-in-white-and-red-polka.jpg")));

    for(var result : results.items()) {
        LOG.info(
"results: {}", result.toString());
    }
}

上面的代码将在提供的图像(预期在类路径中)上运行对象检测,并将结果以以下形式输出到记录器:

a.d.s.e.console.ConsoleApplication: results: class: "dog", probability: 0.90820, bounds: {x=0.487, y=0.057, width=0.425, height=0.484}

如何构建运行?

> git clone git@github.com:awslabs/djl-spring-boot-starter.git 
> cd djl-spring-boot-starter/djl-spring-boot-console-sample
> ../mvnw package
> ../mvnw spring-boot:run

或您可以使用以下java -jar命令直接运行它:

java -jar target/djl-spring-boot-console-sample-${version}.jar

更多点击标题进入