ファイルフォーマットコンバーター

概要

blockdiag NNabla Use NNabla as Runtime Other (Caffe2 etc.) ONNX ONNX NNP NNB C Source code Frozen graph(.pb) File Format Converter File Format Converter NNP Tensorflow (.pb,ckpt) Other runtime NNabla C Runtime Implement to product Tensorflow

ファイルフォーマットコンバーターを使うと、ONNX ファイルフォーマット、および NNabla C Runtime で Neural Network Libraries (または Console) ワークフローを実現できます。

ファイルフォーマットコンバーターには次のような機能があります。

  • NNP のバリエーションを有効な NNP へ変換する
  • ONNX から NNP へ変換する
  • NNP から ONNX へ変換する
  • NNP から NNB へ変換する (NNabla C Runtime のバイナリー形式)
  • NNP から Tensorflow frozen graph へ変換する
  • Tensorflow checkpoint または frozen graph から NPP へ変換する
  • 試用段階: NNP から NNabla C Runtime の C ソースコードへ変換する

重要なお知らせ: 本ファイルフォーマットコンバーターには、いくつかの既知の問題が残っています。

  • サポートする ONNX オペレーターは制限されています。詳細は Function-Level Support Status をご覧ください。
  • サポートする Tensorflow operator は制限されています。詳細は Function-Level Support Status をご覧ください
  • NNP から C ソースコードへの変換はまだ試用段階です。動作しますが、十分にテストされていません。

アーキテクチャー

blockdiag <<file>> INPUT <<file>> OUTPUT proto Process (Split, Expand, etc.) import export

本ファイルフォーマットコンバーターは、中間形式として Neural Network Libraries 内に定義された protobuf を使います。

汎用のファイルフォーマットコンバーターではありませんが、Neural Network Libraries では指定されたコンバーターです。

本コンバーターは、ONNX ファイルに対する入力および出力を指定可能ですが、ONNX ファイルに Neural Network Libraries がサポートしない機能を含んでいる場合、変換中にエラーが発生する可能性があります。

また本コンバーターは、中間プロセス機能も提供します。詳細は、 プロセス をご覧ください。

変換

サポートするフォーマット

NNP

NNP は NNabla のファイルフォーマットです。

NNP フォーマットは データフォーマット に記述されます。

本ファイルフォーマットコンバーターでは、いくつかの NNP バリエーションでしか動作しません。

  • NNP 標準フォーマット (.nnp)
  • NNP ファイルの内容 (.nntxt, .prototxt, .h5, .protobuf)

ONNX

制限事項

  • 学習はサポートしません。
  • オペレーターセット 6 と 9 のみサポートします。
  • すべての機能をサポートしているわけではありません。詳細は Function-Level Support Status をご覧ください。
  • 限られた Neural Network Console のプロジェクトのみサポートします。詳細は Model Support Status をご覧ください。
  • onnx package をご自身の手でインストールしなければならない場合があります。例えば、 pip install onnx コマンドでインストールできます。システム全体にインストールする場合は、 sudo -HE pip install onnx コマンドでインストールできます。

NNB

NNB は NNabla C Runtime のコンパクトなバイナリー形式です。 nnabla-c-runtime 用に設計されています。

C ソースコード

ファイルフォーマットコンバーターは、 nnabla-c-runtime の C ソースコード出力をサポートします。

Tensorflow

tensorflow import と export は onnx を通じて部分的にサポートされます。

importer に関しては、3 つのフォーマットがサポートされる場合があります:
  • .pb, tensorflow frozen graph フォーマット
  • .ckpt, tensorflow check point フォーマット version 1
  • .ckpt.*, tensorflow check point フォーマット version 2

exporter に関して、いくつかの Neural Network Console project をサポートします。詳細は Model Support Status をご覧ください。コンバーターの出力は tensorflow frozen graph フォーマットです (例: *.pb)。

本コンバーターを使用する前に、tnsorflow と関連する package がインストールされていることを確認してください:

$ pip install -U tensorflow==1.5 onnx==1.4.1 onnx_tf
$ pip install https://github.com/onnx/tensorflow-onnx.git

プロセス

繰り返しの拡張と循環

Neural Network Console は LoopControl 擬似関数である RepeatStart, RepeatEnd, RecurrentInput, RecurrentOutput または Delay をサポートしています。

現在、Neural Network Library ではこれらの関数を直接的にはサポートしていません。

ファイルフォーマットコンバーターは、ネットワークを拡張し、デフォルトでこれらの擬似関数を削除します。

これらの関数を保持したい場合、ファイル変換時にコマンドラインオプション --nnp-no-expand-network を指定してください。

ネットワークを分割する

--split オプションを使ってネットワークを分割できます。

この機能を使用する場合、 分割ネットワーク をご覧ください。

使い方

NNP 操作

NNP から NNP への変換

NNP から NNP への変換が必要な場合があります。

たいていの場合、繰り返しの拡張、あるいは循環ネットワークは Neural Network Console ではサポートしていますが、C++ API ではサポートしていません。

$ nnabla_cli convert input.nnp output.nnp

console 出力から単一の NNP ファイルへ変換する

