LoginSignup
15
2

More than 1 year has passed since last update.

Elixir Nx 周辺の更新

Last updated at Posted at 2022-10-26

はじめに

過去の記事で何度か Elixir の Nx 周辺技術を紹介してきました

しかし、 Nx は現在進行形でどんどん進化しています

古いバージョンで動いていたコードが既に動かなくなっていたり、非推奨になっていたりします

というわけで、現状最新である以下のバージョンで各記事の処理を書き直してみました

  • Livebook: 0.7.1
  • Kino: 0.7.0
  • Nx: 0.4.0
  • Explorer: 0.3.1
  • Evision: 0.1.14

各変更箇所のエッセンスだけ抜き出して紹介します

実装したコードの全量はこちら

Evision のインストールオプション

インストールオプションのデフォルト値が変わっていました

  • 0.1.6 以前

    • 何も指定しなければコンパイルしてインストール、
    • 環境変数に EVISION_PREFER_PRECOMPILED=true を指定している場合はコンパイル済のものをインストール
  • 0.1.7 以降

    • 何も指定しなければコンパイル済のものをインストール
    • 環境変数に EVISION_PREFER_PRECOMPILED=false を指定している場合はコンパイルしてインストール

Evision マトリックスの画像表示

なんと言っても便利になったのは Evision のマトリックスがそのまま画像として表示できるようになったことです

また、 ! を付けないでマトリックスのみが返ってくるようになりました

  • ! の仕様変更
    • 旧: {:ok, mat} = Evision.imread(lenna) または mat = Evision.imread!(lenna)
    • 新: mat = Evision.imread(lenna)

Evision 画像表示 旧バージョン実装例

画像を読み込んだあと、バイナリに変換して Kino に渡す必要がありました

defmodule Helper do
  def show_image(mat) do
    Evision.imencode!(".png", mat)
    |> IO.iodata_to_binary()
    |> Kino.Image.new(:png)
  end
end

{:ok, mat} = Evision.imread(lenna)
Helper.show_image(mat)

old_evision.jpg

Evision 画像表示 新バージョン実装例

単純に画像ファイルを読み込むだけで画像が表示できるようになりました

実行結果に Raw Image Numeric のタブが表示され、 Image タブで画像を見ることができます

mat = Evision.imread(lenna)

evision_kino.gif

Evision の仕様変更

Nx のテンソルと Evision のマトリックス間での変換処理が変更されています

  • Nx -> Evision

    • 旧: Evision.Nx.to_mat()
    • 新: Evision.Mat.from_nx()
  • Evision -> Nx

    • 旧: Evision.Nx.to_nx()
    • 新: Evision.Mat.to_nx()

また、引数として List を渡していた箇所が Tuple に変更されています

  • 引数の仕様変更
    • 旧: Evision.warpAffine!(affine, [512, 512])
    • 新: Evision.warpAffine(affine, {512, 512})

Evision 画像加工 旧バージョン実装例

{:ok, affine} =
  [
    [1, 0, 100],
    [0, 1, 50]
  ]
  |> Nx.tensor(type: {:f, 32})
  |> Evision.Nx.to_mat()

lenna
|> Evision.imread!()
|> Evision.warpAffine!(affine, [512, 512])
|> Helper.show_image()

Evision 画像加工 新バージョン実装例

affine =
  [
    [1, 0, 100],
    [0, 1, 50]
  ]
  |> Nx.tensor(type: {:f, 32})
  |> Evision.Mat.from_nx()

lenna
|> Evision.imread()
|> Evision.warpAffine(affine, {512, 512})

Evision.Backend

実は Evision が Nx バックエンドとして動くようになっており、
Evision.Mat.to_nx() を使うと Evision バックエンドが使われます

ただし、一部の関数がサポートされていないため、以下のようなコードを実行するとエラーになります

エラーになるコード

predictions
|> Enum.map(fn prediction ->
  Evision.Mat.to_nx(prediction)
end)
|> Nx.concatenate()

エラーメッセージ

operation concatenate is not yet supported on Evision.Backend
Please use another backend like Nx.BinaryBackend or Torchx.Backend.

エラーを回避するためには、他のバックエンドを使用するよう明示しないといけません

エラー回避コード

predictions
|> Enum.map(fn prediction ->
  Evision.Mat.to_nx(prediction, Nx.BinaryBackend)
end)
|> Nx.concatenate()

Explorer の仕様変更

一部の関数が非推奨になり、代わりの関数を使うようになりました

  • フィルター

    • 旧: DataFrame.filter()
    • 新: DataFrame.filter_with()
  • 加工

    • 旧: DataFrame.mutate()
    • 新: DataFrame.mutate_with()

Explorer 旧バージョン実装例

mutate で「人口(千人)」列を float に cast しています
filter で「都道府県」列が「東京都」の行だけを抽出しています

population_df
|> DataFrame.mutate("人口(千人)": &Series.cast(&1["人口(千人)"], :float))
|> DataFrame.filter(&Series.equal(&1["都道府県"], "東京都"))

Explorer 新バージョン実装例

mutate_with で「人口(千人)」列を float に cast しています
filter_with で「都道府県」列が「東京都」の行だけを抽出しています

population_df
|> DataFrame.mutate_with(fn df ->
  [
    "人口(千人)": Series.cast(df["人口(千人)"], :float)
  ]
end)
|> DataFrame.filter_with(&Series.equal(&1["都道府県"], "東京都"))
|> DataFrame.select(["年齢層", "性別", "人口(千人)"])

mutate_with の問題

DataFrame.mutate_with では Series.transform を使用できません

エラーになるコード

trim_comma = fn input ->
  String.replace(input, ",", "")
end

population_df
|> DataFrame.mutate_with(fn df ->
  [
    "人口(千人)": Series.transform(df["人口(千人)"], trim_comma)
  ]
end)

エラーメッセージ

cannot perform operation on an Explorer.Backend.LazySeries

この問題は公式 Issue にもでているので、 Explorer 0.4 では何がしかの代替策が出てくるはずです

AxonOnnx について

AxonOnnx の 0.2.1 ではまだ Nx の 0.4 を使えません

おわりに

今が熱い 技術はどんどん進化するので、定期的にアップデートしていかないといけませんね

15
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
2