Elixirでディープラーニング①:革新的ライブラリ「Nx」の導入


Elixir Digitalization Implementors/fukuoka.ex/kokura.exのpiacereです
ご覧いただいて、ありがとうございます

今回は、Elixirの2021年を占うポジションであるニューラルネットワーク/ディープラーニング用ライブラリ「Nx」を導入してみます

Elixirによる機械学習/ディープラーニングの実現は、福岡Elixirコミュニティ「fukuoka.ex」を設立した半年後の2017年12月頃で、今回のNx以前から、自分達で独自実装を続けてきましたが、今回、「Nx」にその成果がフィードバックされ、Elixir本体実装にて約3年かかった野望を満たせたことになります

そんな革新的ライブラリ「Nx」が出たのが2021年2月18日 … つまり昨日なので、恐らく国内では一番乗りのコラムです


https://github.com/elixir-nx/nx/tree/main/nx

内容が、面白かったり、役に立ったら、「LGTM」よろしくお願いします

Advent Calendar、fukuoka.ex1位、Elixir2位達成ヽ(=´▽`=)ノ

fukuoka.ex Advent Calendar、Webテクノロジーカテゴリで堂々1位 … 各コラムぜひお読みください
https://qiita.com/advent-calendar/2020/fukuokaex

そして、プログラミング言語カテゴリは、1位がRust、2位がElixir、3位がGoとモダン言語揃い踏みでのトップ3、熱いネー
https://qiita.com/advent-calendar/2020/elixir

本コラムの検証環境

本コラムは、以下環境で検証しています(Windowsで実施していますが、Linuxやmacでも動作する想定です)

「Nx」をWindowsでインストールすると…

まず結論から言うと、Erlangの計算ライブラリ関数 :math.acosh が呼べずにビルドでコケます

Windows以外の環境ならコケずに上手くいきそうですが、未検証なので、検証していただける方、本コラムのWindows対策以外を参考にしながら、よろしくお願いします(私メンションを付けてくれたら嬉しい)

さて、そこまでの手順ですが、Elixir PJを作成します

> mix new nx_review
> cd nx_review

Nxをdepsに追加します

mix.exs
defmodule NxReview.MixProject do
  use Mix.Project

  defp deps do
    [
      {:nx, "~> 0.1.0-dev", github: "elixir-nx/nx", sparse: "nx"}
    ]
  end

ライブラリをインストールします

$ mix deps.get

ビルドすると、下記の通り、コケます

$ iex -S mix
==> file_system
Compiling 7 files (.ex)
Generated file_system app
…
==> nx
Compiling 17 files (.ex)

== Compilation error in file lib/nx.ex ==
** (UndefinedFunctionError) function :math.acosh/1 is undefined or private. Did you mean one of:

      * acosh/1

    (stdlib 3.8) :math.acosh(1)
    (stdlib 3.8) erl_eval.erl:680: :erl_eval.do_apply/6
    (elixir 1.11.2) lib/code.ex:706: Code.eval_quoted/3
    lib/nx.ex:3496: anonymous fn/2 in :elixir_compiler_11.__MODULE__/1
    (elixir 1.11.2) lib/enum.ex:2181: Enum."-reduce/3-lists^foldl/2-0-"/3
    lib/nx.ex:3488: (module)
could not compile dependency :nx, "mix compile" failed. You can recompile this dependency with "mix deps.compile nx", update it with "mix deps.update nx" or clean it with "mix deps.clean nx"

WSL2からビルドする

下記のコラムにある手順でリビルドし直す、という裏ワザを駆使します

WSL2でElixir本体のビルドとiexバージョン変更
https://qiita.com/piacerex/items/7abdfbffcc10bb7106d3

WSL2上のElixirがインストールできたら、改めて「Nx」のビルドを行います

ここでは、上記のElixir PJ構築を、c:\tmp配下に行った想定で、フォルダ移動を行い、ビルドします

$ cd /mnt/c/tmp/nx_review
$ iex -S mix
==> file_system
Compiling 7 files (.ex)
…
==> nx
Compiling 17 files (.ex)
Generated nx app
===> Compiling ranch
…

やった、上手く通りました

「Nx」をお試しする

早速、iexからNxを試してみましょう

iex> matrix = Nx.tensor( [ [ 0.123, 0.456 ], [ 0.789, 1.234 ] ] )
#Nx.Tensor<
  f64[2][2]
  [
    [0.123, 0.456],
    [0.789, 1.234]
  ]
>
iex> matrix
#Nx.Tensor<
  f64[2][2]
  [
    [0.123, 0.456],
    [0.789, 1.234]
  ]
>

Nxでは、このように、行列を定義できます

Nxには、微分の機能が入っているので、ディープラーニングの多クラス分類で頻出する「softmax」を作って、コレも試してみましょう

iex> Nx.divide( Nx.exp( matrix ), Nx.sum( Nx.exp( matrix ) ) )
#Nx.Tensor<
  f64[2][2]
  [
    [0.135520130365152, 0.18907054376721744],
    [0.26378125835705013, 0.4116280675105804]
  ]
>

うむ、イイ感じですねっ

ちなみに

Nxのhexdocは、未だアップされていないため、しばらくはソースコード中のdoctestを見て、アレコレ試してください(下記リンクです)

Nxソースコード
https://github.com/elixir-nx/nx/tree/main/nx/lib

最後に

ニューラルネットワーク/ディープラーニング用ライブラリ「Nx」を導入してみました

次回は、この「Nx」を使ったGPU駆動と、簡単なニューラルネットワークでも開発 GPU駆動の準備してみます

p.s.このコラムが、面白かったり、役に立ったら…

にて、どうぞ応援よろしくお願いします