AWSからリリースされた、JavaでDeepLearningが扱えるライブラリDeep Java Library（DJL）に触れてみる

# 概要
2019/12/03AWSよりJava で機械学習モデルを開発およびデプロイするDeep Java Libraryが発表されました。

<a href="https://djl.ai/">
<img width="755" alt="DJL - Deep Java Library" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/7d5b51b6-8631-0555-8f6a-9c91ef802eee.png">
</a>

ほんの少しですが、触ってみましたので紹介します。
なお、事前知識としては、Javaは普段使っているが、ML/DLの知識は自身ほぼゼロです。

 
<a href="https://aws.amazon.com/jp/about-aws/whats-new/2019/12/introducing-deep-java-library-develop-and-deploy-machine-learning-models-in-java/">
<img width="1242" alt="Deep Java Library の発表: Java で機械学習モデルを開発およびデプロイする" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/0277bc2c-9ee5-ca14-0795-4aeef260ccf2.png">
</a>

ここでは、

> Java で深層学習モデルを開発するためのオープンソースライブラリである DJL を発表します。DJL には、深層学習モデルのトレーニング、テスト、デプロイを行うためのユーザーに使いやすい API が用意されています。深層学習に興味のある Java ユーザーであれば、DJL は素晴らしい出発点になります。深層学習モデルで作業する Java 開発者の場合、DJL を使えば簡単に予測をトレーニングして実行することができます。

とありましたので、期待して触ってみます。

なお、公式なページは以下ですが、Amazon/AWS色はあまり見えません。
https://djl.ai/

# Try

何はともあれ、チュートリアル通り動かしてみます。

https://github.com/awslabs/djl.git

からcloneし、example以下を動かすのが良さそうです。

```
# 適当なフォルダで実行
 git clone https://github.com/awslabs/djl/
```

cloneし終えたら、exampleフォルダに移動し、そこのREADME.mdを見てみます。

以下のように、いろいろな種類の例があるので最初に一つ目の奴をやってみます。

<img width="652" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/5b2bb9c8-e941-1c58-faa6-582e01b90680.png">

Single-shot Object Detection exampleをやっていきます。

まず初めにセットアップせよと言われますが、Java11+と環境変数、オプションでIntelliJでの使い方ぐらいですので、普段Javaやっている人はあまり読まずに突き進んでも良さそうです。

この例では、予め用意されたZooModelというものを使い、それに対して画像をぶつけてそこに何の動物が映っているのかを表現してくれ、その認識した箇所を四角で囲った画像も作る、という例となります。

いきなりですが、以下で動作確認することが出来ます。
(object_detection.mdより引用）

> cd examples
> ./gradlew run -Dmain=ai.djl.examples.inference.ObjectDetection

実行結果として、以下が表示されます。
初回はライブラリのダウンロードなどが走るため、時間がかかりますが、2回目以降は１０秒程度で終わります。

```bash
$ ./gradlew run -Dmain=ai.djl.examples.inference.ObjectDetection

> Task :run
Loading:     100% |████████████████████████████████████████|
[22:02:10] src/nnvm/legacy_json_util.cc:209: Loading symbol saved by previous version v1.5.0. Attempting to upgrade...
[22:02:10] src/nnvm/legacy_json_util.cc:217: Symbol successfully upgraded!
[INFO ] - Detected objects image has been saved in: build/output/detected-dog_bike_car.png
[INFO ] - [
        class: "car", probability: 0.99991, bounds: [x=0.611, y=0.137, width=0.293, height=0.160]
        class: "bicycle", probability: 0.95385, bounds: [x=0.162, y=0.207, width=0.594, height=0.588]
        class: "dog", probability: 0.93752, bounds: [x=0.168, y=0.350, width=0.274, height=0.593]
]

BUILD SUCCESSFUL in 11s
3 actionable tasks: 1 executed, 2 up-to-date
```
車と自転車と犬が写っているという結果が出てます。

後付けになりますが、[ai.djl.examples.inference.ObjectDetection](https://github.com/awslabs/djl/blob/master/examples/src/main/java/ai/djl/examples/inference/ObjectDetection.java)クラスを見ると

> Path imageFile = Paths.get("src/test/resources/dog_bike_car.jpg");

とあるので、この画像がInputであることがわかります。
<img width="701" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/64f8ece8-81bf-db50-6106-4b5fa5c3beae.png">

実行後、出力された画像は　``build/output/detected-dog_bike_car.png``　にあります。（同クラスに実装されています）

<img width="705" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/3cdd4531-fb4a-f0c3-055f-501204fc306a.png">

ちゃんと出来てますね。

Inputの画像を差し替えることで、別の画像でもObject Detectionできそうです。

改めて
[ai.djl.examples.inference.ObjectDetection](https://github.com/awslabs/djl/blob/master/examples/src/main/java/ai/djl/examples/inference/ObjectDetection.java)クラスを見ると、Javaしかわからない自分にでもなんとなくやっていることがわかります。ロガーの設定などが馴染みがあって親近感湧きますね。

全部でおおまかな流れは以下のように読み取りました。

- ロガーの設定
- Inputとなる画像の読み込み
- モデルに渡す各種パラメータの設定
- MxModelZoo([MxNet](https://aws.amazon.com/jp/mxnet/)ベースのモデル)という予め用意されたモデルへパラメータ、画像を渡す
- 予測の実施
- 予測結果を画像へ反映
- 標準出力にも予測結果を出力

といった感じです。パラメータのところはそれぞれどんな意味があるのか詳細確認が必要ですが、用意されたモデルを使ってObject Detectionするというのはハードルが低いなと正直思いました。

# 依存ライブラリの確認

exampleを取り込んだプロジェクトの依存ライブラリは以下のような感じでした。
Spring系との重複とかはなさそうなので、コンフリクト起きずに併用できそうですね。
<img width="522" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/21285eb3-b94c-f5f6-6e0b-0f88be80f702.png">


# まとめ
とりあえずDJLを使って、一つの例だけやってみました。

以前、DeepLearning4Jを触ってみようかと思ったのですが、
環境構築周りで躓き、棚上げしていたのですが、今回はすんなりでした。

ML/DLのシステムを全てJavaで！という感覚までは辿り着けませんでしたが、一般的なWebシステムの一機能だけML/DLを使うという際には、これをスモールスタートで使ってみるというのは良いかもしれないなと思いました。