Sparkで動かす手順について、簡単に紹介したいと思います。DL4JがJava用といっても、Sparkのメインプログラミング言語がScalaなので、本記事ではJavaは使わずにScalaを使います。本記事で注目するDL4Jの特徴は、以下のようなものです。BigDLがあり、両者ともまだまだ開発途上という点も共通しています。異なる点としてはDL4JはJVM用として作られているのに対し、BigDLはIntelアーキテクチャ用に作られています。オープンソースのコミュニティとしてはDL4Jの方が活発なようです。Gitter)なんと言っても両者は同時に使うこともでき(同じjarにDL4J一式とBigDL一式を含めることができる)、その辺りの技術検証も興味深いのですが、今回は入門編ということでDL4Jのみを扱います。以上の前置きのもとで、本記事では以下のJavaサンプルプログラムを、1)Scala用に書き換え、2)Spark用に変更を加えるという手順について説明します。Toreeを使っています。どちらを用いる場合も、DL4Jのライブラリをspark-submitあるいはspark-shellのオプションで指定する必要があります。Sparkで動かせるようになることが伝わりますと幸いです。JavaプログラムをScalaプログラムに変更するJavaのコードをScalaのコードに変更するには、機械的に文法を変えるだけで済みます。28のように書き換えていきます。オリジナルコードでは出力先がログになっていますが、ログファイルの管理が面倒なため標準出力に変更します。全て変更すると、以下のようなコードになります。API仕様が最近(1.0.0-beta3)から変更になりました。null);}型引数を省略してScalaで実行すると次のような例外が出ますので、上記プログラムでは適当な型を指定するように修正してあります。scala.runtime.Nothing$実行例は以下です。secsScalaプログラムをSparkで動くように変更するScalaのプログラムに、いくつかの変更を加えてSparkで実行できるようにします。Sparkでプログラムを実行するためのSparkSessionインスタンスの準備Sparkプログラミングの決り文句的なものです。分散深層学習でよく使われるパラメータサーバの、DL4J独自実装のコードを加えます。Averagingを使っています。.build()RDDの準備Sparkを使わない処理ならばイテレータで順番にデータを読み出せば良いのですが、Sparkで処理するためにはorg.apache.spark.rdd.RDDやorg.apache.spark.sql.Datasetの形にしなければならないので、一度読み出してメモリに入れる処理を追加しています。}Spark用のニューラルネットワークモデルの準備ネットワークモデルを表現するorg.deeplearning4j.nn.multilayer.MultiLayerNetworkから、Spark用のラッパークラスであるorg.deeplearning4j.spark.impl.multilayer.SparkDl4jMultiLayerに変更しています。Spark用なので、Sparkの実行に必要なSparkContextやパラメータサーバを表す変数を引数として渡しています。numEpochs)関数があるのですが、org.deeplearning4j.spark.impl.multilayer.SparkDl4jMultiLayerには無いのでループする処理を追加しています。訓練用のデータは予めRDDを作成しています。}これらの変更を加えたコードは、以下のようになります。}}実行例は以下です。secsScalaのプログラムをSpark対応にするために5箇所ほどの変更点を上げましたが、決り文句的なものばかりで、簡単に分散処理を導入できることが分かります。ループ回数が同じ場合、Sparkで実行する方が処理時間が短くなりました。測定した精度(AccuracyからF1値まで全て)が落ちてしまっています。深層学習において分散処理を導入すると精度が落ちてしまうというのはよく知られており、DL4Jの実装ではどのような原因で精度が落ち、どう対処するのが良いかということは違う記事で触れたいと思います。(DL4J)のサンプルプログラムを例に、JavaのサンプルプログラムをSpark用に変更し、分散処理を導入する手順を簡単に説明しました。細かい手順や詳細な実行情報については省略しましたが、プログラムの変更は簡単であることがお分かり頂けたと思います。Javaは2019年12月現在バージョン1.0.0-beta5が公開されており、活発に開発が続いています。活発すぎて機能追加や仕様変更も多く追いつくのが大変ですが、今のうちから慣れておけばバージョン1.0.0が出る頃には使いこなせるようになるのではないかと思います。Javaの開発プロジェクトには、前処理用のDataVec、ハイパーパラメータチューニングのArbiter、強化学習用のRL4J、はてはScalaのためのND4S、PythonのためのJumpy/PyDL4J/PyDataVecなど多くのサブプロジェクトがあり、今後が楽しみです。