Neural Network Console の現在のバージョンは .nntxt と .h5 を学習結果として出力します。

続いて、分離したファイルを単一の NNP に変換し、パラメータを protobuf 形式で格納する必要があります。

$ nnabla_cli convert net.nntxt parameters.h5 output.nnp

console 出力から単一の NNP ファイルへ 繰り返しの拡張や循環なしに変換する

$ nnabla_cli convert --nnp-no-expand-network net.nntxt parameters.h5 output.nnp

パラメータ形式を hdf5 で保持する

$ nnabla_cli convert --nnp-no-expand-network --nnp-parameter-h5 net.nntxt parameters.h5 output.nnp

すべてを単一の nntxt に入れる

$ nnabla_cli convert --nnp-parameter-nntxt net.nntxt parameters.h5 output.nntxt

ONNX 操作

NNP から ONNX へ変換する

$ nnabla_cli convert input.nnp output.onnx

onnx opset 9 出力を指定する場合、次のように指定してください (デフォルトは opset 7):

$ nnabla_cli convert input.nnp output.onnx -d opset_9

ONNX から NNP へ変換する

$ nnabla_cli convert input.onnx output.nnp

現在、インポートでは opset 6,7,9,10,11 をサポートします。

C Runtime 操作

一般的に、ファイルから C Runtime に変換するときは、バッチサイズを 1 に指定する方がよいとされています。バッチサイズが 1 より大きい場合、バッチサイズを 1 にするためにまとめて処理する必要があります。コマンドラインオプションで -b 1 を追加してください。

NNP から NNB へ変換する

$ nnabla_cli convert -b 1 input.nnp output.nnb

NNP から C ソースコードへ変換する

$ nnabla_cli convert -b 1 -O CSRC input.onnx output-dir

量子化

C-runtime ライブラリは、バイナリ (または固定小数点) の重みをサポートしており、モデル (およびフットプリント) のサイズを劇的に縮小できます。モデルを量子化する方法については、 固定小数点量子化によるネットワークの圧縮 を参照してください。

Tensorflow 操作

NNP から Tensorflow frozen graph へ変換する

$ nnabla_cli convert input.nnp output.pb

NNP から Tensorflow frozen graph へ変換する

$ nnabla_cli convert input.pb output.nnp

Tensorflow checkpoint から NNP へ変換する

checkpoint version 1 の場合:

$ nnabla_cli convert input.ckpt output.nnp --inputs x0,x1 --outputs y0,y1

input.ckpt と同じディレクトリには、 その関連ファイルである checkpoint、input.ckpt.meta などがあることが必要です。 inputs では、モデルの入力名がコンマで区切られていることが必要です。 outputs も同様です。checkpoint 形式の解析では、入力と出力があることが必要です。

checkpoint version 2 の場合:

$ nnabla_cli convert input.ckpt.meta output.nnp --inputs x0,x1 --outputs y0,y1

input.ckpt.meta と同じディレクトリには、その関連ファイルである checkpoint、 *.ckpt.index などがあることが必要です。

分割ネットワーク

分割ネットワークは少し複雑で面倒な場合があります。

NNP ファイルは複数の Executor ネットワークを持つことがありますが、Split は単一ネットワークを分割することしかサポートしません。

まず、NNP の中に executor がいくつあるかを確認し、どの executor を nnabla_cli dump で分割するのか指定してください。

