总览
这是Spring Boot上的另一篇文章 ,该文章将展示如何使用Deep Java Library (DJL)构建示例Web应用程序, Deep Java Library (DJL)是Java的开源深度学习库,用于诊断X射线图像上的COVID-19。
该示例应用程序是DJL的类似COVID-19 示例的基于Spring Boot的版本,它具有一个使用Twitter Bootstrap和JQuery构建的简单静态HTML页面,用户可以将图像URL提交到REST api,DJL库将在其中下载图像和预测是否是被COVID-19感染的肺部的X射线图像。
到源代码的链接包含在这篇文章的结尾。
免责声明 :这只是基于https://github.com/ieee8023/covid-chestxray-dataset上的数据集的演示应用程序,不应将其用于实际医学诊断。
深度Java库
如前所述, DJL是基于Java的库,支持多个
深度学习框架,例如Apache MxNet , PyTorch和Tensorflow 。 由于大多数深度学习引擎都是使用Python而不是Java构建的,因此DJL内置了引擎适配器来访问这些引擎的本机共享库。
DJL以一种优雅的方式做到了这一点,使得根据用例从一个框架切换到另一个框架变得非常简单。
依存关系
该应用程序需要Spring Boot Web Starter:
<code> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency></code>
还有commons-io库,用于一些基本的I / O操作:
<code> <dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency></code>
Lombok库也是如此,因为我懒得编写getter和setter方法:
<code> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency></code>
最后是此示例应用程序的DJL依赖项:
<code> <dependency>
<groupId>ai.djl</groupId>
<artifactId>api</artifactId>
<version>${ai.djl.version}</version>
</dependency>
<dependency>
<groupId>ai.djl.tensorflow</groupId>
<artifactId>tensorflow-api</artifactId>
<version>${ai.djl.version}</version>
</dependency>
<dependency>
<groupId>ai.djl.tensorflow</groupId>
<artifactId>tensorflow-engine</artifactId>
<version>${ai.djl.version}</version>
</dependency>
<dependency>
<groupId>ai.djl.tensorflow</groupId>
<artifactId>tensorflow-native-auto</artifactId>
<version>${tensorflow-native-auto.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version> <!-- overrides default spring boot version to comply with DJL -->
</dependency></code>
这是DJL依赖版本所需的Maven属性列表:
<code> <properties>
<java.version>1.8</java.version>
<ai.djl.version>0.5.0</ai.djl.version>
<jna.version>5.3.0</jna.version>
<tensorflow-native-auto.version>2.1.0</tensorflow-native-auto.version>
</properties></code>
XRayApplication类
此类的main()
方法将启动Spring Boot应用程序,并且看起来像大多数其他Application类文件:
<code>@SpringBootApplication
public class XRayApplication {public static void main(String[] args) {
SpringApplication.run(XRayApplication.class, args);
}}</code>
组态
为了配置DJL库,让我们创建一个带有@Configuration
批注的DjlConfig
类。
此类将定义一个ZooModel
Spring Bean,它将帮助预测所提交的图像URL是否属于受COVID-19感染的肺:
<code> @Bean
public ZooModel xrayModel() throws Exception {
Criteria<BufferedImage, Classifications> criteria =
Criteria.builder()
.setTypes(BufferedImage.class, Classifications.class)
.optTranslator(new XrayTranslator())
.build();return ModelZoo.loadModel(criteria);
}</code>
这段代码说明的是,我们创建了一个带BufferedImage
输入和Classifications
(稍后会详细介绍)输出类型的XrayTranslator
对象,并且它使用XrayTranslator
对象将输入图像转换为深度学习模型正常运行所需的格式。
下面是该代码XrayTranslator
这是内一个内部类DjlConfig
:
Covid19服务
<code> public static final class XrayTranslator implements Translator<BufferedImage, Classifications> {private static final List<String> CLASSES = Arrays.asList("covid-19", "normal");@Override
public NDList processInput(TranslatorContext ctx, BufferedImage input) {
NDArray array =
BufferedImageUtils.toNDArray(
ctx.getNDManager(), input, NDImageUtils.Flag.COLOR);
array = NDImageUtils.resize(array, 224).div(255.0f);
return new NDList(array);
}@Override
public Classifications processOutput(TranslatorContext ctx, NDList list) {
NDArray probabilities = list.singletonOrThrow();
return new Classifications(CLASSES, probabilities);
}
}
</code>
Covid19服务
Covid19Service
类将处理诊断X射线图像的业务逻辑,并且您会发现,令人惊讶的是,实际上只有几行代码:
<code>@Service
public class Covid19Service {@Autowired
private ZooModel xrayModel;public String diagnose(String imageUrl) {
try (Predictor<BufferedImage, Classifications> predictor = xrayModel.newPredictor()) {
Classifications result = predictor.predict(BufferedImageUtils.fromUrl(imageUrl));
return "Diagnose: "
+ result.best().getClassName()
+ " , probability: "
+ result.best().getProbability();
} catch (Exception e) {
throw new RuntimeException("Failed to diagnose", e);
}
}
}</code>
在DjlConfig
类中创建的ZooModel
bean是自动装配的,并在具有imageUrl
参数的imageUrl
diagnose()
方法中使用。
在该方法中,我们使用try-resource
块创建Predictor
对象(因为在执行后需要关闭预测变量),并使用它通过预先训练的Tensorflow模型运行BufferedImage(
使用imageUrl
参数创建)。
有关该模型的更多详细信息,请访问:https://www.pyimagesearch.com/2020/03/16/detecting-covid-19-in-x-ray-images-with-keras-tensorflow-and-deep-learning/ 。
一旦运行diagnostic diagnose()
方法, Classifications
结果对象将显示X射线图像上的肺部是否被COVID-19感染,以及感染的可能性是多少。
Covid19控制器
控制器类定义了REST API来诊断X射线图像,这些图像将由我们的简单前端应用程序消耗:
<code>@RestController
@RequestMapping(value = "/api/v1", produces = MediaType.APPLICATION_JSON_VALUE)
public class Covid19Controller {
private final Covid19Service covid19Service;public Covid19Controller(Covid19Service covid19Service) {
this.covid19Service = covid19Service;
}@GetMapping("/covid19/diagnose")
public ResponseEntity diagnose(@RequestParam String imageUrl) {
String answer = covid19Service.diagnose(imageUrl);
return ResponseEntity.ok(Collections.singletonMap("result", answer));
}
}</code>
@RestController
注释告诉Spring在我们的MVC设计中,这是一个定义REST API的C ontroller bean。
@RequestMapping
注释告诉Spring此类中所有REST /api/v1
路径都应以/api/v1
作为前缀,并且所有REST /api/v1
将返回application\json
响应。
我们之前讨论的Covid19Service
在构造函数中自动装配,随后由REST diagnose
api在GET /api/v1/covid19/diagnose
路径中使用。
诊断api使用imageUrl
请求参数,并返回带有结果字符串表示形式的JSON文档。
前端
Spring Boot应用程序具有一个简单的静态index.html
文件作为诊断REST api的前端客户端,它使用Twitter Bootstrap进行响应式设计,并使用JQuery进行REST api调用:
<code><head>
<link rel="stylesheet" href="/css/bootstrap.min.css"/>
<script src="/js/jquery.min.js"></script>
</head></code>
该文件具有HTML表单,可以捕获用户的X射线图像URL:
<code> <form id="diagnoseForm" class="mb-4">
<div class="input-group">
<input type="url" id="imageUrl" class="form-control" required
placeholder="Enter a image url"
aria-label="Image URL">
<div class="input-group-append">
<button class="btn btn-outline-primary">Submit</button>
</div>
</div>
</form></code>
提交表单后,REST API可能需要一段时间才能做出响应。 同时,页面将显示微调器,一旦收到响应,文本将显示在diagnose
div中:
<code> <div class="row ml-1">
<div id="spinnerDiagnose" class="text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
<div id="diagnose"></div>
</div></code>
参见下面的javascript代码:
<code>$( "#diagnoseForm" ).submit(function( event ) {
const imageUrl = $('#imageUrl').val();
$('#spinnerDiagnose').addClass('spinner-border');
$('#diagnose').html('');$.ajax('/api/v1/covid19/diagnose?imageUrl='+imageUrl)
.done(data => {
$('#spinnerDiagnose').removeClass('spinner-border');
$('#diagnose').html(data.result);
})
.fail(err => {
$('#spinnerDiagnose').removeClass('spinner-border');
$('#diagnose').html('Failed to get answer');
});
event.preventDefault();
});</code>
触发表单的imageUrl
事件时,代码获取imageUrl
值,显示微调器,从先前的运行中清除diagnose
div的内容,并使用imageUrl
调用诊断REST api。
如果响应成功,代码将隐藏微调框并在diagnose
div中显示结果。
发生错误时,代码还将隐藏微调框并显示一般错误消息。
运行应用
该应用需要先下载Tensorflow才能运行。
在项目的根文件夹中运行以下命令:
<code>mkdir models
cd models
curl https://djl-tensorflow-javacpp.s3.amazonaws.com/tensorflow-models/covid-19/saved_model.zip | jar xv
cd ..
./mvnw spring-boot:run -Dai.djl.repository.zoo.location=models/saved_model</code>
然后访问http:// localhost:8080 / index.html进行X射线图像URL的诊断。 要使用的示例图像:
- COVID-19感染的肺
- 正常肺
总览
在本教程中,我们回顾了如何使用Spring Boot,DJL和Tensorflow创建示例深度学习Java应用程序。
该帖子的源代码位于https://github.com/davidkiss/djl-spring-boot-xray 。
翻译自: https://www.javacodegeeks.com/2020/05/deep-learning-with-spring-boot-and-djl.html