歩いたら休め

If the implementation is easy to explain, it may be a good idea.

【Rust】Rustの行列計算ライブラリについて調べる

この間までLotka-Volterraの方程式をRustで解いて勉強していましたが、そろそろPythonnumpy.ndarray のような行列計算を楽にする機構が欲しくなります。

もちろん、実際のソースコードで使われているライブラリ(crate)が良いです(メンテナンスされておらず、最新のコンパイラで動作しない場合もあるようなので…)。ということでまずはawesome-rustにある機械学習ライブラリの依存ライブラリをつてに探してみます。

github.com

AtheMathmo/rusty-machine

Rustの機械学習ライブラリだそうです。依存ライブラリはこんな感じ。

[dependencies]
num = { version = "0.1.41", default-features = false }
rand = "0.4.1"
rulinalg = { git = "https://github.com/AtheMathmo/rulinalg", rev = "1ed8b937" }

いきなり見つかりました。ちゃんと調べていないですが、逆行列(inverse)の計算も行えるようです。

github.com

A linear algebra library written in Rust https://crates.io/crates/rulinalg

avinashshenoy97/RusticSOM

こちらでは別のライブラリが使われています。

[dependencies]
rand = "0.4"
ndarray = "0.11"

github.com

こちらは追加のライブラリでシリアライゼーション( serde-1 )や並列化( rayon )、実験的のようですがblasの利用などできるみたいです。

autumnai/leaf

[dependencies]
collenchyma = { version = "0.0.8", default-features = false, features = ["native"] } # native feature to read/write data into tensors
collenchyma-blas = { version = "0.2.0", default-features = false, features = ["native"] } # only compiles with native feature
collenchyma-nn = { version = "0.3.2", default-features = false }

log = "0.3.2"
rand = "0.3.0"
num = "0.1"

capnp = "0.6.2"

timeit = "0.1.2"

clippy = { version = "0.0.41", optional = true }

[build-dependencies]
capnpc = "0.6.1"

こちらもまた別のライブラリに依存しています。

github.com

Provides a simple and unified API to run fast and highly parallel computations on different devices such as CPUs and GPUs, accross different computation languages such as OpenCL and CUDA and allows you to swap your backend on run-time.

OpenCLやCUDA等の計算言語をまたがって、統一的なAPIでCPUやGPU上で計算できるcrateのようです。ただ、以下の2017年の記事の時点で開発が止まっているようで、Githubのコミットログを見ても最近は開発されていないようです。

qiita.com

Leafフレームワークのコアの部分までRustで書かれていたのですが、当時はRustでCPU/GPUで高速に行列演算できるライブラリがなく、ディープラーニングのコアの部分(計算グラフの構築, 微分計算の記述, backward/update)自体よりもバックエンドの行列演算のライブラリ利用・開発に難儀していたようです。

そのような状況でTensorFlowのRustバインディングが公開され、Autumnの開発者がLeafの開発を停止したのですが、TensorFlowのRustバインディングは学習済みのモデルをloadしてinferenceに使用できるだけというもので、実際にはPythonなど他の言語でモデルの開発・学習・保存する必要があり、Leafの開発の中止は非常に残念でした。

tensorflow/rust

有名なニューラルネットワークのライブラリ tensorflow のRustバインディング

[dependencies]
libc = "0.2.43"
aligned_alloc = "0.1.3"
num-complex = { version = "0.2.1", default-features = false }
tensorflow-sys = { version = "0.15.0", path = "tensorflow-sys" }
byteorder = "1.2.7"
crc = "1.8.1"

どうやらlibc経由でC言語C++?)を呼び出していて、自前で行列計算は実装していないように見えます。

maciejkula/rustlearn

[dependencies]
rand = "0.3"
crossbeam = "0.2.9"
serde = "1.0"
serde_derive = "1.0"

どうやらこのライブラリ自体でdense / sparse matricesの実装がされているようです。

参考

どうやら、いまのところPythonにおける numpy のような、デファクトスタンダードにまでなっているライブラリは無いようですね。この辺りから、自分にとって使いやすいものがどれか試してみたいと思います。

また、Rust自体の進化が激しく、ライブラリの情報がすぐに古くなっていて最新情報が分かりづらいのは、言語初心者としてはけっこうつらいですね…。これは新興のプログラミング言語なのである程度は仕方ないかもしれませんが。