$ nnabla_cli dump squeezenet11.files/SqueezeNet-1.1/*.{nntxt,h5}
2018-08-27 15:02:40,006 [nnabla][INFO]: Initializing CPU extension...
Importing squeezenet11.files/SqueezeNet-1.1/net.nntxt
Importing squeezenet11.files/SqueezeNet-1.1/parameters.h5
 Expanding Training.
 Expanding Top5Error.
 Expanding Top1Error.
 Expanding Runtime.
  Optimizer[0]: Optimizer
  Optimizer[0]:  (In) Data      variable[0]: Name:TrainingInput                  Shape:[-1, 3, 480, 480]
  Optimizer[0]:  (In) Data      variable[1]: Name:SoftmaxCrossEntropy_T          Shape:[-1, 1]
  Optimizer[0]:  (Out)Loss      variable[0]: Name:SoftmaxCrossEntropy            Shape:[-1, 1]
  Monitor  [0]: train_error
  Monitor  [0]:  (In) Data      variable[0]: Name:Input                          Shape:[-1, 3, 320, 320]
  Monitor  [0]:  (In) Data      variable[1]: Name:Top5Error_T                    Shape:[-1, 1]
  Monitor  [0]:  (Out)Monitor   variable[0]: Name:Top5Error                      Shape:[-1, 1]
  Monitor  [1]: valid_error
  Monitor  [1]:  (In) Data      variable[0]: Name:Input                          Shape:[-1, 3, 320, 320]
  Monitor  [1]:  (In) Data      variable[1]: Name:Top1rror_T                     Shape:[-1, 1]
  Monitor  [1]:  (Out)Monitor   variable[0]: Name:Top1rror                       Shape:[-1, 1]
  Executor [0]: Executor
  Executor [0]:  (In) Data      variable[0]: Name:Input                          Shape:[-1, 3, 320, 320]
  Executor [0]:  (Out)Output    variable[0]: Name:y'                             Shape:[-1, 1000]

上記の出力結果によって、1 つの executor のみがあることが分かります。

続いて nnabla_cli dump -E0 で executor の詳細情報を見ることができます。

$ nnabla_cli dump -E0 squeezenet11.files/SqueezeNet-1.1/*.{nntxt,h5}
2018-08-27 15:03:26,547 [nnabla][INFO]: Initializing CPU extension...
Importing squeezenet11.files/SqueezeNet-1.1/net.nntxt
Importing squeezenet11.files/SqueezeNet-1.1/parameters.h5
 Try to leave only executor[Executor].
 Expanding Runtime.
  Executor [0]: Executor
  Executor [0]:  (In) Data      variable[0]: Name:Input                          Shape:[-1, 3, 320, 320]
  Executor [0]:  (Out)Output    variable[0]: Name:y'                             Shape:[-1, 1000]

-F オプションにより、関数リストを取得できます。

$ nnabla_cli dump -FE0 squeezenet11.files/SqueezeNet-1.1/*.{nntxt,h5}
2018-08-27 15:04:10,954 [nnabla][INFO]: Initializing CPU extension...
Importing squeezenet11.files/SqueezeNet-1.1/net.nntxt
Importing squeezenet11.files/SqueezeNet-1.1/parameters.h5
 Try to leave only executor[Executor].
 Expanding Runtime.
  Executor [0]: Executor
  Executor [0]:  (In) Data      variable[0]: Name:Input                          Shape:[-1, 3, 320, 320]
  Executor [0]:  (Out)Output    variable[0]: Name:y'                             Shape:[-1, 1000]
  Executor [0]:   Function[  0  ]: Type: Slice                Name: Slice
  Executor [0]:   Function[  1  ]: Type: ImageAugmentation    Name: ImageAugmentation
  Executor [0]:   Function[  2  ]: Type: MulScalar            Name: SqueezeNet/MulScalar
  Executor [0]:   Function[  3  ]: Type: AddScalar            Name: SqueezeNet/AddScalar
  Executor [0]:   Function[  4  ]: Type: Convolution          Name: SqueezeNet/Convolution
  Executor [0]:   Function[  5  ]: Type: ReLU                 Name: SqueezeNet/ReLU
  Executor [0]:   Function[  6  ]: Type: MaxPooling           Name: SqueezeNet/MaxPooling

    SNIP...

  Executor [0]:   Function[ 63  ]: Type: ReLU                 Name: SqueezeNet/FireModule_8/Expand1x1ReLU
  Executor [0]:   Function[ 64  ]: Type: Concatenate          Name: SqueezeNet/FireModule_8/Concatenate
  Executor [0]:   Function[ 65  ]: Type: Dropout              Name: SqueezeNet/Dropout
  Executor [0]:   Function[ 66  ]: Type: Convolution          Name: SqueezeNet/Convolution_2
  Executor [0]:   Function[ 67  ]: Type: ReLU                 Name: SqueezeNet/ReLU_2
  Executor [0]:   Function[ 68  ]: Type: AveragePooling       Name: SqueezeNet/AveragePooling
  Executor [0]:   Function[ 69  ]: Type: Reshape              Name: SqueezeNet/Reshape
  Executor [0]:   Function[ 70  ]: Type: Identity             Name: y'

ImageAugmentation を除いたネットワークを取得したい場合、上記の出力結果によれば、ImageAugmentation は index 2 に配置されます。index 3 に分割した後、 ImageAugmentation を除いたネットワークを取得できます。 nnabla_cli 変換-E0 -S 3- オプションを指定する必要があります。このコマンドで出力を XXX_S_E.nnp という名前に変更します。 XXX は元の名前で、S は開始関数の index、E は終了関数の index です。

$ nnabla_cli convert -E0 -S 3- squeezenet11.files/SqueezeNet-1.1/*.{nntxt,h5} splitted.nnp
2018-08-27 15:20:21,950 [nnabla][INFO]: Initializing CPU extension...
Importing squeezenet11.files/SqueezeNet-1.1/net.nntxt
Importing squeezenet11.files/SqueezeNet-1.1/parameters.h5
 Try to leave only executor[Executor].
 Expanding Runtime.
   Shrink 3 to 70.
    Output to [splitted_3_70.nnp]

最終的に分割された出力として splitted_3_70.nnp を取得できました。分割された NPP は nnabla_cli dump で確認できます。

注意: Input shape は元のネットワークから変更されました。新しい input shape は開始関数の入力と同じです。

$ nnabla_cli dump splitted_3_70.nnp
2018-08-27 15:20:28,021 [nnabla][INFO]: Initializing CPU extension...
Importing splitted_3_70.nnp
 Expanding Runtime.
  Executor [0]: Executor
  Executor [0]:  (In) Data      variable[0]: Name:SqueezeNet/MulScalar           Shape:[-1, 3, 227, 227]
  Executor [0]:  (Out)Output    variable[0]: Name:y'                             Shape:[-1, 1000]

以上で終了です。