(57)【要約】【課題】効率的に機械学習を実行する情報処理装置を提供すること。【解決手段】一実施形態に係る情報処理装置は、ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段と、各フォワード処理と該フォワード処理に対応するバックワード処理との対応関係を記憶する記憶手段と、前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、前記記憶手段に記憶された前記対応関係に基づいて該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段と、を具備する。【選択図】図２
2020170551.tif 000002
【特許請求の範囲】
【請求項１】
ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段と、
前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段と、
を具備することを特徴とする情報処理装置。
【請求項２】
前記ソースコードは、前記ニューラルネットワークに対するバックワード処理を実行する関数を記載したコードを、前記ニューラルネットワークを構成する各層のフォワード処理を定義したコードの後に含み、
前記実行手段は、前記関数を記載したコードを実行した時点において、生成された前記参照構造に基づいて、前記ニューラルネットワークに対するバックワード処理を実行する、請求項１に記載の情報処理装置。
【請求項３】
前記ソースコードは、各層のフォワード処理を定義したコードを制御構文に対応するコードと組み合わせて含む、請求項１又は請求項２に記載の情報処理装置。
【請求項４】
前記ソースコードは、参照構造を断ち切る関数を記載したコードを含み、
前記実行手段は、前記参照構造を断ち切る関数を記載したコードを実行した時点において、対応する層を起点にして入力層側に向かう参照構造を断ち切る、請求項１から請求項３のいずれかに記載の情報処理装置。
【請求項５】
コンピュータを、
ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段、及び、
前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段、
として機能させることを特徴とするコンピュータプログラム。
【請求項６】
コンピュータに機械学習を実行させるための情報処理方法であって、
ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得処理と、
前記ソースコードに含まれた各コードを順次実行する実行処理であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行処理とを含む
ことを特徴とする情報処理方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本明細書に開示された技術は、機械学習に関する。
【背景技術】
【０００２】
近年、ニューラルネットワークを用いた機械学習が様々な分野において利用されている。
このような機械学習を実行するに際して、開発者等は、所定のプログラミング言語を用いて、ニューラルネットワークのネットワーク構造等を定義したソースコードを作成し、そのように作成したソースコードをパーソナルコンピュータ等に実行させることによって、そのようなパーソナルコンピュータに機械学習を実行させることができる（非特許文献１）。
【先行技術文献】
【非特許文献】
【０００３】
【非特許文献１】Yangqing Jia、”Caffe”、[online]、Berkeley Vision and Learning Center、[平成２７年９月２８日検索]、インターネット<URL: http://caffe.berkeleyvision.org/>
【発明の概要】
【発明が解決しようとする課題】
【０００４】
近年、ニューラルネットワークのネットワーク構造等を定義したソースコードを効率的に作成することを可能にするフレームワークが必要とされている。
【課題を解決するための手段】
【０００５】
そこで、本発明の様々な実施形態により、効率的に機械学習を実行する情報処理装置及び情報処理方法を提供する。
【０００６】
一態様に係る情報処理装置は、ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段と、各フォワード処理と該フォワード処理に対応するバックワード処理との対応関係を記憶する記憶手段と、前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、前記記憶手段に記憶された前記対応関係に基づいて該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段と、を具備するものである。
また、一態様に係るコンピュータプログラムは、コンピュータを、ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段、各フォワード処理と該フォワード処理に対応するバックワード処理との対応関係を記憶する記憶手段、及び、前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、前記記憶手段に記憶された前記対応関係に基づいて該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段、として機能させるものである。
【発明の効果】
【０００７】
本発明の様々な実施形態により、効率的に機械学習を実行する情報処理装置及び情報処理方法を提供することができる。
【図面の簡単な説明】
【０００８】
【図１】図１は、従来技術に係る「Define-and-Run」と称される手法を概念的に示す模式図である。
【図２】図２は、本発明の実施形態に係る「Define-by-Run」と称される手法を概念的に示す模式図である。
【図３】図３は、ニューラルネットワークのネットワーク構成の一例を示す模式図である。
【図４】図４は、ニューラルネットワークのネットワーク構成の別の例を示す模式図である。
【図５】図５は、ニューラルネットワークのネットワーク構成のさらに別の例を示す模式図である。
【図６】図６は、Linearによりフォワード処理時に実行される計算を実現するための擬似コードを示す図である。
【図７】図７は、Linearによりバックワード処理時に実行される計算を実現するための擬似コードを示す図である。
【図８】図８は、ReLUによりフォワード処理時に実行される計算を実現するための擬似コードを示す図である。
【図９】図９は、ReLUによりバックワード処理時に実行される計算を実現するための擬似コードを示す図である。
【図１０】図１０は、Convolution 2Dによりフォワード処理時に実行される計算を実現するための擬似コードを示す図である。
【図１１】図１１は、本発明の一実施形態に係る学習装置のハードウェア構成例を示す模式図である。
【図１２】図１２は、本発明の一実施形態に係る学習装置が有する機能例を模式的に示すブロック図である。
【図１３】図１３は、本発明の一実施形態に係る学習装置に入力されるソースコードの一例を示す図である。
【図１４】図１４は、図１３に示されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。
【図１５】図１５は、従来技術に係るCaffeにより記述されたソースコードの一例を示す図である。
【図１６】図１６は、本発明の一実施形態に係る学習装置に入力されるソースコードの別の例を示す図である。
【図１７】図１７は、図１６に示されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。
【図１８】図１８は、従来技術に係るCaffeにより記述されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。
【図１９】図１９は、本発明の一実施形態に係る学習装置に入力されるソースコードのさらに別の例を示す図である。
【図２０】図２０は、本発明の実施形態に係る実装手法のステップIを説明する模式図である。
【図２１】図２１は、本発明の実施形態に係る実装手法のステップIIを説明する模式図である。
【図２２】図２２は、Pythonによる実行部とチップによる実行部とが通信する場合を説明する模式図である。
【図２３】図２３は、本発明の実施形態に係る実装手法のステップIIIを説明する模式図である。
【図２４】図２４は、本発明の一実施形態に係る実装手法（第１の手法）に用いられる実装装置の構成例を示す模式図である。
【図２５】図２５は、本発明の一実施形態に係る実装手法に用いられる手順の一例を示すフロー図である。
【図２６】図２６は、本発明の一実施形態に係る実装手法における組み込み系チップの動作状態を示す模式図である。
【図２７】図２７は、本発明の一実施形態に係る実装手法（第２の手法）に用いられる実装装置の構成例を示す模式図である。
【図２８】図２８は、本発明の一実施形態に係る実装装置が有する機能を概念的に示す模式図である。
【図２９】図２９は、本発明の一実施形態に係る実装装置に含まれるＮａｔｉｖｅ層実行部の構成例を示す模式図である。
【図３０】図３０は、本発明の一実施形態に係る実装装置の多次元配列モジュールの構造体定義例を示す図である。
【図３１】図３１は、本発明の一実施形態に係る実装装置の多次元配列モジュールにおける多次元配列データの相互互換及び参照関係を示す図である。
【図３２】図３２は、本発明の一実施形態に係る実装装置のメモリプールモジュールを説明するための図である。
【図３３】図３３は、本発明の一実施形態に係る実装装置のメモリプールモジュールの構造体定義例を説明するための図である。
【図３４】図３４は、本発明の一実施形態に係る実装装置におけるパイプライン化のコーディング例を示す図である。
【図３５】図３５は、本発明の一実施形態に係る実装装置における仮想マシンモジュールの内部状態を示す図である。
【図３６】図３６は、本発明の一実施形態に係る実装装置における仮想マシンモジュールの実行フロー例を示す図である。
【図３７】図３７は、本発明の一実施形態に係る実装装置における仮想マシンモジュールの実行フロー例を示す図である。
【図３８】図３８は、本発明の一実施形態に係る実装装置における仮想マシンモジュールにおいてアドレス設定例を示す図である。
【図３９】図３９は、本発明の一実施形態に係る実装装置におけるPython層とNative層とが連携する全体動作の具体例を示す図である。
【図４０】図４０は、本発明の一実施形態に係る実装装置におけるバイトコード生成部における複数ネットワーク構成の出力を示す図である。
【図４１】図４１は、本発明の一実施形態に係る実装装置におけるバイトコード生成部におけるコード例を示す図である。
【図４２】図４２は、本発明の一実施形態に係るNative I/Fの構成例を示す図である。
【図４３】図４３は、本発明の一実施形態に係るNNによる識別・学習を実行するための構成例を示す図である。
【図４４】図４４は、本発明の一実施形態に係る多次元配列を管理する構成例を示す図である。
【図４５】図４５は、本発明の一実施形態に係るデータ表現変換部の構成例を示す図である。
【図４６】図４６は、本発明の一実施形態に係る通信部の構成例を示す図である。
【図４７】図４７は、本発明の一実施形態に係る浮動小数点及び固定小数点の実行部及び型変換部の構成例を示す図である。
【図４８】図４８は、本発明の一実施形態に係るメモリプールの構成例を示す図である。
【図４９】図４９は、本発明の一実施形態に係る複数のNNアルゴリズムを融合したアルゴリズム実行部の構成例を示す図である。
【図５０】図５０は、本発明の一実施形態に係る多次元配列のデータ通信量削減部の構成例を示す図である。
【図５１】図５１は、本発明の一実施形態に係る既存実行部との連携例を示す図である。
【図５２】図５２は、本発明の一実施形態に係る既存実行部との連携例を示す図である。
【図５３】図５３は、本発明の一実施形態に係るバイトコード生成部と仮想マシンの構成例を示す図である。
【図５４】図５４は、本発明の一実施形態に係る比較部の構成例を示す図である。
【図５５】図５５は、本発明の一実施形態に係る関数合成部の構成例を示す図である。
【発明を実施するための形態】
【０００９】
以下、本発明の様々な実施形態について添付図面を参照して説明する。なお、各図面において共通する構成要素には同一の参照符号が付されている。
まず、第１部において、実施形態に係る情報処理装置（以下、情報処理装置の一例である学習装置として説明を行う）について説明し、第２部において、実施形態に係る情報処理装置に実装されたアルゴリズムを組み込み系チップ（組み込み系半導体集積回路）に実装する手法について説明する。
【００１０】
第１部（実施形態に係る学習装置）
１．背景及び概略
深層学習（ディープラーニング）を含む機械学習アルゴリズムは、モデル毎に定義される損失関数の総和の最小化問題として定式化できることが多い。損失関数とは、与えられた学習用データサンプルにおいて、モデルの出力と正解との誤差で表されるような指標のことである。ここでは、データをモデルに入力してから出力を得て正解との比較を行うまでの一連の処理を計算グラフと呼び、その結果を損失関数とする。損失関数の最小化問題は、損失関数を微分した勾配（gradient）さえ計算可能であれば、勾配法と呼ばれる一般的な手法で解ける。
【００１１】
計算機プログラムとして実装しようとした場合は、損失関数も勾配も全てを自らコーディングするという方法があるが、複雑なモデルの勾配の算出は一般に困難であり、明示的に計算式を得ることが難しいことが多く、直接的にプログラムとして記述できない。そこで、Caffe（http://caffe.berkeleyvision.org/）、Torch（http://torch.ch/）、Theano（http://deeplearning.net/software/theano/）といったような計算ライブラリを使うのが第二の方法である。なお、これらのURLに開示された内容は、引用によりその内容の全体が本明細書に組み込まれる。
【００１２】
これらのライブラリでは、専用のミニ・プログラミング言語において、用意された基本計算要素（Primitive）の組み合わせとして損失関数を記述するだけで、その勾配関数をも自動的に得ることができる。これは、各基本計算要素の勾配自体が定義されているため、その組み合わせ全体の勾配も自動微分として得ることができるためである。すなわち、ディープラーニングで用いられるような、大規模な計算グラフとして表現できるニューラルネットワークも、その損失関数の計算がこのミニ・プログラミング言語を用いて明示的に表現できれば、その勾配関数を用いて勾配法で学習できる。
【００１３】
そのような計算ライブラリは、これまで、本件出願人が「Define-and-Run」と呼ぶ計算手順をベースとしてきた。これは、まず計算グラフを定義（Define）し、勾配を自動微分により導出した後、学習データによる学習（Run）を進めるというアプローチである。このアプローチは、計算グラフが複雑な制御構文（ifやforなど）を持たず、時間的にも変化しない場合には、Define時に一連の勾配計算をひとかたまりとして高速化コンパイルして準備しておける、メモリ管理が不要などのメリットをもたらすものであった。
【００１４】
しかしながら、ディープラーニングの研究の発展に伴って増えてきたような、複雑な制御構文を持つ計算グラフの場合や、データに依存しないメタな条件でも計算グラフが動的に変化するモデルの場合には、ミニ・プログラミング言語の表現力の低さやデバッグの困難性、動的に構造を変更できないことによるメモリ効率の悪化などの課題が存在していた。そのため、モデルの複雑さやデータの規模によっては、実装や実行が困難である場合があった。
【００１５】
そこで、実施形態では、本件出願人が「Define-by-Run」と呼ぶ新たな計算手順を提案する。具体的には、実施形態では、「Define-and-Run」のように固定されたグラフ構造を予め持つのではなく、毎回の学習（Run）においてグラフ構造を動的に抽出・記憶し、メタな変更を加え、勾配を都度計算し直すというアプローチを採用する。
【００１６】
これによって、事前にグラフを定義するミニ・プログラミング言語が不要となり、開発者にとってはその設計と実装とメンテナンスのコスト、ユーザにとってはその学習コストやデバッグの困難性が取り除かれるという効果がある。また、制御構文についても、一般的なプログラミング言語（CやJava（登録商標）やPython）が持つものを自由に用いることができるようになるため、より複雑なグラフ構造を持つニューラルネットワークも容易に実装可能となる。さらに、グラフに対するある種の条件付けによるメタな変更操作を可能にすることで、メモリ効率の向上や、モデルの柔軟な学習・適用が実現される。
【００１７】
上述した従来技術に係る「Define-and-Run」と称される手法と、実施形態に係る「Define-by-Run」と称される手法との概念的な違いは、図１と図２とを対比することによっても明らかである。図１は、従来技術に係る「Define-and-Run」と称される手法を概念的に示す模式図であり、図２は、本発明の実施形態に係る「Define-by-Run」と称される手法を概念的に示す模式図である。図１に示すDefine-and-runの構成では、まずミニ・プログラミング言語がモデル定義のみを入力し、計算グラフの実体であるフォワード(識別)処理とバックワード(学習)処理の計算手順を出力する(Defineステップ)。次のステップでFoward/Backwardの処理系がフォワード(識別)処理とバックワード(学習)処理の計算手順に従いデータの入力とパラメータ(重み)の更新を行う(Runステップ)ものである。
これに対して図2に示すDefine-by-runの構成では、汎用プログラミング言語の処理系がモデル定義、入力データ、パラメータを入力しながらフォワード(識別)処理を実行すると同時にバックワード(学習)処理の計算手順を生成する。ここでモデル定義は関数呼び出しや四則演算、ループや分岐といった汎用プログラミング言語の文法にそのまま準拠して定義されたものである。バックワード(学習)処理の計算手順はフォワード(識別)処理の実行とは独立して動的に変更することもできる。任意のタイミングでBackwardの処理系を呼び出すことができる。Backwardの処理系はBackwardの計算手順に従って入力データとFoward処理の結果からパラメータを更新する。
【００１８】
２．ニューラルネットワークに関連した背景技術
２−１．ニューラルネットワークの基本的な処理の流れ
ニューラルネットワークにおいて行われる処理には、主に、フォワード（Forward）処理、バックワード（Backward）処理、及び、重みの更新が含まれる。
フォワード処理とは、ニューラルネットワークの入力層から出力層に向かって情報を加工して伝播する処理をいう。
【００１９】
バックワード処理とは、ニューラルネットワークの出力層から入力層に向かって、誤差逆伝播及び重み勾配算出という２つの処理を行うものをいう。誤差逆伝播とは、出力側の層から得られた誤差（δ）を入力側レイヤーに伝播する処理をいう。重み勾配算出とは、重みを有する層について、出力側の層から得られた誤差（δ）と入力側レイヤーの出力値から重みの勾配（∂Ｗ）を求める処理をいう。
【００２０】
重みの更新とは、重みを有する層について、上記重み勾配算出により得られた重みの勾配（∂Ｗ）を用いて、確率的勾配降下法（SGD）から派生したアルゴリズムにより重みを更新する処理をいう。この重みの更新は、バッチ処理の単位ごとに１回実行される。
【００２１】
２−２．ニューラルネットワークの実例において頻出する計算モジュール
ニューラルネットワークを構成する各層は、例えば次に列挙するレイヤーアルゴリズムにより実現されるものである。
−Linear
−ReLu
−Dropout
−Softmax Cross Entropy
−Convolution 2D
−Pooling（Average Pooling及びMax Pooling等）等
【００２２】
重みの更新アルゴリズムの代表例としては、次のものが挙げられる。
−momentum-SGD
−Adam等
【００２３】
２−３．ニューラルネットワークのネットワーク構成例（１）
図３は、ニューラルネットワークのネットワーク構成の一例を示す模式図である。図３には、一例として、入力層と出力層（Softmax）との間に６つの中間層（Linear、ReLU、Linear、ReLU、Dropout及びLinear）が配置されたニューラルネットワークが例示されている。紙面上、右向きの矢印がフォワード処理を示し、左向きの矢印がバックワード処理を示す。
入力層は、更新すべき重みを持たないものであるので、バックワード処理は、この入力層に最も近い重みを有する中間層（図３に示した例では、入力層に隣接して配置されたLinear層）まで行われる。
【００２４】
２−４．ニューラルネットワークのネットワーク構成例（２）
図４は、ニューラルネットワークのネットワーク構成の別の例を示す模式図である。図４には、一例として、入力層と出力層（Softmax）に隣接して配置された中間層（Linear）との間に、直列に配置された複数の中間層（Convolution 2D、ReLU、Convolution 2D、ReLU）が、複数（３つ）並列に配置されたニューラルネットワークが例示されている。紙面上、上向きの矢印がフォワード処理を示し、下向きの矢印がバックワード処理を示す。
【００２５】
２−５．ニューラルネットワークのネットワーク構成例（３）
図５は、ニューラルネットワークのネットワーク構成のさらに別の例を示す模式図である。図５には、一例として、ループを有するニューラルネットワーク（これは、「Recurrent Neural Network」と呼ばれることがある。）が例示されている。同図には、フォワード処理におけるデータの流れが矢印により示されている。中間層（ここではLinear）は、前回のこの中間層の出力値と今回の入力層の出力値とを加算したものをこの中間層の入力とする計算を実行する。このようなニューラルネットワークにおいてバックワード処理を実現する方法としては、予めネットワークを時間軸方向に展開してループのないネットワークに変換する方法（BPTT）が知られている。
【００２６】
２−６．レイヤーアルゴリズムの計算内容（Linear）
レイヤーアルゴリズムの１つであるLinearは、入力側レイヤーの全ノードの加重平均を取る操作をその中間層内のノード数分だけ繰り返す計算を実行するものである。
図６は、Linearによりフォワード処理時に実行される計算を実現するための擬似コードを示す図であり、図７は、Linearによりバックワード処理時に実行される計算を実現するための擬似コードを示す図である。
【００２７】
２−７．レイヤーアルゴリズムの計算内容（ReLU）
レイヤーアルゴリズムの１つであるReLUは、入力側レイヤーの各ノードにMax(0,val)の計算を実行するものである。このアルゴリズムは、ニューラルネットワークの計算に非線形性を加える処理（活性化関数）で近年最も使われている手法である。
図８は、ReLUによりフォワード処理時に実行される計算を実現するための擬似コードを示す図であり、図９は、ReLUによりバックワード処理時に実行される計算を実現するための擬似コードを示す図である。
【００２８】
２−８．レイヤーアルゴリズムの計算内容（Dropout）
レイヤーアルゴリズムの１つであるDropoutは、ランダムに一定の割合のノードを選択し、出力及び誤差逆伝播を不活性化する計算を実行するものである。このアルゴリズムは、識別のみを実行する場合（すなわち、学習を実行しない場合）には、不要となるものである。
２−９．レイヤーアルゴリズムの計算内容（Softmax Cross Entropy）
レイヤーアルゴリズムの１つであるSoftmax Cross Entropyは、入力側レイヤーの値を以下の式により補正するものである。
【数１】
2020170551.tif 000003
このレイヤーアルゴリズムは、一般に出力層で用いられる。
また、このレイヤーアルゴリズムは、バックワード処理時には、正解ラベル（１又は０）と出力値との差分から誤差を計算する。
【００２９】
２−１０．レイヤーアルゴリズムの計算内容（Convolution 2D）
レイヤーアルゴリズムの１つであるConvolution 2Dは、Channel*Width*Heightのデータ構造を有する画像を畳み込むものである。入力側レイヤーも、当該レイヤーの出力も、Channel*Width*Heightのデータ構造を有する。このアルゴリズムでは、ストライド処理により画像サイズの縮小も可能である。また、このアルゴリズムでは、入力側レイヤーの画像にパディングを挿入することが行われる。このアルゴリズムは、Channel方向に関しては、Linearと同様の計算構造（出力Channel回数だけ入力Channelの内積計算を繰り返す）を有する。
図１０は、Convolution 2Dによりフォワード処理時に実行される計算を実現するための擬似コードを示す図である。
なお、Convolution 2Dは、バックワード処理時には、Linearと同様に重みの勾配計算及び誤差逆伝播を実行する。それぞれの処理のループの規模は、フォワード処理時におけるものと同様である。
【００３０】
２−１１．レイヤーアルゴリズムの計算内容（Max Pooling）
レイヤーアルゴリズムの１つであるMax Poolingは、入力側レイヤーの画像の最大値を取ることによってその画像を縦横方向に縮小するものである。なお、最大値を取るフィルタサイズと画像縮小のストライド幅とが異なる場合もある。また、Channel数に変化はない。
【００３１】
２−１２．レイヤーアルゴリズムの計算内容（Average Pooling）
レイヤーアルゴリズムの１つであるMax Poolingは、入力側レイヤーの画像の平均値を取ることによってその画像を縦横方向に縮小するものである。なお、平均値を取るフィルタサイズと画像縮小のストライド幅とが異なる場合もある。また、Channel数に変化はない。
【００３２】
２−１３．重みの更新アルゴリズム
重みの更新アルゴリズムとしては、確率的勾配降下法（SGD）から派生した様々なアルゴリズムが存在する。これらのアルゴリズムでは、重みの要素ごとに計算は独立している。
先に挙げたmomentum-SGDの計算式は次のとおりである。
【数２】
2020170551.tif 000004
また、先に挙げたAdamの計算式は次のとおりである。
【数３】
2020170551.tif 000005
【００３３】
３．実施形態に係る学習装置のハードウェア構成
次に、本発明の実施形態に係る学習装置のハードウェア構成について説明する。図１１は、本発明の一実施形態に係る学習装置のハードウェア構成例を示す模式図である。
【００３４】
学習装置１０は、図１１に示されているとおり、ＣＰＵ１１と、メインメモリ１２と、入力Ｉ／Ｆ１３と、出力Ｉ／Ｆ１４と、通信Ｉ／Ｆ１５と、外部メモリ１６と、ユーザＩ／Ｆ１７と、を含み、これらの各構成要素が内部バス１８を介して互いに電気的に接続されている。なお、学習装置１０は、選択的にＧＰＵ（図示せず）を含むことも可能である。
【００３５】
ＣＰＵ１１は、外部メモリ１６からオペレーティングシステム、及び、プログラミング言語（例えばPython）をサポートするプログラム（ソースコードの作成に用いられるプログラム）等の様々なプログラムをメインメモリ１２にロードし、ロードしたプログラムに含まれる命令を実行する。メインメモリ１２は、ＣＰＵ１１が実行するプログラムを格納するために用いられ、例えば、ＤＲＡＭによって構成される。
【００３６】
入力Ｉ／Ｆ１３は、測定装置（図示しない）の出力データを取り込む機能を有し、内部バス１８によって、各構成要素と接続される。ここで、測定装置の出力である各種測定データは、センサ等で取得した情報、例えば、温度、湿度、位置情報、画像データなどを含み、動画データや温度のある一定間隔で取得された温度データ列など時系列データでもよい。出力Ｉ／Ｆ１４は、内部バス１８を通して各構成要素からデータを受信し、学習装置の外部にある出力装置（図示しない）に出力するものである。ここで、出力装置に出力されるデータは、例えばモータを駆動する際の制御情報や、ブザー、制御スイッチ、自動車のアクセルやブレーキ、液晶ディスプレイなどの情報出力装置に対する制御情報などが想定される。
【００３７】
通信Ｉ／Ｆ１５は、ハードウェア、ファームウェア、又は、ＴＣＰ／ＩＰドライバやＰＰＰドライバ等の通信用ソフトウェア又はこれらの組み合わせとして実装され、通信網２０を介して、図示しないサーバ装置と様々な情報を通信することが可能となるように構成される。
外部メモリ１６は、例えば磁気ディスクドライブやフラッシュメモリ等により構成され、オペレーティングシステム及びプログラミング言語（例えばPython）をサポートするプログラム（ソースコードの作成に用いられるプログラム）等の様々なプログラムを記憶す
る。
【００３８】
以上の構成を有する一実施形態に係る学習装置１０は、ＣＰＵ１１（選択的にはこれに加えてＧＰＵ）が、外部メモリ１６からメインメモリ１２にロードした所定のプログラムを実行することによって、機械学習を行う学習装置として機能することができる。例えば、機械学習を行う学習装置１０は、ＣＰＵ１１（選択的にはこれに加えてＧＰＵ）が様々なプログラムを実行することにより、ニューラルネットワークによりモデル化された学習装置として実現され得る。
【００３９】
上記構成を有する学習装置１０は、対応する個体（機器）に搭載されるものとすることができる。また、学習装置１０は、対応する測定装置、及び、対応する出力装置に接続されるものとすることができる。これらの測定装置及び出力装置は、対応する個体（機器）に搭載される場合もあるし、別の機器として通信手段を使って接続される場合もある。
【００４０】
学習装置１０は、一実施形態において、機械学習を実行可能な任意の情報処理装置であり、例えば、パーソナルコンピュータ、タブレット、携帯電話機、スマートフォン、携帯情報端末、タッチパッド、及び、情報処理サーバ等を含むが、これらには限られない。
【００４１】
４．実施形態に係る学習装置の機能ブロック
次に、上記構成を有する学習装置１０が有する機能について簡単に説明する。図１２は、本発明の一実施形態に係る学習装置が有する機能例を模式的に示すブロック図である。
【００４２】
実施形態に係る学習装置１０は、上述したように「Define-by-Run」と呼ばれる手法に基づくものである。具体的には、実施形態に係る学習装置１０は、ニューラルネットワークのフォワード処理を、分岐、ループ及び関数呼び出しを含む一般的な手続き型言語により実行するタイミングで、バックワード処理及び重み更新の処理に必要なネットワーク構成の情報が動的に生成されることによって、実際にバックワード処理及び重み更新の処理を実行することができる仕組みを具備するものである。
【００４３】
このような「Define-by-Run」を実現するために、図１２に示すように、一実施形態に係る学習装置１０は、主に、取得部１１０と、記憶部１２０と、実行部１３０とを含む。取得部１１０は、ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得するものである。具体的には、かかるソースコードは、開発者やユーザ等によりテキストエディタを用いて所定のプログラミング言語（例えばPython等）を用いて作成されたものであり、取得部１１０は、このようなソースコードを取得する。
かかる取得部１１０は、例えば、図１１に示したＣＰＵ１１、メインメモリ１２、外部メモリ１６及びユーザＩ／Ｆ１７等が協働することによって、実現されるものとすることができる。
【００４４】
記憶部１２０は、ソースコードにおいて定義可能な複数のフォワード処理の各々と該フォワード処理に対応するバックワード処理との対応関係を記憶するものである。記憶部１２０に記憶された対応関係では、複数のフォワード処理に含まれる或るフォワード処理には、対応するバックワード処理が１対１の関係により対応付けられている。すなわち、記憶部１２０に記憶された対応関係では、例えば、Linearというレイヤー（中間層）については、Linearに対応したフォワード処理と、このフォワード処理に対応したバックワード処理とが、対応付けられている。（このようにフォワード処理とバックワード処理との１対１で対応付けられた対応関係は、バックワード処理のための参照構造を用いてバックワード処理を実行する際に、フォワード処理に対応した処理を実行するために用いられる。例えば、フォワード処理をＡ→Ｂ→Ｃという順番で実行すると、バックワード処理は、Ｃ→Ｂ→Ａという順番で実行されるところ、Ａ〜Ｃのそれぞれの関数に対して、フォワード処理及びバックワード処理という両方の処理がペアで実装されていることによって、このようなバックワード処理を実現することができる。）
なお、記憶部１２０は、取得部１１０に取得されたソースコード、及び、このソースコードに対応するプログラミング言語において用いられる様々なライブラリ等を含む様々な情報を記憶することができる。
かかる記憶部１２０は、例えば、図１１に示したＣＰＵ１１、メインメモリ１２及び外部メモリ１６等が協働することによって、実現されるものとすることができる。
【００４５】
実行部１３０は、取得部１１０に取得され（記憶部１２０に記憶され）たソースコードに含まれた各コードを順次実行するものである。この実行部１３０は、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算することができる。また、この実行部１３０は、各コードを実行した時点において、該コードに対応する層におけるオブジェクト間の参照構造を生成することができる。
かかる実行部１３０は、例えば、図１１に示したＣＰＵ１１、メインメモリ１２及び外部メモリ１６等が協働することによって、実現されるものとすることができる。
【００４６】
また、上述した「Define-by-Run」という手法を実現するために、一実施形態に係る学習装置１０は、上述した取得部１１０、記憶部１２０及び実行部１３０を用いることによって、３つのクラス、すなわち、Function、Variable及びOptimizerという３つのクラスを利用する。なお、これらのクラスの名称は、便宜的に付されたものであって、限定的なものではない。
まず、Functionというクラスは、フォワード処理とバックワード処理とをペアにして定義したクラスである。このFunctionというクラスは、上記「２−６」〜「２−１２」で例示した具体的なレイヤーアルゴリズムをサブクラスで定義するものである。
次に、Variableというクラスは、Function間で入出力されるデータを管理するクラスである。このVariableというクラスは、GPUとCPUとの違いを隠蔽する役割を有するものであり、また、ループを含むネットワークのバックワード処理を有限範囲で打ち切るためのメソッド（後述するunchain_backward）を有する。
さらに、Optimizerというクラスは、重みの更新を行うクラスである。
【００４７】
５．動作例１
次に、上記構成を有する実施形態に係る学習装置１０によりなされる動作の具体例について説明する。図１３は、本発明の一実施形態に係る学習装置に入力されるソースコードの一例を示す図である。なお、図１３に例示されたソースコードは、本実施形態に係る学習装置の特徴を説明することを目的として意図的に簡略化されたものであることに留意されたい。また、図１３において左端に記載された行数は、本具体例を説明するために付されたものであって、実際のソースコードには含まれない。
以下、本実施形態では、ソースコードが一例としてPythonにより記述される場合について説明するが、ソースコードはPython以外のプログラミング言語により記載されるものであってもよい。Phythonの詳細は、https://www.python.org/に開示されている。このURLに開示された内容は、引用によりその内容の全体が本明細書に組み込まれる。
【００４８】
まず、開発者等が図１３に例示されたソースコードをテキストエディタ等を利用して作成する。このように作成されたソースコードを学習装置１０の取得部１１０（図１２参照）が取得して記憶部１２０に記憶させる。次に、実行部１３０が、記憶部１２０に記憶されたソースコードに含まれた各コードを１行ずつ実行する。図１３に例示されたようにソースコードにif文やfor文等の制御構文が含まれていない場合には、実行部１３０は、第１行から最終行まで上から下に向かって１行ずつ順次実行する。逆に、ソースコードに制御構文が含まれている場合には、実行部１３０は、制御構文に従った順序により各コード
を実行する。
【００４９】
図１３に例示されているソースコードの内容について説明する。
第１行〜第３行は、FunctionSetによるパラメータを含むFunctionの登録を記述している。具体的には、ここでは、FunctionSetというクラスのオブジェクトに重みを含むFunction(本例では内積を行うレイヤーアルゴリズムを定義したFunctionサブクラスであるLinearクラスのインスタンスl1,l2,l3)を登録している。重みを含むFunctionはOptimizerによりその重みを更新できる。FunctionSetは、Optimizerによって更新されるFunctionをひとまとめにすることでコードの可読性を高めるための仕組みである。
【００５０】
第４行及び第５行は、Optimizerの初期化を記述している。第４行でAdamというアルゴリズムを実装したOptimizer(重みを更新するためのクラス)サブクラスのインスタンスを生成している。Adamの処理内容は、上記「２−１３」に記載した数式による更新を重みの要素ごとに実行するものである。第５行では、第４行で生成したOptimizerサブクラスのインスタンスのsetupメソッドに対して、第１行〜第３行で定義済みの重みを含むFunctionの一覧を渡している。このsetupメソッドの実行により、本メソッドに渡されたFunctionの一覧に含まれる重みを更新するためのOptimizerサブクラスの内部状態が初期化される。
【００５１】
第６行は、入力データのロードを記述している。すなわち、第６行は、入力データxおよびtをファイルなどから読み込む処理を例示している。本例において、xには画像や音声など情報量の多いデータが保持され、tにはxに対応するラベルID（答え合わせのための情報量の少ないデータ）が保持される。
【００５２】
第７行は、入力データのVariableオブジェクトによる保持を記述している。すなわち、第７行において、入力データを保持するVariableクラスのオブジェクトを生成する。「Define-by-Run」の機能は、VariableオブジェクトとFunctionオブジェクトとが相互依存することで実現されており、任意の入力データは「Define-by-Run」の機能を実現するための仕組みを有していないため、明示的にVariableクラスのインスタンスによって保持する手続きが必要となる。
【００５３】
第８行〜第１１行は、フォワード処理の実行を記述している。具体的には、第８行〜第１１行において、一般的なプログラミング言語の記述によりForward処理を実行する。「Define-by-Run」の機能により、本定義の実行と同時にバックワード処理のための参照構造が生成される。FunctionクラスのインスタンスとVariableクラスのインスタンスが相互に参照することで、任意の処理とデータの対応関係を表現できる。Variableクラスはデータを代表し、Functionクラスは処理を代表するのであるからこのことは自明である。この参照構造を用いて図２に示すBackwardの計算手順を表現するデータ構造を構築したものをバックワード処理のための参照構造と定義する。バックワード処理のための参照構造は、Variableオブジェクトに対する基本的な計算(四則演算やべき乗)及びVariableオブジェクトを引数や戻り値とするFunctionの呼び出しが行われる都度成長する。よって、分岐やループ、FunctionやVariableに対するもの以外の関数呼び出しを含むフォワード処理の記述であっても、バックワード処理のための参照構造を生成することができる。Variableオブジェクトに対する基本的な計算にもそれぞれFunctionサブクラスが対応付いている。
【００５４】
第１２行は、バックワード処理の実行を記述している。具体的には、第１２行は、第８行〜第１１行で実行したフォワード処理の実行結果として得られたloss変数（Variableクラスのインスタンス）のバックワードメソッド呼び出しにより、バックワード処理を実行する。バックワード処理は、フォワード処理実行時に生成されたバックワード処理のための参照構造をたどることでフォワード処理とは逆の順序で自動的に実行される。
【００５５】
第１３行は、重みの更新を記述している。具体的には、第１３行では、第１２行でバックワード処理を実行した結果として重みの勾配が算出される。第１３行のようにOptimizerサブクラスのインスタンスのupdateメソッドを呼び出すと、この重みの勾配を用いて重みが更新される。Optimizerサブクラスに対するupdateメソッドの呼び出しとVariableクラスのbackwardメソッドの呼び出しとは別関数となっているので、部分的にバックワード処理を実行した後、重みの更新を実行することもできる。これは、すでに学習済みのFunctionに対して重みの更新を行いたくない場合に有効である。
【００５６】
ここで、フォワード処理時に処理される内容として、特に第８行に記述されたコードによって処理される内容に着目する。
第８行は、h1=F.relu(model.l1(x))と記述している。
【００５７】
“model.l1(x)”の実行時には、以下のようなバックワード処理のための参照構造が生成される。
【数４】
2020170551.tif 000006
上記参照構造において、x'はxをコピーしたVariableオブジェクトを表し、l1’はl1のコピー(浅いコピー)を表し、yはl1’のforwardメソッドが返す値(Variableオブジェクト)を表し、splitterはネットワークの分岐を管理するクラスのインスタンスを表す。
浅いコピーとはオブジェクトをコピーする際に、オブジェクトが内部的に参照するデータをコピーしないようなオブジェクトのコピー方法である。浅いコピーとすることで例えばFuntionのインスタンスが持つ重みのデータの重複を避けることができる。
また、矢印の意味はオブジェクトの参照の方向を表す。例えばA←Bという記述はBのオブジェクトのメンバにAのオブジェクトへの参照が含まれることを意味する。
【００５８】
上記参照構造は、“F.relu(”の実行後には以下のようなバックワード処理のための参照構造となる。
【数５】
2020170551.tif 000007
ここでは、第８行に記述されたコードの実行時にバックワード処理のための参照構造が生成される場合について説明したが、第９行及び第１０行に記述されたコードの実行時においても同様に参照構造が生成されることはいうまでもない。
以上のように、フォワード処理の実行時には、自然な形式の関数呼び出しによってバックワード処理のための参照構造が生成される。
この時点で、h1を起点にバックワードの処理が実行可能な状態と成っている。実際にh1からバックワード処理を実行する場合のバックワード処理系が実行する処理の流れを以下に示す。
h1のインスタンスが参照するrelu'をたどりrelu'のBackward処理を呼び出す。この時の入力はh1が保持する誤差の値であり、出力結果はy'のインスタンスに格納される。このようなFunctionインスタンスが入出力するデータ対応はFunctionのサブクラスごとに定義されるFoward処理／Backward処理においてそれぞれ定義される。次にrelu'からy'を経由してspliterにたどり着く、spliterはy'が保持する誤差の値をyにコピーする。(splitterが挿入される理由は次節で述べる)。次にyからl1'をたどりl1'のBackward処理を実行する。この時の入力はyが保持する誤差の値であり、出力結果はx'のインスタンスに格納される。また重みの誤差も計算される。重みの誤差は、x’に格納されたFoward時の出力値と、yが保持する誤差の値から計算される。以下同様にバックワード処理のための参照構造の終点であるxまでたどるとバックワード処理は終了となる。
【００５９】
なお、Splitterが参照構造に挿入される理由について念のため説明する。
上記参照構造の作成直後に“model.l1(x)”をもう一度コールすると以下のような参照構造が生成される。
【数６】
2020170551.tif 000008
上記参照構造において、l1''はl1のコピー(浅いコピー)を表し（l1’とは別インスタンス)、x''はxをコピーしたVariableオブジェクトを表し(x’とは別インスタンス)、zはl1''のforwardメソッドが返す値(Variableオブジェクト)を表す。
【００６０】
バックワード処理時に誤差値を出力側レイヤーから伝播する際、splitterのインスタンスがx’とx''にそれぞれ伝わる誤差の値を加算合成した結果をxの誤差として設定する。このようにsplitterを挿入することで、フォワード処理時にxを入力として用いた全てのFunctionからバックワード処理時に誤差を伝播することができる。
【００６１】
次に、図１３に例示されたソースコードを実行した際に生成されるニューラルネットワークのネットワーク構成について補足する。図１４は、図１３に示されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。なお、図１４において、点線により描かれたブロックは、変数のインスタンスを示し、実線により描かれたブロックは、関数を示す。
【００６２】
まず、第７行が実行された時点では、変数xのインスタンス３０及び変数tのインスタンスが生成される。説明の便宜上、図１４には、変数xのインスタンス３０のみしか示されていないが、実際には、変数tのインスタンスも同様に生成される。第７行が実行された時点では、変数xのインスタンスには、実際に画像や音声などのデータが保持されている。
【００６３】
次に、実行部１３０により第８行が実行された時点では、変数xのインスタンス３０の後に、関数「l1」３１、関数「relu」３２及び変数h1のインスタンス３３が順次成長した状態のニューラルネットワークが生成される。第８行が実行された時点では、第８行に記述されたフォワード処理の実行結果が既に変数h1のインスタンス３３により保持されていることに留意されたい。また、第８行が実行された時点では、上述したように、現時点において生成されているバックワード処理のための参照構造が生成される。
【００６４】
次に、実行部１３０により第９行が実行された時点では、変数h1のインスタンス３３の後に、関数「l2」３４、関数「relu」３５及び変数h2のインスタンス３６が順次成長した状態のニューラルネットワークが生成される。第９行が実行された時点では、第９行に記述されたフォワード処理の実行結果が既に変数h2のインスタンス３６に保持されていることに留意されたい。また、第９行が実行された時点では、上述したように、現時点において生成されているバックワード処理のための参照構造が生成される。
【００６５】
同様に、実行部１３０により第１０行が実行された時点では、変数h2のインスタンス３６の後に、関数「l3」３７及び変数yのインスタンス３８が順次成長した状態のニューラルネットワークが生成される。第１０行が実行された時点では、第１０行に記述されたフォワード処理の実行結果が既に変数yのインスタンス３８に保持されていることに留意されたい。また、第１０行が実行された時点では、上述したように、現時点において生成されているバックワード処理のための参照構造が生成される。
【００６６】
最後に、実行部１３０により第１１行が実行された時点では、変数yのインスタンス３８の後に、関数「Softmax」３９及び変数lossのインスタンス４０が順次成長した状態のニューラルネットワークが生成される。第１１行が実行された時点では、第１１行に記述されたフォワード処理の実行結果が既に変数lossの新スタンス４０に保持されていることに留意されたい。また、第１１行が実行された時点では、上述したように、現時点において生成されているバックワード処理のための参照構造が生成される。第１１行が実行された時点において、ソースコードに記述されたフォワード処理は完了している。すなわち、第１１行が実行された時点において、最終的に得られたニューラルネットワークにより行われた識別の結果と変数tによって与えられる真の識別結果との差分が変数lossのインスタンス４０に保持されている。この差分を入力として次のステップのバックワード処理が実行される。
【００６７】
第８行〜第１１行に記述されたフォワード処理が完了した後、次に、実行部１３０により第１２行が実行されることにより、バックワード処理が実行される。生成されたバックワード処理のための参照構造が既に生成されているため、実行部１３０は、この参照構造に基づいてバックワード処理を実行することにより、ニューラルネットワークに含まれた各中間層（但し、重みを有する中間層のみ）の重みの勾配を算出することができる。
【００６８】
次に、実行部１３０により第１３行が実行される。これにより、第１２行の実行により算出された重みの勾配を用いて、各中間層（但し、重みを有する中間層のみ）の重みが更新される。すなわち、学習が実行される。
【００６９】
このように、本実施形態に係る学習装置にあっては、開発者等は、フォワード処理に関しては、いずれの変数のインスタンスをいずれの関数に与えることによって得られた実行結果をいずれの変数のインスタンスに保持させるかを１行ずつ記述する方式により、ニューラルネットワークを構築することができる。これにより、開発者等は、フォワード処理をソースコードにおいて直感的に記述することを容易に行うことができる。また、開発者等は、ソースコードにおいて（バックワード処理を意識する必要なく）フォワード処理を記述し、そのソースコードを本実施形態に係る学習装置に実行させることにより、自動的にバックワード処理を学習装置に実行させることができる。
【００７０】
６．比較例１
次に、本実施形態に係る学習装置の優位性を示すために、図１３に例示したソースコードにより実行されるものと等価な処理を従来技術に係るCaffeにより記述した場合について説明する。図１５は、従来技術に係るCaffeにより記述されたソースコードの一例を示す図である。
【００７１】
図１５に示すように、「layer」という用語の直後に記載された｛｝で囲まれたブロックにレイヤー（本実施形態におけるFunctionに対応するもの）の定義が記述されている。この従来技術に係る手法では、レイヤー間の依存関係をコード中に明示する必要がある。例えば、「top」及び「bottom」という記述がレイヤー同士の依存関係を表している。「bottom」は、レイヤーに対する入力がどのレイヤーから得られるかを表し、「top」は、レイヤーでの処理結果がいずれのレイヤーに出力されるのかを表す。
【００７２】
この従来技術に係る手法では、ニューラルネットワークで行われる学習及び識別の処理に先んじて静的にネットワークの構成を定義しておく必要がある。すなわち、ニューラルネットワークのネットワーク構成をまず定義し、その後に、そのニューラルネットワークの学習及び識別を実行させる必要がある。よって、データの性質に応じてネットワークの構成を動的に変更することが困難である。
これに対して、本実施形態に係る学習装置では、図１４を参照して上述したように、ニューラルネットワークの構成を定義する各コードを実行した時点において、そのコードに対応するフォワード処理が実行される。すなわち、ニューラルネットワークの構成の定義とその構成によるフォワード処理の実行とが同じタイミングで実行される。これにより、データの性質に応じてネットワークの構成を動的に変更することも容易に行うことができる。例えば図１３のコードに分岐を加えて変数tの値や、変数xのデータサイズに応じて、フォワード処理を実行するレイヤーを切り替えても良い。また例えば図１９のコードで９行目の定数「10」の代わりに可変な値を入力データとして与えることもできる。
【００７３】
また、従来技術に係る手法では、開発者等は、ソースコードを作成する際に、フォワード処理及びバックワード処理の両方を適切に実行できるように、ニューラルネットワークのネットワーク構成の定義を記述する必要がある。これに対して、本実施形態に係る学習装置では、図１４を参照して上述したように、バックワード処理が適切に実行できるかどうかを意識する必要なく、単にフォワード処理（ネットワーク構成）を記述した後、ソースコードを学習装置に実行させることによって、学習装置が自動的にバックワード処理を実行する。したがって、開発者等は、簡単かつ効率的にニューラルネットワークを構築して識別及び学習を実行させることができる。
【００７４】
さらに、従来技術に係る手法では、開発者等は、ソースコードを作成する際には、フォワード処理及びバックワード処理の両方を適切に実行できるように、ニューラルネットワークを定義した後、そのように定義されたニューラルネットワークに対してデータ（入力データ及び教師データ等）を代入する、という手順を踏む。したがって、ソースコードを直感的に記述することが困難である。
これに対して、本実施形態に係る学習装置では、開発者等は、フォワード処理（ネットワーク構成）を１行ずつ記載する時点において、いずれの変数のインスタンスをいずれの関数に与えることによって得られた実行結果をいずれの変数のインスタンスに保持させるかを１行ずつ記述する方式により、ソースコードを記述する。これにより、開発者等は、ソースコードを直感的に記述することができる。
【００７５】
７．動作例２
次に、上記構成を有する実施形態に係る学習装置１０によりなされる動作の別の具体例について説明する。図１６は、本発明の一実施形態に係る学習装置に入力されるソースコードの別の例を示す図である。なお、図１６に例示されたソースコードは、本実施形態に係る学習装置の特徴を説明することを目的として意図的に簡略化されたものであることに留意されたい。また、図１６において左端に記載された行数は、本具体例を説明するために付されたものであって、実際のソースコードには含まれない。
【００７６】
図１６に示されたソースコードを参照して、本実施形態に係る学習装置によれば、制御構文（ここではfor文）を用いて容易にニューラルネットワークを構築することも可能である点について説明する。
【００７７】
第１行〜第３行については、図１３に示したソースコードにおける第１行〜第５行と同様であるので、詳細な説明を省略する。
第４行は、iの値が０〜１０００になるまで第５行〜第１０行に記述された処理をループ処理することを記述している。
第５行及び第６行については、図１３に示したソースコードにおける第６行及び第７行と同様であるので、詳細な説明を省略する。
第７行は、関数l1及び関数reluの処理結果であるyを再度l1の引数に足し込むことを記述している。
第８行〜第１０行については、図１３に示したソースコードにおける第１１行〜第１３行と同様であるので、詳細な説明を省略する。
【００７８】
図１７は、図１６に示されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。なお、図１７において、点線により描かれたブロックは、変数のインスタンスを示し、実線により描かれたブロックは、関数を示す。また、図１７は、説明の便宜上、変数iが０〜２である場合のみに生成されるニューラルネットワークの構成しか示していない。
【００７９】
図１６及び図１７から明らかであるように、本実施形態に係る学習装置では、変数のインスタンス及び関数を含んだ同一の構成（ここでは、変数xのインスタンス５１と変数yのインスタンス５０とを加算する関数５２の後に、関数「l1」５３及び関数「relu」５４が順次続き、関数「relu」５４の出力値が変数yのインスタンスに保持されるような構成）を複数繰り返すようなニューラルネットワークであっても、簡単な制御構文（ここではfor文）を用いて簡単に構築することができることが分かる。すなわち、本実施形態に係る学習装置において用いられるソースコードは、プログラミング言語の制御構文と親和性の高いものであることが分かる。
【００８０】
８．比較例２
次に、本実施形態に係る学習装置の優位性を示すために、図１６に例示したソースコードにより実行されるものと等価な処理を従来技術に係るCaffeにより記述した場合について説明する。図１８は、従来技術に係るCaffeにより記述されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。
【００８１】
図１６及び図１７に例示したものと同様のニューラルネットワークを従来技術に係るCaffeにより構築しようとする場合には、制御構文を用いてニューラルネットワークの構成を定義することができないため、開発者等は、まず、図１８に示すような基本的な構成を定義する。次に、開発者等は、関数７２に対して変数yのインスタンス７５の初期値を与えるとともに、関数７２に対して前時間における変数yのインスタンス７５と現時間における変数xのインスタンス７１とを与える（図１８における太線で描かれた矢印の部分）処理を特別に記述しなくてはならない。上記基本的な構成が多数繰り返されるようなニューラルネットワークを構築する場合、又は、多層構造を有するニューラルネットワークを構築する場合には、開発者等は、そのように多数繰り返す都度、又は、多層構造における各層ごとに、かかる特別な記述をしなくてはならない。
【００８２】
これに対して、本実施形態に係る学習装置では、図１６及び図１７に例示したとおり、記述されるソースコードは、プログラミング言語の制御構文を用いて特別な記述を必要とすることなく簡単に記述可能なものである。したがって、本実施形態に係る学習装置によれば、複雑な又は大規模なニューラルネットワークであっても、簡単かつ効率的に構築することができる。
【００８３】
９．付加的な機能（１）について
一実施形態に係る学習装置は、バックワード処理のための参照構造を断ち切る関数を実行することが可能であってもよい。
具体的には、Variableクラスのインスタンスのunchain_backwardメソッドがコールされると、そのインスタンスを起点に入力側へと向かうバックワード処理のための参照構造が断ち切られる。例えば、以下のようなバックワード処理のための参照構造がフォワード処理の実行により生成されていたとする(splitterなどの詳細な構成は省略して示す)。
【００８４】
A（入力層）←Convolution2D←B←Linear←C←Softmax←D（出力層）
ここで、A,B,C,DはVariableクラスのインスタンスを表し、Convolution2D, Linear, SoftmaxはFunctionクラスのインスタンスを表す。
【００８５】
このとき、B. unchain_backward()をコールするとバックワード処理のための参照構造はBを起点に断ち切られる結果、以下のように変化する。
B←Linear←C←Softmax←D（出力層）
【００８６】
このunchain_backwardメソッドを図１６に示したソースコードに適用する局面について検討する。このソースコードにおいて、第７行では、関数l1及び関数reluの処理結果であるyを再び関数l1の引数に足し込んでいる。「Define-by-Run」の仕組みでは、”x+y”の記述を実行する際に、yのコピーが生成された上で、これまで実行されたフォワード処理によって生成済みのバックワード処理のための参照構造が連結される。よって、本例ではループが繰り返されるごとにバックワード処理のための参照構造が成長し続ける。
第９行で実行されるバックワード処理は、成長したバックワード処理のための参照構造に対して実行される。第９行の処理は、ループ内に含まれているため、このループ処理全体の計算時間は、ループサイズの２乗に比例してしまう。
【００８７】
図１９は、本発明の一実施形態に係る学習装置に入力されるソースコードのさらに別の例を示す図である。なお、図１９において左端に記載された行数は、本具体例を説明するために付されたものであって、実際のソースコードには含まれない。
【００８８】
図１６に示したソースコードを変更し、図１９に示すように、第１１行においてunchain_backwardを定期的に呼び出すことにより、計算時間の増加を抑えることができる。
第９行は、第４行以降のループが１０回実行される度に、第１０行〜第１２行の処理が実行されることを記述している。
第１１行は、unchain_backwardをコールし、lossを起点にバックワード処理のための参照構造を破棄している。これにより、ループ処理全体の計算時間を短く抑えることができる。
【００８９】
このようにunchain_backwardを用いることにより、参照構造にループを有するフォワード処理に対して学習を行う場合であっても、バックワード処理のための参照構造の過剰な成長を抑え、現実的な計算量で学習処理を実行することができる。
さらに、別の実施形態では、特定のFunctionについて重みの更新を行わないようにすることを目的として、unchain_backwardを用いることも可能である。
【００９０】
１０．付加的な機能（２）について
一実施形態に係る学習装置は、Variableクラスのインスタンス初期化時にvolatile属性を指定することができる。volatile属性が有効な場合には、そのVariableを入力するフォワード処理についてバックワード処理のための参照構造は生成されない。
【００９１】
学習済みの重みを用いてフォワード処理のみを実行する場合（すなわち、バックワード処理を実行する必要がない場合)には、フォワード処理の実行時にバックワード処理のための参照構造を生成する処理が実行されてしまうと、実行速度及びメモリ使用量の両方において無駄が発生してしまう。このような場合に、フォワード処理の入力データを保持するVariableクラスのインスタンス初期化時にvolatile属性を指定しておくことにより、バックワード処理のための参照構造の生成を止めて、効率的にフォワード処理のみを実行することができる。
【００９２】
１１．付言
最も好ましい実施形態として、Pythonにより記述されたソースコードが学習装置に入力される実施形態を説明してきたが、本明細書に開示された技術は、Pythonにより記述されたソースコードを用いた場合のみに限定されるものではない。すなわち、本明細書に開示された技術は、学習装置が各コードを実行した時点においてそのコードに記述されたフォワード処理の出力値を入力値に基づいて計算すること、学習装置が各コードに記述されたフォワード処理を実行する度にバックワード処理のための参照構造を生成（してこの参照構造に基づいてバックワード処理を実行可能に）すること、及び、制御構文を用いてニューラルネットワークの構成を定義すること、のうちの少なくとも１つを実現することが可能なPythonと等価なプログラミング言語（例えば、R、Julia、Sparkz及びMLib等）により記述されたソースコードを用いた場合にも、同様に適用可能なものである。
【００９３】
本明細書に開示された技術は、Python及びこれと等価なプログラミング言語により記述されたソースコードを実行することによって実現可能なものであり、これに代えて、Python及びこれと等価なプログラミング言語により記述されたモジュール又はライブラリを実行することによって実現可能なものであってもよい。
【００９４】
本明細書において、変数、関数、メソッド、クラス、サブクラス等を識別するために用いられた名称は、本明細書に開示された技術を限定するものではなく、任意のものであってよい。
【００９５】
本明細書で説明される処理及び手順は、実施形態において明示的に説明されたものによってのみならず、ソフトウェア、ハードウェア又はこれらの組み合わせによっても実現可能なものである。具体的には、本明細書で説明された処理及び手順は、集積回路、揮発性メモリ、不揮発性メモリ、磁気ディスク、光ストレージ等の媒体に、当該処理に相当するロジックを実装することによって実現される。また、本明細書で説明された処理及び手順は、それらの処理・手順をコンピュータプログラムとして実装し、各種のコンピュータに実行させることが可能である。
【００９６】
本明細書中で説明される処理及び手順が単一の装置、ソフトウェア、コンポーネント、モジュールによって実行される旨が説明されたとしても、そのような処理又は手順は、複数の装置、複数のソフトウェア、複数のコンポーネント、及び／又は、複数のモジュールによって実行されるものとすることができる。また、本明細書中で説明されるデータ、テーブル又はデータベースが単一のメモリに格納される旨説明されたとしても、そのようなデータ、テーブル又はデータベースは、単一の装置に備えられた複数のメモリ又は複数の装置に分散して配置された複数のメモリに分散して格納されるものとすることができる。さらに、本明細書において説明されるソフトウェア及びハードウェアの要素は、それらをより少ない構成要素に統合して、又は、より多い構成要素に分解することによって実現されるものとすることができる。
【００９７】
第２部（アルゴリズムの組み込み系チップへの実装手法）
１．背景
ディープラーニング（深層学習）は、その高い性能を得られる反面、大規模な演算量及びメモリ使用量、並びに、学習サンプル量を要求するアルゴリズムである。潤沢な計算資源を安価に得られるGPU及びクラウド、並びに、学習サンプルの共有を可能とするWebインフラの普及が、近年のディープラーニングの隆盛を支える背景にあったといえる。
ディープラーニングのアルゴリズム開発を支援する環境(ライブラリ、フレームワーク)には様々なものが存在する。多くの開発環境はGPUを用いて学習速度を向上させる機能を有している。
【００９８】
自動車の完全自動運転や汎用性の高いロボット制御といった分野では、カメラやLIDAR(レーザー距離測定)といった様々なセンサーからの取得した情報をリアルタイムに解析し、無数のモーターをコントロールしてその課題を解決するための高度な情報処理能力が要求されるので、従来とは一線を画す性能を持つディープラーニングの応用が強く期待されている。
しかしながら、こうした分野は、安全性やチップ価格、消費電力などの要請からGPUやクラウドと比べると計算資源に乏しい組み込み環境に依存しているため、高い計算資源を必要とするディープラーニングの応用が遅れている。
組み込み環境へのディープラーニングの応用が遅れている要因は、こうしたアルゴリズムの計算資源への要求が現実的・経済的な組み込み環境の性能を超えているという側面の他に、ソフトウェア環境を初めとしてディープラーニングをサポートする実装が出揃っていない面も挙げられる。
組み込み環境においても、ハードウェアの性能は年々向上しており、ディープラーニングのアルゴリズムにおいても、計算資源への要請を緩和する改良が継続しているので、前者の要因は徐々に解決していくものと考えられる。
【００９９】
本発明の実施形態が解決すべき課題は、組み込み系チップにおいて製品レベルの要求を満たした上で動作するディープラーニングのアルゴリズムを設計するためのフレームワーク開発により、主にソフトウェア環境面で残っているディープラーニングの組み込み環境適応への障壁を突破し、開発速度を促進するためのものである。
GPUベースではありながらディープラーニングのアルゴリズム開発において高い生産性をもたらすフレームワークである上記第１部において述べた実施形態に係る学習装置を、組み込み環境向けに機能拡張することが本課題を解決する上で最適な手段と考えられるので、次段落以降では実施形態に係る学習装置にフォーカスした組み込み環境適応への課題を述べる。
【０１００】
２．実施形態に係る実装手法の課題
上記第１部において説明した実施形態に係る学習装置は、高度な言語機能やライブラリに依存しているので、この学習装置において動作するアルゴリズムをそのまま組み込み系半導体チップ上で動作させようとすることは、以下のような弊害をもたらす可能性がある。
まずセキュリティ面に関して、ライブラリや言語の規模が大きくなると事実上不可知な実装にアプリケーションが依存する度合いが高まる。それにつれて、そうした実装に含まれる不具合が、そのままチップ製品の不具合となってしまうリスクが高まる。
次に、フットプリント面に関して、ライブラリや言語の実装自体がチップ製品のメモリ資源を圧迫する。
さらに、オーバーヘッド面に関して、高度に抽象化したAPIを持つライブラリ経由では、チップ製品の計算資源をフル活用できない。少なくともニューラルネットワークで必要とされる大規模計算についてはチップに特化した低レベルなパフォーマンスチューニングが必須となる。
以上のような理由から、実施形態に係る学習装置において動作するアルゴリズムをそのまま組み込み系半導体チップ上で動作させるだけでは、製品レベルの要求を満たせない可能性が高い。
【０１０１】
３．実施形態に係る実装手法のコンセプト
実施形態に係る実装手法では、豊富な計算資源を有するパーソナルコンピュータ等において設計した新規のニューラルネットワーク（NN）のアルゴリズムを任意の組み込みチップ（組み込み系半導体集積回路）において製品レベルの要件を満たした上で動作できる状態を最短期間で実現する。そのためには、アルゴリズムを設計する開発者と、ハードウェアを深く意識する開発者とがなるべく独立して仕事を進められることが望ましい。本実施形態では、それを助ける装置（フレームワーク）に関する技術的思想を提案する。
【０１０２】
４．組み込みチップ開発で想定される開発ステップ
組み込み系チップを開発する際に辿るステップとして、以下の３つのステップが想定される。
ステップI：PC（+GPU）上で実施形態に係る学習装置に用いられるコード（一例としてPythonで記述されたコード）が動いている状態
この状態は、複雑な構成を有するニューラルネットワークを用いたアルゴリズムの設計・検証を少ないコード記述で実現した状態である。これは、上述した「Define-by-Run」という手法のコンセプトである。
ステップII：チップ向けに最適化した実装とPythonコードとが混在した状態
この状態は、実施形態に係る学習装置で設計したアルゴリズムのチップ上での動作確認及びパフォーマンス検証をPythonコードをほとんど変えずに実現した状態である。
ステップIII：チップ向けに最適化した実装のみで実施形態に係る学習装置で設計したアルゴリズムが動作する状態
この状態は、チップとしての製品レベルの仕様要件を満たした上でアルゴリズムが動作する（チップ上で他のモジュールや制御機構とのリアルタイム性の高い協調動作ができる）状態である。
本実施形態に係る実装手法では、実施形態に係る学習装置で新しいアルゴリズムを開発するときに、上記ステップI〜IIIのステップ間において、なるべく再修正、再設計及び再学習の手間を省くことにより、短期間で開発を進められるようなフレームワークを提案する。
【０１０３】
４−１．  ステップIについて
図２０は、本発明の実施形態に係る実装手法のステップIを説明する模式図である。図２０に示された構成は、上記第１部において説明した実施形態に係る学習装置が前提としている構成である。すなわち、この構成は、プログラミング言語の一態様としてのPythonで記述されたソースコードが、ライブラリの一態様としてのPyCUDA及びライブラリの一態様としてのnumpy（BLAS）を利用し、これらのライブラリがそれぞれGPU及び汎用計算機をドライブするものである。なお、図２０に示された「Chainer」とは、上記第１部において述べた実施形態に係る学習装置において用いられるソースコードを記述するためのフレームワークに対して本件出願人により付された名称である。
【０１０４】
４−２．ステップIIについて
図２１は、本発明の実施形態に係る実装手法のステップIIを説明する模式図である。図２１に示された構成では、Python上でChainerのフロントエンドを実行する。図２１に示すように、本実施形態では、Native I/F（例えばC言語など低水準の言語で記載されたChainerの主要機能と同等な実装を呼び出すためのインターフェイス)を設けることで、PC上の実行と組み込みチップ向けに最適化した実行とを同一コードで実行できる。
【０１０５】
図２２は、Pythonによる実行部とチップによる実行部とが通信する場合を説明する模式図である。図２２に示すように、Native I/Fの実装に通信機能を設けることで組み込みチップ上の構成からPythonへの依存を取り除くことも可能（PC上のChainerから組み込みチップ上の最適化実装をドライブする）である。
【０１０６】
Native I/Fの実装について
ChainerのFunction及びOptimizerに対してリファレンスコード（例えばC言語など低水準の言語を想定）を実装する。このリファレンスコードは、numpyなどの外部ライブラリに依存しない形で実装する。また、動的ネットワーク定義に適したメモリプールの仕組みを実装する。また、Function/Optimizerとは別口でnumpyとのデータコンバート関数を作成する。さらに、上記Function/Optimizerの浮動小数点版リファレンスコードを作成する。
さらにまた、上記Function/Optimizerの固定小数点版リファレンスコードを作成する。
また、Function/Optimizerとは別口で浮動小数点・固定小数点間のデータコンバート関数を作成する。これは、固定小数点版リファレンスコードを作成する理由は、FPUが付いてないチップも少なくないためである。
上記リファレンスコードを元に各種チップ向けに最適化したコードを実装する。
【０１０７】
４−３．ステップIIIについて
図２３は、本発明の実施形態に係る実装手法のステップIIIを説明する模式図である。図２３に示すように、Chainerからネットワーク定義及び重みをバイトコードとして出力するメソッドが追加されている。また、バイトコードを解釈してニューラルネットワークの処理（フォワード処理、バックワード処理、重みの更新）を実行する仮想マシンが設けられる。Native I/Fのチップ向け最適化実装を流用することができる。
【０１０８】
構成１
(Native IFの構成)
図４２は、本発明の一実施形態に係るNative I/Fの構成例を示す図である。
NNアルゴリズム毎に、計算機の種類に非依存のインターフェイスを設ける構成。
NNアルゴリズムを利用する処理系がこのインターフェイスを経由して特定の計算機にアルゴリズムの実行を指示する。
ここでいうインターフェイスとは、入力データの形式と出力データの形式、並びに、入力データの形式の加工方法と出力データの形式の対応を定義する手段。インターフェイスが同一であれば同一の入力に対して同一の出力結果が得られる。例えば、C言語で記載された関数と、その関数宣言が挙げられる。
NNアルゴリズムを利用する側の処理系は、特に限定しない。例えば、NN設計のための既存のフレームワーク（Chainerほか）などがあげられ。また、アルゴリズムの開発と併せて開発される処理系も挙げられる。
ここでいう計算機とは、計算を実行する装置を意味する。計算機は、演算コア、メモリ階層、及び、計算を実行するのに必要なハードウェア資源を含む装置である。
汎用計算機は、一般的に使用される計算機を意味する。Linux（登録商標）OS、及びPythonを含む従来のアルゴリズムが容易に動作する計算機である。
ここでいうアクセラレータとは、NNアルゴリズムの計算を含む特定の計算を高速に実行する装置を意味する。
ここでいうGPUとは、画像処理に特化した計算機だが汎用的計算を実行する能力も持つ計算機である。GPUは、前記アクセラレータの一形態も含む。CUDAなどのソフトウェア資産があるので、NNアルゴリズムを実装する容易さは、汎用計算機の場合と、一般的なアクセラレータの場合の中間程度である。
【０１０９】
構成１-１
（NNによる識別・学習を実行するための構成）
図４３は、本発明の一実施形態に係るNNによる識別・学習を実行するための構成例を示す図である。
Native I/Fは、少なとも、Forward処理部を有する。この構成によって、Native I/Fは、NNアルゴリズムを用いて、識別処理を実行することができる。
更に、Native I/Fは、少なくとも、Forward処理部、Backward処理部、重みの更新アルゴリズムの内部状態初期化処理部、及び重みの更新処理部を有する。かかる構成によって、Native I/Fは、NNアルゴリズムを用いて識別処理及び学習処理を実行することができる。
Forward処理部、及び Backward処理部は、レイヤーアルゴリズム毎に含まれる。重みの更新アルゴリズムの内部状態初期化処理部、及び重みの更新処理部は、重みの更新アルゴリズム毎に含まれる。
更に、Native I/Fは、レイヤーアルゴリズム毎に、Forward処理呼び出しインターフェ
イス、及び、Backward処理呼び出しインターフェイスを、並びに、重みの更新アルゴリズム毎に、重みの更新アルゴリズムの内部状態初期化処理インターフェイス、及び、重みの更新処理呼び出しインターフェイスを、有する。
更に、Native I/Fを通じて呼び出される側の実装は、NativeI/F呼び出し管理部を有する。かかる構成によって、Native I/Fを通じて呼び出される側の実装は、NativeI/Fのパラメータの違いによって、Native I/Fの動作を最適に実行できる実装を変えることができる。因みに、NativeI/Fの動作を実行できる実装が存在しない場合、該Native I/Fの呼び出し管理部は、その呼び出し元にエラーを返す。したがって、Native
I/Fを通じて呼び出される側の実装は、その動作を最適に実行できる実装を選択して実行することができる。
【０１１０】
構成１-１-１
（NNによる識別・学習を実行するための構成１；多次元配列を管理する構成（多次元配列管理部）の場合）
図４４は、本発明の一実施形態に係る多次元配列を管理する構成例を示す図である。
Native I/Fは、更に、多次元配列管理部を有する。該多次元配列管理部は、多次元配列の生成、破棄、属性(軸数、軸毎の要素数)取得、集計結果(軸毎の総和や平均、分散など)取得、及び、多次元配列同士の要素ごとの四則演算、を含む群から選択される少なくとも１つを行うことができる。
【０１１１】
構成１-２
（データを共有するための構成）
【０１１２】
構成１-２-１
（データを共有するための構成１；データ表現変換部の場合）
図４５は、本発明の一実施形態に係るデータ表現変換部の構成例を示す図である。
更に、Native I/Fは、データ表現変換部を有する。該データ表現変換部は、Native I/Fに特定の計算機に依存するデータ表現(デバイス依存データ表現)と、特定の計算機に依存しないデータ表現(デバイス非依存データ表現)を相互に変換することができる。
【０１１３】
構成１-２-２
（データを共有するための構成２；＋外部記憶媒体を有する場合）
更に、Native I/Fを呼び出す側の処理系は、外部記憶媒体を有する。該外部記憶媒体は、デバイス非依存データに変換された重みデータを保存することができる。
【０１１４】
構成１-２-３
（データを共有するための構成３；＋通信部を有する場合）
図４６は、本発明の一実施形態に係る通信部の構成例を示す図である。
更に、Natieve I/Fを通じて呼び出される側の実装は、通信部を有する。該通信部は、呼び出される側の実装にNativeI/Fの呼び出し情報を通信することができる。また、NNアルゴリズムを利用する任意の処理系が、呼び出し情報の通信の有無と関係ないNative I/Fを呼び出そうとするとき、該NativeI/Fを通じて呼び出される側の実装は、必要に応じて最適な通信処理を実行することができる。この工程によって、計算機の物理的な距離、メモリ共有の有無、又は、通信プロトコルの違いを、NNアルゴリズムを利用する任意の処理系から隠蔽することができる。
例えば、呼び出し情報の通信の有無と関係ないNative I/Fは、レイヤーアルゴリズムを実行するためのインターフェイス、重みの更新アルゴリズムを実行するためのインターフェイス、又は、データ表現変換を実行するためのインターフェイスなどがある。
【０１１５】
構成２
（Native I/Fの拡張版の構成）
【０１１６】
構成２-１
（Native I/Fの拡張版の構成１；型変換部、並びに、浮動小数点用のNNアルゴリズム実行部、及び／又は、固定小数点用のNNアルゴリズム実行部を有する場合）
図４７は、本発明の一実施形態に係る浮動小数点及び固定小数点の実行部及び型変換部の構成例を示す図である。
Native I/Fは、型変換部、並びに、浮動小数点用のNNアルゴリズム実行部、及び／又は、固定小数点用のNNアルゴリズム実行部を有する。
例えば、型変換部のみを有する計算機B、浮動小数点用のNNアルゴリズム実行部のみを有する計算機A、又は固定小数点用のNNアルゴリズム実行部のみを有する計算機Cがある。かかる計算機A， 計算機B、及び計算機Cを、Native I/Fの基本構成と組み合わせとき、該計算機Aが生成した浮動小数点型のデータは計算機Bに転送される。引き続き、該計算機Aから該計算機Bに転送されたデータは、該計算機Bによって固定小数点型のデータに変換される。そして、該計算機Bによって変換された固定小数点型のデータは、該計算機Cに転送される。そして、該計算機Bから転送された固定小数点型のデータは、該計算機Cの入力データになり、NNアルゴリズムの全体動作が実行される。かかる工程は逆順に実行することもできる。
【０１１７】
構成２-２
（Native I/Fの拡張版の構成２；メモリプールモジュールを有する場合）
図４８は、本発明の一実施形態に係るメモリプールの構成例を示す図である。
更に、Native I/Fを通じて呼び出される側の実装は、メモリプールモジュールを有する。該メモリプールモジュールは、動的なメモリ管理を実現することができる。
【０１１８】
構成２-３
（Native I/Fの拡張版の構成３；複数のNNアルゴリズムを融合したアルゴリズム実行部を有する場合）
図４９は、本発明の一実施形態に係る複数のNNアルゴリズムを融合したアルゴリズム実行部の構成例を示す図である。
更に、Native I/Fは、複数のNNアルゴリズムを融合したアルゴリズム実行部を有する。該複数のNNアルゴリズムを融合したアルゴリズム実行部は、頻出するNNアルゴリズムの組み合わせに対して、複数のアルゴリズムを同時に実行する。
【０１１９】
構成２-４
（Native I/Fの拡張版の構成４；多次元配列データ圧縮解凍部を有する場合）
図５０は、本発明の一実施形態に係る多次元配列のデータ通信量削減部の構成例を示す図である。
更に、Native I/Fを通じて呼び出される側の実装は、多次元配列データ圧縮解凍部を有する。該多次元配列データ圧縮解凍部は、前記通信部に備わる。
【０１２０】
構成３
（Native I/F＋Chainer実行部の構成）
図５１は、本発明の一実施形態に係る既存実行部との連携例を示す図である。
【０１２１】
構成３-１
（Native I/F＋Chainer実行部の構成１；バイトコード生成部と仮想マシンを有する場合）
図５３は、本発明の一実施形態に係るバイトコード生成部と仮想マシンの構成例を示す図である。
更に、Chainer実行部は、バイトコード生成部を有する。該バイトコード生成部は、Backwardの計算手順と重みを入力し、バイトコードとして出力する。例えば、バイトコード生成部を ChainerのPython層に有する。
また、Native I/Fは、仮想マシンを有する。該仮想マシンは、バイトコードを解釈してNNアルゴリズム処理を実行させる。ここでいうNNアルゴリズム処理とは、フォワード処理、バックワード処理、及び、重みの更新のいずれか、又は、その組み合わせである。
【０１２２】
構成３-２
（Native I/F＋Chainer実行部の構成２；比較部を有する場合）
図５４は、本発明の一実施形態に係る比較部の構成例を示す図である。
更に、Chainer実行部は、比較部を有する。該比較部は、同一のNNアルゴリズムに対応する既存実行部とNative層実行部の入出力結果を比較する、又は、同一のNativeI/Fにおいて異なる実装のNative層実行部を呼びだすNative層実行部同士の入出力結果を比較する。
【０１２３】
構成３-３
（Native I/F＋Chainer実行部の構成３；関数合成部を有する場合）
図５５は、本発明の一実施形態に係る関数合成部の構成例を示す図である。
更に、Chainer実行部は、関数合成部を有する。該関数合成部は、Backwardの計算手順を入力し、「複数のアルゴリズムを同時に実行するNative I/F」が対応可能なFunctionクラスのインスタンスの組み合わせを、「複数のアルゴリズムを同時に実行するNative I/F」に対応したFunctionクラスのインスタンスに置換する。しかし、Backwardの計算手順を実行する計算機のためのNative層の実装において、「複数のアルゴリズムを同時に実行するNative I/F」が存在しない場合は、上記の置換はしない。
ここでいう置換は、Backwardの計算手順を文字列として見立てた場合、部分一致検索により実行することができる。
例えば、該関数合成部は、ChainerのPython層に備わる。
【０１２４】
構成４
（Forward処理実行を特化させる最適化装置の構成）
【０１２５】
構成４-１
（Forward処理実行を特化させた最適化装置の構成１；重みの最適化処理手段を有する場合）
更に、Chainer実行部は、重みの最適化処理手段を有する。該重みの最適化処理手段は、Functionクラスに適した重みの最適化処理を実行する。
【０１２６】
構成４-２
（Forward処理実行を特化させた最適化装置の構成２；データメモリ領域の再利用手段を有する場合）
更に、Chainer実行部、並びにNative I/Fは、データメモリ領域の再利用手段を有する。該データメモリ領域の再利用手段は、レイヤー間で入出力されるデータのメモリ領域を再利用する。該再利用手段は、Forward処理実行部、又は、前記仮想マシンに備わる。
例えば、仮想マシンのForward処理を実行するインターフェイス(NativeI/Fにて定義されるもの)の引数にForward処理のみの実行であることを識別するためのフラグを設ける。
この処理を実行する条件は、ChainerのFunctionクラスのインスタンスが入力するVariable変数にvolatile属性が指定されているとき、又は、仮想マシンのForward処理が実行される際にForward処理のみの実行であることを識別するためのフラグが有効となっているとき、である。
【０１２７】
作用１
（NativeIFの構成による作用）
NNのアルゴリズムを設計・利用する開発者と、計算機のハードウェア構成を深く意識する開発者の分業が容易となる。
例えば、アルゴリズムを設計・利用する開発者は、実行したいNNアルゴリズム毎のインターフェイスの同一性がNative I/Fにより保証されるので、Native I/Fを呼び出す側のソフトウェアを変更することなく様々な計算機で処理を実行することができる。
具体的には、特定の計算機に自ら開発しているソフトウェアが依存してしまうリスクを下げることができる。その結果、計算機の価格や特定用途での弱み強みといったより本質的な基準で計算機を選別することができるようになる。
計算機のハードウェア構成を深く意識する開発者にとっては、 Native I/Fに対応した計算機に最適化な実装を提供すれば、幅広いNNアルゴリズムの利用者に対して自ら開発した計算機を利用してもらえる。
【０１２８】
作用１-１
（NNによる識別・学習を実行するための構成による作用）
NNのアルゴリズムを設計・利用する開発者は、NNアルゴリズムを利用する任意の処理系を用いて、NativeI/Fに具備されているインターフェイスを呼び出すことにより、NNのアルゴリズム全体動作を実現することができる。
また、NNのアルゴリズムを設計・利用する開発者は、計算機の具体的な構成を意識せずとも利用している計算機に最適な実装を用いて、NNのアルゴリズム全体動作を実現することができる。
【０１２９】
作用１-１-１
（NNによる識別・学習を実行するための構成１による作用；多次元配列を管理する構成（多次元配列管理部）の場合）
NNのアルゴリズムを設計・利用する開発者は、NNアルゴリズムの全体動作を実行するとき、余計なデータ変換処理を経ることなく任意のNNアルゴリズムを組み合わせて実行することができる。
このとき、任意のNNアルゴリズムの処理結果である多次元配列の内容の集計結果を確認することにより、NNアルゴリズムが意図した通りの計算を実行できているかどうかを確認することができる。
【０１３０】
作用１-２
（データを共有するための構成による作用）
作用１-２-１
（データを共有するための構成１による作用；データ表現変換部の場合）
デバイス非依存データ表現を経由することで、異なるハードウェア構成の計算機の間でNNのアルゴリズム全体動作を実現するのに必要なデータを交換することができる。
【０１３１】
作用１-２-２
計算機毎に固有の情報を隠すことができる。
（データを共有するための構成２；＋外部記憶媒体を有する場合）
重みのデータをデバイス非依存データ表現に変換した後、外部記憶媒体に保存することによって、特定の計算機を用いて学習済みの重みを用いて、任意の計算機上で識別処理を実行することができる。
【０１３２】
作用１-２-３
（データを共有するための構成３による作用；＋通信部を有する場合）
計算機のハードウェア構成や、物理的な距離、メモリ共有の有無に関わらず、NNのアルゴリズム全体動作を実現するのに必要なデータを交換することができる。
NNアルゴリズムを利用する側の処理系が動作可能な計算機から、NNアルゴリズムを利用する側の処理系が動作不能な計算機に実装されたNNアルゴリズム実装を呼び出すこともできる。
したがって、コンピュータネットワークに繋がれた複数台の計算機を用いてNNのアルゴリズム全体動作を実現することができる。
【０１３３】
作用２
（Native I/Fの拡張版の構成による作用）
【０１３４】
作用２-１
（Native I/Fの拡張版の構成１による作用；型変換部、並びに、浮動小数点用のNNアルゴリズム実行部、及び／又は、固定小数点用のNNアルゴリズム実行部を有する場合）
浮動小数点演算器（FPU）を持たない計算機と、FPUを持つ計算機が混在するハードウェア構成において、それぞれの計算機に適したデータ型を用いて、NNのアルゴリズム全体動作を実現することができる。
浮動小数点演算、又は、固定小数点演算を用いて、NNのアルゴリズム全体動作を実現できる。
具体的には、計算機Aは、計算機Aの浮動小数点用のNNアルゴリズム実行部が生成した浮動小数点型データを計算機Bに転送する。次に、計算機Bは、計算機Aから転送された当該浮動小数点型データを型変換部により固定小数点型データに変換した後、当該固定小数点型データを計算機Cに転送する。
計算機Cは、計算機Cの固定小数点用のNNアルゴリズム実行部が生成した固定小数点型データを計算機Bに転送する。次に、計算機Bは、計算機Cから転送された当該固定小数点型データを型変換部により浮動小数点型データに変換した後、当該浮動小数点型データを計算機Aに転送する。
【０１３５】
作用２-２
（Native I/Fの拡張版の構成２による作用；メモリプールモジュールを有する場合）
動的なメモリ管理の仕組みに依存した処理系が、データの生成と破棄を含むNativeI/Fを呼び出しNNアルゴリズム全体動作を実行するとき、その動作を軽量に実現することができる。
【０１３６】
作用２-３
（Native I/Fの拡張版の構成３による作用；複数のNNアルゴリズムを融合したアルゴリズム実行部を有する場合）
グローバルなメモリへの不要なアクセスを回避することができる。また、関数呼び出しのオーバーヘッドを削減できる。したがって、頻出するNNアルゴリズムの組み合わせを高速に実行することができる。
【０１３７】
作用２-４
（Native I/Fの拡張版の構成４による作用；多次元配列データ圧縮解凍部を有する場合）
コンピュータネットワークに繋がれた複数台の計算機を用いてNNのアルゴリズム全体動作を実行させるとき、多次元配列のデータ通信量を削減することができる。したがって、動作速度を向上させることができる。
【０１３８】
作用３
（Native I/F＋Chainer実行部による作用）
NativeI/FのサポートがあるNNのアルゴリズムと、NativeI/FのサポートのないNNのアルゴリズムとを組み合わせて、NNの全体動作を定義及び実行することができる。
NativeI/Fのサポートを得ることができ次第、適宜NativeI/Fに置き換えることによって、NN全体動作を実行することができる。したがって、既存のソフトウェアの修正が不要になる。
NativeI/Fを組み合わせる場合も、Define-by-runの既存のメリットを享受することができる。
【０１３９】
作用３-１
（Native I/F＋Chainer実行部の構成１による作用；バイトコード生成部と仮想マシンを有する場合）
Chainer実行部がバイトコード生成部を有し、NativeI/Fが仮想マシンを有することによって、高度なライブラリやプログラミング言語への依存度を減少させることができる。よって、アクセラレータなどの貧弱な実行環境を含む様々な計算機においても、製品レベルの要件を満たしつつ、Chainerで設計したNNの全体動作を実行することができる。
【０１４０】
作用３-２
（Native I/F＋Chainer実行部の構成２による作用；比較部を有する場合）
比較部は、同一のNNアルゴリズムに対応する既存実行部とNative層実行部の入出力結果を比較する、並びに、同一のNativeI/Fにおいて異なる実装のNative層を呼びだすNative層実行部同士の入出力結果を比較する。
かかる比較部を有することによって、浮動小数点用のNNアルゴリズム実行部の処理結果の精度と、固定小数点用のNNアルゴリズム実行部の処理結果の精度を比較することができる。したがって、NNのアルゴリズムが正しく計算できることが既に十分テストされた実行部の処理結果と、新規に作成するNative層の処理結果とを比較することができる。故に、新規に作成するNative層の実装がNNのアルゴリズムを正しく計算することが可能であることを保証することができる。
【０１４１】
作用３-３
（Native I/F＋Chainer実行部の構成３による作用；関数合成部を有する場合）
関数合成部は、Backwardの計算手順を入力し、「複数のアルゴリズムを同時に実行するNative I/F」が対応可能なFunctionクラスのインスタンスの組み合わせを、当該「複数のアルゴリズムを同時に実行するNative I/F」に1:1対応したFunctionクラスのインスタンスに置換する。尚、当該「複数のアルゴリズムを同時に実行するNative I/F」が存在しない場合、かかる関数合成部は、上記の置換を実行しない。
かかる関数合成部をChainerのPython層の構成に有することによって、「複数のアルゴリズムを同時に実行するNative I/F」の有無に関わらず、Backwardの計算手順が自動的に加工される。かかるBackwarodの計算手順の加工によって、「複数のアルゴリズムを同時に実行するNative I/F」が存在する場合は、当該Native I/Fが呼び出され、対応したFunctionクラスのインスタンスに置換される。これによって、高速なNNのアルゴリズム全体動作を常に実現することができる。
また、「複数のアルゴリズムを同時に実行するNative I/F」が存在しないような関数の組み合わせであっても、関数合成部がメリットを発揮する場合もある。具体的には、Forward処理に限定した場合のConvolution2D+BatchNormalizationの組み合わせや、Linear+BatchNormalizationの組み合わせである。
BatchNormalizationは、その入力となる多次元配列の一つ一つの要素に対して、NNの学習を通じた長期的な統計情報に基づいて、要素間の分散を揃え、平均をとり除く処理である。学習するのではなくForward処理のみを行う場合であれば、分散や平均を更新する必要はなく、例えばaとbを定数とすればy=ax+bのような変換を配列要素ごとに行う処理に過ぎない。Linear処理は行列積を行う処理である。また、Convolution2Dは畳み込みと行列積の組み合わせの計算を行う処理である。これらの処理は先に例示したy=ax+bのような変換を内包しているので、LinearやConvolution2Dの重みやバイアスを調整することで、これらのFunctionの出力結果をBatchNormalizationへ入力し処理するのと同じ結果を得ることができる。
関数合成部はこうした重みやバイアスの調整を行うことで、Convolution2D+BatchNormalizationを単独のConvolution2Dに変換することができる。Linear+BatchNormalizationから単独のLinearへの変換も同様である。
【０１４２】
作用４
（Forward処理実行に特化した最適化装置の構成による作用）
Forward処理における重みの情報量、あるいは入力データのデータメモリ量を削減してForward処理を実行することによって、メモリを削減することができる。また、重みの要素数を削減したり０の重みを計算しないでFoward処理を実行することによって、計算量を削減することができる。
【０１４３】
作用４-１
（Forward処理実行を特化させた最適化装置１による作用；重みの最適化処理手段を有する場合）
Forward処理実行に特化した重みの最適化処理手段を、ChainerのFunctionクラスに有することによって、学習済みのネットワークの構成に含まれる任意のFunctionクラスのインスタンスに対して、重みの最適化処理を実行することができる。このように、重みの最適化処理を実行することができることで、Forward処理の際のメモリや計算量を削減することができる。これによって、NNのアルゴリズム全体動作を高速に実行することができる。
【０１４４】
作用４-２
（Forward処理実行を特化させた最適化装置２による作用；データメモリ領域の再利用手段を有する場合）
Forward処理のみを実行するフラグを、Forward処理の実行部(Chainer、又は、仮想マシン）に引数として与えることによって、Forward処理の際のメモリを削減することができる。これによって、NNのアルゴリズム全体動作を高速に実行することができる。
【０１４５】
５．実施形態に係る実装手法の具体的な手順について
実施形態に係る実装手法は、第１の手法及び第２の手法を含む。
５−１．第１の手法について
図２４は、本発明の一実施形態に係る実装手法（第１の手法）に用いられる実装装置の構成例を示す模式図である。図２４に示すように、一実施形態に係る実装装置は、主に、評価ボード（マザーボード）１００と、評価ボード１００に着脱自在に搭載された組み込み系チップ（組み込み系半導体集積回路）２００と、を含む。
【０１４６】
評価ボード１００は、主に、ＣＰＵ１０１と、メインメモリ１０２と、通信Ｉ／Ｆ１０３と、外部メモリ１０４と、を含む。これらの各構成要素が内部バス１０９を介して電気的に接続されている。
【０１４７】
ＣＰＵ１０１は、外部メモリ１０３からオペレーティングシステム等の様々なプログラムをメインメモリ１０２にロードし、ロードしたプログラムに含まれる命令を実行する。メインメモリ１０２は、ＣＰＵ１０１が実行するプログラムを格納するために用いられ、例えば、ＤＲＡＭによって構成される。
【０１４８】
通信Ｉ／Ｆ１０３は、ハードウェア、ファームウェア、又は、ＴＣＰ／ＩＰドライバやＰＰＰドライバ等の通信用ソフトウェア又はこれらの組み合わせとして実装され、イーサネット（登録商標）やインターネット等を含む通信網（図示しない）を介して、開発者等により操作される図示しない計算機及び入出力装置等と通信することが可能となるように構成される。また、通信Ｉ／Ｆ１０３は、組み込み系チップ２００の後述する通信Ｉ／Ｆ２０４と通信することも可能である。外部メモリ１０４は、例えばフラッシュメモリ等により構成され、オペレーティングシステム等の様々なプログラムを記憶する。
【０１４９】
次に、組み込み系チップ２００は、ＣＰＵ２０１と、アクセラレータ（補助演算装置）２０２と、メインメモリ２０３と、通信Ｉ／Ｆ２０４と、外部メモリ２０５と、を含む。これらの各構成要素が内部バス２０９を介して電気的に接続されている。なお、組み込み系チップは、選択的に、ＧＰＵ（図示せず）を含むことも可能である。
【０１５０】
ＣＰＵ２０１は、評価ボード１００（の通信Ｉ／Ｆ１０３）から通信Ｉ／Ｆ２０４を介して受信したソースコード（例えばPython等で記述されたソースコード）をメインメモリ２０３にロードし、ロードしたソースコードに含まれる各コードを実行する。
アクセラレータ２０２は、評価ボード１００（の通信Ｉ／Ｆ１０３）から通信Ｉ／Ｆ２０４を介して受信したソースコード（例えばC言語やアセンブラ等）で記述されたソースコード）をメインメモリ２０３にロードし、ロードしたソースコードに含まれる各コードを実行する。メインメモリ２０３は、ＣＰＵ２０１及びアクセラレータ２０２が実行するソースコードを格納するために用いられ、例えば、ＤＲＡＭによって構成される。
【０１５１】
通信Ｉ／Ｆ２０４は、評価ボード１００の通信Ｉ／Ｆ１０３と通信して様々な情報を送受信する。外部メモリ２０５は、例えばフラッシュメモリ等により構成され、様々なデータを記憶する。
【０１５２】
図２５は、本発明の一実施形態に係る実装手法に用いられる手順の一例を示すフロー図である。
まず、ステップ３０１において、第１のプログラミング言語（例えばPython等）で記述されたソースコードをパーソナルコンピュータ等において実行させる。開発者等は、当該実行結果に基づいて、当該ソースコードがパーソナルコンピュータ等において動作するか否かを確認する。ここでいうパーソナルコンピュータ等とは、豊富な計算資源を有する計算機をいい、例えば、上記第１部において説明した実施形態に係る学習装置を含むものである。このステップ３０１においてソースコードがパーソナルコンピュータ等において動作する状態とは、上記「４−１」において説明したステップIと同一の状態である。
【０１５３】
ステップ３０２において、上記ステップ３０１においてパーソナルコンピュータ等において動作するものであることを確認したPython等で記述されたソースコードを、評価ボード１００を用いて組み込み系チップ２００のＣＰＵ２０１に実行させる。開発者等は、当該実行結果に基づいて、このソースコードがＣＰＵ２０１により動作可能なものであるか否かを確認する。なお、このような動作は、評価ボード１００のＣＰＵ１０１が外部メモリ１０４に記憶された所定のプログラムをロードして実行することによって実現されるものとすることができる。ここで、Python等で記述されたソースコードは、評価ボード１００の通信Ｉ／Ｆ１０３及び組み込み系チップ２００の通信Ｉ／Ｆ２０４を介してＣＰＵ２０１に渡されるものとすることができる。このソースコードがＣＰＵ２０１により動作可能なものでないことが判明した場合には、開発者等は、このソースコードを修正して、ステップ３０２を繰り返す。このソースコードがＣＰＵ２０１により動作可能なものであることを確認した場合には、開発者等は、次のステップ３０３に移行する。
【０１５４】
ステップ３０３において、開発者等は、上記ステップ３０２においてＣＰＵ２０１により動作可能なものであると確認されたソースコード（の少なくとも一部）をアクセラレータ２０２で動作させるために第２のプログラミング言語（例えばＣ言語やアセンブラ）で書き換える。
【０１５５】
ステップ３０４において、上記ステップ３０３においてＣ言語等で書き換えたソースコードを、評価ボード１００を用いて組み込み系チップ２００のアクセラレータ２０２に実行させる。開発者等は、当該実行結果に基づいて、この書き換えられたソースコードがアクセラレータ２０２により動作可能なものであるか否かを確認する。このような動作は、評価ボード１００のＣＰＵ１０１が外部メモリ１０４に記憶された所定のプログラムをロードして実行することによって実現されるものとすることができる。ここで、Ｃ言語等で記述されたソースコードは、評価ボード１００の通信Ｉ／Ｆ１０３及び組み込み系チップ２００の通信Ｉ／Ｆ２０４を介してアクセラレータ２０２に渡されるものとすることができる。このソースコードがアクセラレータ２０２により動作可能なものでないことが判明した場合には、開発者等は、このソースコードを修正して、ステップ３０４を繰り返す。このソースコードがアクセラレータ２０２により動作可能なものであることを確認した場合には、開発者等は、次のステップ３０５に移行する。
【０１５６】
ステップ３０５において、評価ボード１００において、ＣＰＵ２０１がPython等で記述されたソースコードにおける第１の特定コード（検証対象のコード）を実行した結果と、アクセラレータ２０２がＣ言語等で記述されたソースコードにおける第２の特定コードであって第１の特定コードがPython等からＣ言語等に書き換えられた第２の特定コードを実行した結果とを（例えば組み込み系チップ２００により実行されるユニットテストと称されるモジュールを用いて）比較させて、比較結果を出力させる。開発者等は、当該比較結果に基づいて、両方の実行結果において同一の入力に対して同一の出力が得られているかを検証する。このような動作は、評価ボード１００のＣＰＵ１０１が外部メモリ１０４に記憶された所定のプログラムをロードして実行することによって実現されるものとすることができる。この検証が完了するまで、開発者等は、上述したステップ３０３〜３０５を繰り返す。この検証が完了した場合には、開発者等は、次のステップ３０６に移行する。
【０１５７】
ステップ３０６において、開発者等は、ステップ３０５において、Ｃ言語等で記述されたソースコードがアクセラレータ２０２によりさらに高速に動作するように、このソースコードをチューニングする。
【０１５８】
ステップ３０７において、評価ボード１００において、ＣＰＵ２０１がPython等で記述されたソースコードを実行した結果と、アクセラレータ２０２が上記ステップ３０６においてチューニングされたＣ言語等で記述されたソースコードを実行した結果とを（例えば組み込み系チップ２００により実行されるユニットテストと称されるモジュールを用いて）を比較させて、比較結果を出力させる。開発者等は、当該比較結果に基づいて、両方の実行結果において同一の入力に対して同一の出力が得られているかを検証する。このような動作は、評価ボード１００のＣＰＵ１０１が外部メモリ１０４に記憶された所定のプログラムをロードして実行することによって実現されるものとすることができる。この検証が完了するまで、開発者等は、上述したステップ３０６及びステップ３０７を繰り返す。この検証が完了した場合には、開発者等は、次のステップ３０８に移行する。
【０１５９】
ステップ３０７が完了した状態では、組み込み系チップ２００は、Python等及びＣ言語等の２つのソースコードによって動作する状態にある。この状態について、図２６を参照して説明する。図２６は、本発明の一実施形態に係る実装手法における組み込み系チップの動作状態を示す模式図である。
【０１６０】
図２６に示すように、上記ステップ３０１（これはステップIに相当する）では、関数の呼出し側（すなわち、関数を呼び出す主体）は、Python等により記述されており、被呼出し側（すなわち、呼び出される関数）もまた、Python等により記述されている。
次に、上記ステップ３０２〜３０７では、関数の呼出し側は、依然としてPython等により記述されており、被呼出し側は、Python等により記述されたものとＣ言語等により記述されたものとが混在した状態となっている。すなわち、ステップ３０７が完了した状態では、組み込み系チップ２００は、Python等及びＣ言語等の２つのソースコードによって動作する状態にある。
【０１６１】
本実施形態に係る実装手法が最終的に目的とするのは、図２６の右端に示すように、呼出し側、及び、被呼出し側の両方がともにＣ言語等により記述された状態、すなわち、組み込み系チップ２００がＣ言語等に記述されたソースコードのみによって動作する状態である。
【０１６２】
そこで、図２５に戻り、ステップ３０８では、開発者等は、組み込み系チップ２００がＣ言語等で記述されたソースコードのみによって動作するように、Pythonで記述されたソースコードであってまだＣ言語等に書き換えられていない部分をすべてＣ言語等に書き換える。このステップ３０８では、組み込み系チップ２００がPythonから切り離されることになる。このようにして生成されたＣ言語等により記述されたソースコードは、組み込み系チップ２００の外部メモリ２０５等に記憶される。これにより、組み込み系チップ２００は、外部メモリ２０５等に記憶されたソースコードを読み出してアクセラレータ２０２に実行させ、機械学習を実行することができるようになる。この状態は、実施形態に係る実装手法が目標とする状態であって、上記「１」及び「２」において述べた課題が解決されている状態である。
【０１６３】
５−２．第２の手法について
図２７は、本発明の一実施形態に係る実装手法（第２の手法）に用いられる実装装置の構成例を示す模式図である。第２の手法において用いられる実装装置（図２７）が、第１の手法において用いられる実装装置（図２４）と異なるのは、組み込み系チップ２００がＣＰＵを備えない点である。第２の手法では、第１の手法で組み込み系チップ２００のＣＰＵ２０１が担っていた動作は、外部に設けられた図示しない計算機（パーソナルコンピュータ等）に設けられたＣＰＵによりなされる。例えば、ここでいう計算機（パーソナルコンピュータ等）は、上記第１部において説明した学習装置（図１１に例示したパーソナルコンピュータ等）であってもよい。
【０１６４】
第２の手法で行われる実装方法では、図２５を参照して説明した実装方法について、ステップ３０２、３０５及び３０７において組み込み系チップ２００のＣＰＵ２０１で実行された動作を、上記外部に設けられた計算機（図示せず）に設けられたＣＰＵにおいて行うように変更される。これを実現するために、図２７に示した評価ボード１００は、例えば通信Ｉ／Ｆ１０３を介して、上記外部に設けられた計算機（図示せず）と通信可能に接続されることにより、この計算機に設けられたＣＰＵにPythonで記述されたソースコードを実行させ、その実行結果を受信することができるものであってもよい。
【０１６５】
６．実装装置の構成
次に、上述した実施形態に係る実装装置１００が上記「５」において説明した手法を実現するために必要な構成について説明する。
【０１６６】
６-１．本発明を構成を説明するための用語定義
（クラスとモジュールの違い）
モジュールは特定の目的を実現するために定義・実装された手続きとデータの集合 (特定のプログラミング言語による支援の有無とは無関係の概念)
クラスはPythonなどのオブジェクト指向言語の支援を用いて定義・実装されたモジュール
【０１６７】
（Python層とNative層）
Native層とは、Native I/Fとそこから呼び出される実装(ソフト及びハード)の階層をいう。Python層とは、Python言語上で実行されることが想定されるソフトウェア階層をいう。現状ChainerはPython言語で記述されているが、将来Chainerが別のプログラミング言語に移植されることも考えられる。ここでPython層として説明する機能は必ずしもPython言語に特化することを意味するわけではない。Python層及びNative層の役割分担として、Python層はよりアルゴリズム設計に適した抽象化レベルの高い開発環境を想定し、Native層はよりハードウェア構成を具体的に意識する抽象化レベルの低い開発環境を想定する。
【０１６８】
（計算機と実行部の対応）
図５２は、本発明の一実施形態に係る既存実行部との連携例を示す図である。
実行部とはニューラルネットのアルゴリズムを実際に計算するためのFunction/Optimizerクラスのメソッドである。
既存実行部とは汎用計算機実行部もしくはGPU実行部もしくはその両方である。汎用計算機実行部は、汎用計算機を用いてNNのアルゴリズムを計算する。GPU実行部はGPUを用いてNNのアルゴリズムを計算する。
Native実行部は、Native層の実装を用いてNNのアルゴリズムを計算する。Native層は計算機の種類毎に実装するので、全ての計算機の種別(汎用計算機、GPU、アクセラレータ)についてNativeI/Fを通じて動作可能である。
【０１６９】
６−２．実装部の構成
図２８は、本発明の一実施形態に係る実装装置が有する機能を概念的に示す模式図である。図２８に示すように、実装部４００は、主に、駆動部４０１と、Functionクラス／Optimizerクラス４０２と、汎用計算機実行部４０３と、GPU実行部４０４と、Native層実行部４０５と、汎用計算機用多次元配列４０６と、GPU用多次元配列４０７と、Native用多次元配列４０８と、Variableクラス４０９と、を含む。
【０１７０】
駆動部４０１は、主に、あるアルゴリズム（関数）の実行をFunctionクラス／Optimizerクラス４０２に命令する実行部と、そのアルゴリズム（関数）についての汎用計算機実行部４０３による実行結果（又はGPU実行部４０４による実行結果）とNative層実行部４０５による実行結果とを例えばユニットテストと称されるモジュール等を用いて比較し、その比較結果を出力する比較部と、を含む。
【０１７１】
Functionクラス／Optimizerクラス４０２は、駆動部４０１から命令されたアルゴリズム（関数）を汎用計算機実行部４０３、GPU実行部４０４及びNative層実行部４０５のうちの少なくとも１つに実行させる。
【０１７２】
汎用計算機実行部４０３は、Functionクラス／Optimizerクラス４０２から命令されたアルゴリズム（関数）に対応する多次元配列を汎用計算機用多次元配列４０６から取得してそのアルゴリズム（関数）をＣＰＵを用いて実行する。その実行結果は、Functionクラス／Optimizerクラス４０２を介して駆動部４０１に戻される。
【０１７３】
GPU実行部４０４は、Functionクラス／Optimizerクラス４０２から命令されたアルゴリズム（関数）に対応する多次元配列をGPU用多次元配列４０７から取得してそのアルゴリズム（関数）をGPUを用いて実行する。その実行結果は、Functionクラス／Optimizerクラス４０２を介して駆動部４０１に戻される。
【０１７４】
Native層実行部４０５は、Functionクラス／Optimizerクラス４０２から命令されたアルゴリズム（関数）に対応する多次元配列をNative用多次元配列４０８から取得してそのアルゴリズム（関数）をアクセラレータを用いて実行する。その実行結果は、Functionクラス／Optimizerクラス４０２を介して駆動部４０１に戻される。
【０１７５】
Variableクラス４０９は、汎用計算機用多次元配列４０６、GPU用多次元配列４０７及びNative用多次元配列４０８により用いられるすべての多次元用配列を保持しており、汎用計算機用多次元配列４０６、GPU用多次元配列４０７及びNative用多次元配列４０８に対して対応する多次元用配列を供給する。
【０１７６】
なお、実装手法として、上記「５−１」で述べた第１の手法が採用される場合には、図２８に示されたすべての構成要素が組み込み系チップ２００（図２４参照）に配置される。この場合、汎用計算機実行部４０３は、組み込み系チップ２００に搭載されたCPU２０１を用いてアルゴリズム（関数）を実行し、GPU実行部４０４は、組み込み系チップ２００に搭載されたGPU（図示せず）を用いてアルゴリズム（関数）を実行し、Native層実行部４０５は、主として組み込み系チップ２００に搭載されたアクセラレータ２０２を用いてアルゴリズム（関数）を実行する。
【０１７７】
一方、実装手法として、上記「５−２」で述べた第２の手法が採用される場合には、図２８に示された構成要素のうち、Functionクラス／Optimizerクラス４０２、汎用計算機実行部４０３、GPU実行部４０４、汎用計算機用多次元配列４０６、GPU用多次元配列４０７及びVariableクラス４０９が、外部に設けられた計算機（パーソナルコンピュータ等）に配置される。この場合、Native層の実装は、組み込み系チップ２００にも依然として配置されている。さらに、この場合、汎用計算機実行部４０３は、上記外部に設けられた計算機のCPUを用いてアルゴリズム（関数）を実行し、GPU実行部４０４は、上記外部に設けられた計算機のGPUを用いてアルゴリズム（関数）を実行する。
【０１７８】
６−３．Native層実行部の構成
次に、上述したNative層実行部４０５の構成について説明する。図２９は、本発明の一実施形態に係る実装装置に含まれるNative層実行部の構成例を示す模式図である。
図２９に示すように、Native層実行部４０５は、Python層において、主に、NativeDeviceクラス５０１と、NativeArrayクラス５０２と、Functionクラス／Optimizerクラス５０３と、バイトコード生成部５０４と、を含む。なお、図２９に記載されたFunctionクラス／Optimizerクラス５０３と図２８に記載されたFunctionクラス／Optimizerクラス４０２とは同一の構成要素であり、図２９に記載されたNativeArrayクラス５０２と図２８に記載されたNative用多次元配列４０８とは同一の構成要素である。
さらに、Native層実行部４０５は、Native層において、主に、デバイス管理モジュール５０５と、データ変換モジュール５０６と、多次元配列モジュール５０７と、Functionモジュール／Optimizerモジュール５０８と、仮想マシンモジュール５０９と、メモリプールモジュール５１０と、を含む。
【０１７９】
NativeDeviceクラス５０２は、Native層のデバイス管理モジュールをPython層でラップするとともにNative層への関数呼び出しやデータ入出力を隠蔽する。NativeArrayクラス５０２は、Native層の多次元配列をPython層でラップする。Functionクラス／Optimizerクラス５０３のうち、Functionクラスは、Native層のFunctionモジュールをPython層でラップし、Optimizerクラスは、Native層のOptimizerモジュールをPython層でラップする。ここで、Functionクラス及びOptimizerクラスは、Chainerにおいて実装済みであり、汎用計算機とGPUによる実行の違いを隠蔽する機能を有する。この機能を拡張することでNative層での実行も隠蔽できる。
バイトコード生成部は、バイトコードを生成する。
なお、図２９に例示した各構成要件の詳細については後述する。
【０１８０】
７．実施形態に係る実装装置の効果
ディープラーニングは研究開発が盛んな発展途上の技術であるので、組み込み系チップ向けの開発期間中に従来よりも優れた性能を持つ新規のレイヤーアルゴリズムが発明され、こうした新規のアルゴリズムを開発中のソフトウェア、あるいはハードウェア実装に取り込む需要が発生することが想定される。
新規のレイヤーアルゴリズムを含むニューラルネットワークの構成を組み込み環境で製品レベルの仕様を満たした上で動作する状態を実現するためには以下のような開発ステップを踏む必要がある。
１．GPUなど潤沢な計算資源を得られる環境でアルゴリズムの実装と検証を行う。
２．１で実装検証したアルゴリズムを組み込みチップで既に最適化実装が終わったニューラルネットワークのモジュールと結合し動作検証を行う。その結果に応じて該当チップ向けに特化した最適化を１で実装検証したアルゴリズムに適応する。
３．２の作業完了後、該当チップ向けに最適化されたニューラルネットの実装のみを用いて、これ以外のモジュール(センサーやモータの制御系など)とも結合した上で製品レベルの仕様を満たしているか否かを様々な試験項目により検証する。
【０１８１】
実施形態に係る実装装置は、Python上でニューラルネットワークのアルゴリズムを動作させるとき、汎用計算機上で動作するPython言語を用いた実行部と、GPUを用いた実行部と、特定チップ向けの最適化実装を用いた実行部とをレイヤーごとに呼び分ける構成を有し、バイトコードを経由することでこの特定チップ向けの最適化実装のみを用いてニューラルネットワークのアルゴリズム全体を動作させる構成を有する。
前段落で説明したステップ１、２間で１のステップで作成したアルゴリズム実装コードを２のために流用でき、ステップ１、２間の動作結果の違いも容易に比較検討できる。さらに、ステップ２、３間では、ステップ２のために作成した最適化実装をステップ３のために流用でき、逆にステップ３で見つかった最適化実装に関する不具合修正もステップ２のために流用することができる。その結果、新規のレイヤーアルゴリズムを含むニューラルネットの構成を組み込み環境で製品レベルの仕様を満たした上で動作する状態を最小の開発コストで実現できる。
【０１８２】
用語の定義
本発明の実施形態を詳細説明する上で以下の用語を定義する。
「全体動作」とは、フォワード処理単独、又は、フォワード処理、バックワード処理及び重みの更新処理を繰り返して実行するような処理単位を表す。この全体動作は、典型的なニューラルネットワークの学習及び識別の実施形態として想定されるものである。
【０１８３】
８．Native層
次に、図２９に例示した実施形態に係る実装装置のNative層に関する構成について説明する。
８−１．デバイス管理モジュール
デバイス管理モジュール５０５は、デバイス（最適化実装に依存するソフトウェア及びハードウェア状態)の初期化と解放処理を行う。具体的には、デバイス管理モジュール５０５内で行う処理は、デバイスの形態次第で異なるが、典型的な処理内容として例えば後述するメモリプールの確保や解放を行う。デバイスは、Chainer及びPythonを実行する汎用計算機と同一チップや、同一基板上に存在する必要はない。別基板にあるデバイスと通信し初期化・解放するような最適化実装も可能である。
【０１８４】
デバイスを初期化又は解放する関数の定義例を以下に示す。
（例１）Device* chnr_init_device(void)
これによりデバイスを初期化することができる。
（例２）void chnr_release_device(Device* device)
これによりデバイスを解放することができる。
【０１８５】
８−２．Functionモジュール
Functionモジュール５０８は、ニューラルネットワークのレイヤーごとの計算を行う関数群であり、レイヤーの種類別に以下の関数を定義する。
chnr_forward_xxxx(…)
−フォワード処理(浮動小数点版)を実装
chnr_backward_xxxx(…)
−バクワード処理(浮動小数点版)を実装
chnr_forward_xxxx_fx(…)
−フォワード処理(固定小数点版)を実装
chnr_backward_xxxx_fx(…)
−バックワード処理(固定小数点版)を実装
ここで、xxxxはレイヤーの種類別に付与される名称を表す。
各関数での具体的な処理内容は、上記第１部の上記「２−６」〜「２−１２」において例示したものを含む。
【０１８６】
８−３．多次元配列（MDArray）モジュール
多次元配列モジュール５０７は、Native層のFunctionの間で入出力される多次元配列を管理する。多次元配列モジュール５０７は、任意のサイズ・次元数を管理できる。また、多次元配列モジュール５０７は、後述するように、Numpy(Chainerが依存しているpython層の多次元配列クラス)やGPU向け多次元配列ライブラリとの相互変換の仕組みを有する。
さらにまた、この多次元配列モジュール５０７は、浮動小数点型だけではなく固定小数点型も保持できる。これにより、FPU(浮動小数点演算ユニット)を持たないハードウェアでもニューラルネットの計算を容易に実現できる。また、この多次元配列モジュール５０７は、浮動小数点の多次元配列との相互変換の関数を有する。
【０１８７】
多次元配列モジュール５０７の実装例について説明する。
本発明の一実施形態に係る実装装置の多次元配列モジュールの構造体定義例が図３０に示されている。
次に、関数定義例は以下のとおりである。
（例１）MDArray chnr_create_md_array(dimensions[], numaxis, type)
これにより、多次元配列を生成・初期化することができる。
（例２）void chnr_delete_md_array(MDArray* mdrray)
これにより、多次元配列を削除することができる。
（例３）void chnr_md_array_add(MDArray* dst, MDArray* a, MDArray* b)
これにより、多次元配列の要素同士の加算を行うことができる。
【０１８８】
次に、多次元配列モジュール５０７の多次元配列のメモリ管理について説明する。
多次元配列の実体を格納するメモリ領域の管理(生成・破棄)はNative層で実現する。組み込み環境の場合、Linux（登録商標） OSなどが標準提供するメモリ管理機構(malloc/free)では管理できないようなメモリ構成を有する環境も考えらえる。Python層では、アルゴリズム開発、Native層では、ハードウェアを強く意識する開発というソフトウェア階層の役割分担を考えると、こうしたハードウェア環境の特徴に対して責任を持つ管理機構はNative層で実装することが適切である。後述する仮想マシンを利用する場合（Python層への依存を取り除いた場合）も、このメモリ管理機構を使い回すことができる。
Python層でNative層の多次元配列をラップするクラスを用意し、メモリ領域の生成・解放タイミングはこのPythonクラスのインスタンス生存期間に一致させる。Python上のコードで多次元配列を自然に扱うために、こうした仕組みが必要となる。「Define-by-Run」の機能もPythonのメモリ管理機構に依存している。
【０１８９】
多次元配列データの相互互換及び参照関係を図３１に示す。
【０１９０】
８−４．メモリプールモジュール
メモリプールモジュール５１０は、一旦確保したメモリ領域を使い回すことで、コスト(処理サイクル数など)が高いメモリ管理機構のコール回数を削減するための仕組みである。
関数定義例は以下のとおりである。
（例１）void chnr_momory_pool_init(MemoryPool* momory_pool)
これにより、メモリプールを初期化することができる。
（例２）void chnr_momory_pool_release(MemoryPool* momory_pool)
これにより、メモリプールを破棄することができる。
（例３）void* chnr_momory_pool_alloc_buffer(MemoryPool* momory_pool, int byte_size, void* old_addr)
これにより、メモリを確保することができる。
（例４）void chnr_momory_pool_free_buffer(MemoryPool* momory_pool, void*addr)
これにより、メモリを解放することができる。
【０１９１】
Native層でメモリプールモジュールが必要となる背景（１）
Chainerの「Define-by-Run」はPythonが持つ動的メモリ管理の仕組みに依存している。その例（Linear Functionのフォワード処理）を図３２に示す。この例では、３行目のWx = x.dot(self.W.T)の記述でWxのインスタンス（中身は多次元配列）が新たに生成されている。Wxはどの変数からも参照されなくなった時点でPythonのメモリ管理機構により自動破棄される。
Functionが出力するデータ（上記の例ではWx）のサイズは入力データサイズやパラメータに依存して動的に変更可能であって、その実体（メモリ領域）の確保もフォワード処理やバックワード処理のコードフロー内で実行される。「Define-by-Run」（ネットワーク構成の実行時に定義）を実現するためには、こうした必要なタイミングで必要なサイズだけメモリを確保する仕組みが必要である。
【０１９２】
Native層でメモリプールモジュールが必要となる背景（２）
Python層でNative層の多次元配列をラップするクラスを用意し、Native層の多次元配列の生存期間をPython層と一致させる工夫をすることで、「Define-by-Run」の柔軟性を享受しながらNative層の実装を利用することができる。
しかしながら、通常Functionは高い頻度でコールされるため、その度にNative層のmallocやfreeなどコストの高いメモリ管理機構をコールしてしまうと、処理速度の低下を招く可能性がある。このため、一旦確保したメモリ領域を使い回す機能(メモリプール)を用意する必要が生じる。
【０１９３】
メモリプールの実装例（１）
構造体定義例を図３３に示す。
メモリ確保時の処理フローは次のとおりである。
１．Buffer_sizeの配列の中から、解放済みフラグが1でかつ前回確保したときのサイズが今回確保したいサイズと一致しているインデックスを検索し、見つかれば、解放済みフラグを0にセット後、同じインデックスのbuffer_addrの値(メモリバッファのアドレス)を返す。ここで、解放済みフラグは例えばbuffer_size配列要素の符号ビットで管理する。前回確保したときのサイズとアドレスの組み合わせにより配列要素を検索することで、アドレスの入れ替わりを少なくすることもできる。
２．上記一致しているインデックスが見つからなければ、実際にメモリを確保(mallocなどをコール)して、そのアドレスとサイズを配列に加えた後、アドレスを返す。
【０１９４】
メモリプールの実装例（２）
メモリ解放時の処理として、buffer_addrの配列の中から解放すべきアドレスを検索し、そのアドレスが見つかれば、解放済みフラグを1にセットする。
メモリプール解放時の処理として、buffer_addrの配列の中からアドレスが設定されている要素に対してメモリの解放（free関数のコールなど）を行う。
【０１９５】
メモリプール実装の効果
大半のニューラルネットワークにおいては、メモリサイズの組み合わせは、学習のイテレーション毎に変化することはなく固定的なので、上述のようなメモリプールの実装例を用いることで、mallocなどの呼び出しを最初のイテレーション時だけにとどめることができる。
【０１９６】
８−６．Optimizerモジュール
Optimizerモジュール５０８は、ニューラルネットワークの重みを有するレイヤーごとに重み更新を行う関数群である。Optimizerモジュール５０８は、重みの更新アルゴリズム別に以下の関数を定義する。
（例１）chnr_op_init_state_xxxx(…)
これにより、重み更新アルゴリズムの内部状態初期化処理を実装(浮動小数点版)することができる。
（例２）chnr_op_update_one_xxxx(…)
これにより、重み更新処理を実装(浮動小数点版)することができる。
（例３）chnr_op_init_state_xxxx_fx (…)
これにより、重み更新アルゴリズムの内部状態初期化処理を実装(固定小数点版)することができる。
（例４）chnr_op_update_one_xxxx_fx (…)
これにより、重み更新処理を実装(固定小数点版)することができる。
ここで、xxxxは重みの更新アルゴリズム別に付与される名称を表す。
なお、重みの更新アルゴリズムは、上記第１部の上記「２−１３」において説明したものを含むことができる。
【０１９７】
８−７．データ変換(Converter)モジュール（１）
データ変換モジュール５０６は、データ形式の変換を行う関数群である。
関数定義例は以下のとおりである。
（例１）chnr_float_to_fixed(MDArray* dst, MDArray* src, int Q)
これにより、浮動小数点型から固定小数点型へ変換することができる。
（例２）chnr_fixed_to_float(MDArray* dst, MDArray* src)
これにより、固定小数点型から浮動小数点型へ変換することができる。
（例３）chnr_host_to_device(MDArray* dst, float* src_data, int src_dimensions[], int src_num_axis, int Q, int async, …)
これにより、デバイス非依存データ表現(後述)からデバイス依存データ表現(後述)へ変換することができる。
（例４）chnr_device_to_host(float* dst_data, int dst_dimensions[], int*dst_num_axis, MDArray* src, int async, …)
これにより、デバイス依存データ表現からデバイス非依存データ表現へ変換することができる。
【０１９８】
浮動小数点型と固定小数点型変換の効果
組み込み向け半導体チップには、FPU(浮動小数点演算ユニット)を省いたり、少なくとも大規模並列計算に関してFPUを用いない回路設計とすることで、計算量に対するハードウェア資源（トランジスタ数や消費電力）削減を狙ったものが多く見られる。FPUを用いないでニューラルネットワークなど数値計算のアルゴリズムを実行する場合、整数演算器とシフト演算器を利用して小数点以下の情報を含む数値を表現する固定小数点型と呼ばれるデータ型がよく用いられる。浮動小数点型は、実数値をより直感的に扱えるようにするという意味で、アルゴリズム設計に適したデータ型であり、固定小数点型はハードウェア資源の有効活用に適したデータ型といえる。ニューラルネットワークを設計実行するフレームワーク内にこのようなデータ型間の変換関数を用意しておくことで、ニューラルネットのアルゴリズム開発を、統一された環境下で数理面からハードウェアを意識した実装面へ、型変換の影響度をFunction単位で確認しながら段階的に進めることができる。
【０１９９】
デバイス非依存データ表現とは、特定の計算機に依存する情報をもたないデータ表現をいう。このデータ表現の代表的な実装は、メモリアドレスが連続なC言語形式の多次元配列である。Python層にてnumpyなどのライブラリを利用すればこのようなデータ表現を容易に扱うことができるが、ライブラリやホスト言語を特定するものではない。
デバイス依存データ表現とは、特定の計算機に特化した最適化実装に適したデータ表現をいう。
これら２つのデータ表現を相互変換する関数を用意することで、ハードウェアを強く意識した最適化実装と、アルゴリズムを意識した実装(例えばPythonで記述された数式に近い構造の読みやすいコードなど)を連携して全体動作を実行できる。
【０２００】
デバイス依存データ表現への変換で考慮すべき要件例
（１）メモリ構成
共有メモリに配置するのか？ハードウェア特有のメモリ領域に配置するのか？
（２）メモリアライメント
先頭アドレス、各次元ごとの先頭アドレス、パディング
（３）バイトオーダ
リトルエンディアン、ビッグエンディアン
（４）データ型
固定小数点(Q値)／浮動小数点,バイト幅(32bit, 16bit, 8bit, …)
（５）マルチコア実行におけるデータ入出力のスケジューリング
（６）データ通信
最適化実装を持つデバイスが別チップや別基板などにある場合の通信処理
【０２０１】
８−８．通信手段
これまでに説明したNative層の関数群（Native I/F）の実装を以下のような変更を適応することで、別チップや別基板などにあるデバイスと通信しながら全体動作を高速に実行できる
（１）RPC(remote procedure call)
（２）命令キュー
（３）多次元配列のデータ通信量の削減
（４）転送と計算の非同期処理
これらの変更方針について解説するために以下の用語を定義する
「ホストデバイス」：全体動作を実行するデバイス（通常の実装ではPython上でChainerのコードが実行されるデバイス）
「遠隔デバイス」：別チップや別基板などにあるなどの理由で通信処理が必要なデバイス
【０２０２】
RPC(remote procedure call)
Native I/Fで定義された関数を呼び出したとき、その処理要件（メモリ確保や演算の実）を直接実行するのではなく、処理要求を表す情報（関数の種類や引数）を生成し、遠隔デバイスへ送信し、遠隔デバイスではその指示に基づいた処理を実行した後、その処理結果をホストデバイスが受信する仕組みを設ける。
命令キュー
RPCによる処理要求の通信は、Native I/Fで定義された関数を呼び出す都度実行するのではなく、処理要求を表す情報を一旦キュー(FIFOバッファ)に蓄えることで通信のスケジュールを効率化する。
多次元配列のデータ通信量の削減
多次元配列は膨大なデータサイズを持つため、その通信量を削減することは全体動作の速度を向上させる上で重要な課題である。通信量を削減するためには大きく以下の２つの方策がある。
（１）多次元配列の転送回数を削減する
（２）個々の多次元配列のデータ通信量を削減する
【０２０３】
多次元配列の転送回数を削減する方法
中間層（ニューラルネットの入力層と出力層以外）のレイヤー間で入出力するデータ及び重みの勾配は、遠隔デバイスのみに存在すればよくデバイス間の通信は不要である。また「重み」についても、ネットワーク構造を定義する最初の段階で遠隔デバイスへ転送し、学習終了時にホストデバイスへ転送すればよい。
データ変換(Converter)モジュール５０６について説明したデバイス非依存データ表現及びデバイス依存データ表現の変換関数は、このような転送タイミングのマネージを行うのに最適である。具体的には各関数で以下の処理を行う。
デバイス非依存データ表現からデバイス依存データ表現へ変換する際に、ホストデバイスから遠隔デバイスへのデータ転送を行う。
デバイス依存データ表現からデバイス非依存データ表現へ変換する際に、遠隔デバイスからホストデバイスへのデータ転送を行う。
【０２０４】
個々の多次元配列のデータ通信量を削減する方法
様々なデータ圧縮のためのアルゴリズムが知られている。
（１）可逆圧縮(ハフマン符号化、ランレングス圧縮、etc)
（２）不可逆圧縮(DCT, スカラー量子化、ベクトル量子化, etc)
データ通信を依頼する関数（デバイス非依存データ表現とデバイス依存データ表現の変換関数を想定）の引数にて、これらの圧縮アルゴリズムの種別とパラメータを指定することで、データの性質や精度要件の考慮に基づいた最適なデータ圧縮手段を用いて通信量を削減できる。
【０２０５】
転送と計算の非同期処理
多くの組み込み系チップでは、データ通信及び演算処理を別々のハードウェアが非同期に実行する構成を持つ。データ通信を依頼する関数（デバイス非依存データ表現とデバイス依存データ表現の変換関数を想定）に非同期実行(non-blocking)するものを用意すれば、こうしたハードウェア構成を意識したコーディング(一般にパイプライン化と呼ばれる手法)により、アリゴリズム全体の高速化を実現できる。
疑似コードによるパイプライン化のコーディングを図３４に示す
【０２０６】
８−９．仮想マシンモジュール
仮想マシンモジュール５０９は、バイトコードを解釈しニューラルネットの学習／識別処理（フォワード処理、バックワード処理及び重みの更新）を実行する機能を実現する関数群である。バイトコードは、後述するPython層のバイトコード出力器によって生成されるものを前提とするが、他のソフトウェアで生成されたバイトコードであっても形式が正しければ仮想マシンモジュールで解釈実行できる。
関数定義例は以下のとおりである。
（例１）void chnr_init_with_bytecode(VMState* state, char* byte_code)
これにより、バイトコードを構文解析し仮想マシンの内部状態を初期化することができる。
（例２）void chnr_forward(VMState* state)
これにより、フォワード処理を実行することができる。
（例３）void chnr_backward(VMState* state)
これにより、バックワード処理を実行することができる。
（例４）void chnr_update_weight(VMState* state)
これにより、重みの更新処理を実行することができる。
【０２０７】
バイトコードのフォーマット例
以下のような情報をバイナリーフォーマットにて格納する。
（１）入出力データ情報
{配列次元数・サイズ, データ型(float32, FixedPoint)}*Variable数
（２）重み情報
{配列次元数・サイズ, データ型(float32, FixedPoint), 実現値}*重み個数
（３）バックワード処理時Function呼び出し情報
{Functionの種別,入出力データのindex, 重み情報のindex, Functionの種別毎に固有のパラメータ}*Function数
（４）重み更新の種別及びパラメータ
さらにバイトコードには、ニューラルネット全体処理の入出力となる多次元配列のindexを加えてもよい。このindexをバイトコードに格納しておくことにより、仮想マシンを利用するユーザコードではニューラルネット全体処理の入力となる多次元配列と、出力となる多次元配列を関数呼び出しに関して適切に紐付けることができる。例えば、以下のようなフローにより、この紐付けを行うことができる。
（ステップ１）ユーザコードは仮想マシンの構成に用意された関数を呼び出すことにより、全体処理の入力多次元配列を取得する。
（ステップ２）ユーザコードは前記ステップ１で取得した多次元配列に入力データをコピーする。
（ステップ３）ユーザコードは仮想マシンの構成に用意された全体動作を実行する関数を呼び出す。
（ステップ４）ユーザコードは仮想マシンの構成に用意された関数を呼び出すことにより、全体処理の出力多次元配列を取得する（この多次元配列は前記ステップ３で実行される全体動作の処理結果が格納された状態となっている。前記ステップ３とステップ４の関数は必ずしも分離する必要はなく一体の関数であってもよい。）。
（ステップ５）ユーザコードは前記ステップ４で取得した多次元配列から出力データの中身を取得する。
【０２０８】
仮想マシンの内部状態初期化の処理フロー実装例
（１）バイトコード内の「入出力データ情報」を解釈して、Functionで入出力する多次元配列のリストを生成する。
（２）バイトコード内の「重み情報」を解釈して重みと重みの勾配(何れも多次元配列)のリストを生成する。
（３）バイトコード内の「Backward時Function呼び出し情報」を解釈して以下の情報を持つ構造体（FunctionState）のリストをForward用とBackward用にそれぞれ生成する（フォワード処理/バックワード処理を実行する関数の識別ID, 入出力データのアドレス, 重みのアドレス, 重みの勾配のアドレス, Functionの種別毎に固有のパラメータ）。
（４）バイトコード内の「重み更新の種別とパラメータ」を解釈して、重み更新アルゴリズムの内部状態の多次元配列と、以下の情報を持つ構造体（OptimizerState）を初期化す
る（重みの更新を実行する関数のアドレス,重みのアドレス,重みの勾配のアドレス,重み更新アルゴリズムの内部状態, 重みの更新種別毎に固有のパラメータ）。
【０２０９】
仮想マシン内部状態の構成図を図３５に示す
【０２１０】
仮想マシンモジュールの実行フロー例（１）（フォワード処理及びバックワード処理）
仮想マシンモジュールは、図３６に示す擬似コードのような処理を実行する。
【０２１１】
仮想マシンの実行フロー例（２）（Optimizer）
仮想マシンモジュールは、図３７に示す擬似コードのような処理を実行する。
【０２１２】
Forward処理実行を特化させた最適化装置の構成２；データメモリ領域の再利用手段を有する場合（１）
全体動作を実行する際、学習（重みの更新）を行わず識別処理のみを実行するのであればフォワード処理のみを実行すれば良い。この場合、以下のデータは不要となる。
（１）レイヤー間で入出力されるデータのうち現在実行中のFunctionがアクセスしないもの
（２）重みの勾配
（３）重み更新アルゴリズムの内部状態
仮想マシンの内部状態初期化の際、重みの勾配及び重み更新アルゴリズムの内部状態は確保の必要がない。レイヤー間で入出力されるデータについても例えば次段落に記載するような手順でメモリ確保量を抑えることができる。
【０２１３】
Forward処理実行を特化させた最適化装置の構成２；データメモリ領域の再利用手段を有する場合（２）
仮想マシンモジュールの内部状態初期化時の手順例
（１）Functionごとに入出力するデータサイズ（メモリサイズ）の和を計算し、最大サイズのものを選ぶ。
（２）多次元配列をハンドルする構造体（MDArray）を初期化する際に１で確保したメモリ領域を使い回すようにアドレスを設定する。
レイヤー毎にメモリ領域の左端と右端を入出力として交互に切り替えて使うようなアドレス設定を行うことで、配列データのコピーが発生しないようにする。ループのある入出力を行うFunctionが含まれている場合には、次イテレーションに持ち越す出力データに関しては、この手順で示した再利用の対象外とし個別にメモリ領域を確保する。
【０２１４】
Forward処理実行を特化させた最適化装置の構成２；データメモリ領域の再利用手段を有する場合（３）
Functionが入出力するデータのアドレス設定例を図３８に示す。
【０２１５】
バイトコードのフォーマットに関する補足
これまでの説明では「バックワード処理時Function呼び出し情報」に格納された情報を単純に昇順あるいは降順に実装する例を示した。しかしながら、複数の実行順序をバイトコードに格納しておいたり、繰り返し、分岐の指示をバイトコードに格納しておくことで、仮想マシン実行時に入力データの性質に応じてニューラルネットの構成を動的に変更するといった、より高度な処理を実行することも可能である。メモリプールモジュールに関して上述したメモリ管理機構はこうした動的なメカニズム実現のために利用することができる。
【０２１６】
仮想マシンから外部のコードへ入出力するデータのひも付けについて
「仮想マシンの内部状態初期化処理」にてFunction間で入出力するデータのリストが作成されるが、仮想マシンの関数をコールする外部のコードが、このリストの要素に直接アクセスするのが最も簡易な方法である。バイトコード生成時にPythonのVariableインスタンスの変数名を「入出力データ情報」に格納しておけば、この名前を使って入出力をひも付けることもできる。
【０２１７】
９．Python層
次に、図２９に例示した実施形態に係る実装装置のPython層に関する構成について説明する。
９−１．NativeArrayクラス
NativeArrayクラス５０２は、Python層でNative層の多次元配列をラップするクラスである。NativeArrayクラス５０２は、Native層の多次元配列と1:1対応するインスタンスとして生成する。また、NativeArrayクラス５０２は、Pythonオブジェクトとしての基本機能として参照カウントによる生存期間管理機能を持つ。さらにまた、NativeArrayクラス５０２は、生存期間が終了した時点でNative層の多次元配列の解放を依頼する機能を持つ。
また、NativeArrayクラス５０２は、Native層の多次元配列の型情報のコピーを持ち、Python層の他のオブジェクトへ伝える機能を持つ。
さらにまた、NativeArrayクラス５０２は、データコピーや配列要素ごとの加算などの機能を持ち、その実行をNative層へ依頼する機能を持つ。
加えて、NativeArrayクラス５０２は、その他、Chainerが依存するNumpyやGPUArrayといったPython層の多次元配列ライブラリとコンパチブルに動作する機能を持つ。
【０２１８】
９−２．NativeDeviceクラス
NativeDeviceクラス５０１は、Native層の最適化実装及び参照実装を抽象化するクラスである。NativeDeviceクラス５０１は、以下のような処理をPython層の他のオブジェクトからの依頼に応じてNative層へ依頼する機能を持つ。
（１）デバイスの初期化と解放
（２）多次元配列の生成とコピー（これをラップしたPython層のNativeArrayインスタンスを生成する）
（３）デバイス非依存データ表現とデバイス依存データ表現間の変換（浮動小数点と固定小数点間の変換も指示できる）
（４）FunctionやOptimizerの処理実行（Native層の個々の関数を呼び分ける）
【０２１９】
９−３．Functionクラス
Functionクラス５０３は、フォワード処理とバックワード処理とをペアにして定義したクラスである。Functionクラス５０３は、Chainerに存在するクラスだが、フォワード処理とバックワード処理をNative層へ依頼する機能を追加する。
メソッド実装例は以下のとおりである。
（例１）forward_native(…)
これにより、フォワード処理をNative層に依頼することができる。
（例２）backward_native(…)
これにより、バックワード処理をNative層に依頼することができる。
【０２２０】
Forward_nativeやbackward_native呼び出し時に想定される処理フロー
（１）入力データサイズやFunctionインスタンス初期化時のパラメータから、出力データサイズを計算する。
（２）（１）で求めた出力データサイズと、入力データのインスタンス(NativeArray)、Functionの区分(Linear, ReLU, …)をNativeDeviceインスタンスに渡してNative層の関数呼び出しを依頼する。
（３）NativeDeviceインスタンスはこの呼び出しに応じて以下の処理を実行する。
（Ａ）Native層に出力データの多次元配列生成を依頼する。入力データを上書きするFunctionであればこの処理は行わない。
（Ｂ）入力データの型（浮動小数点、固定小数点）とFunctionの区分より実際にコールするNative層の関数を決定し呼び出す（Native層の関数はAで確保した多次元配列に処理結果を書き込む）
（Ｃ）上記（Ａ）で確保した多次元配列をラップするNativeArrayインスタンスを生成する。
（４）上記（Ｃ）で生成したNativeArrayインスタンスをFunctionの戻り値として返す。
【０２２１】
９−４．Optimizerクラス
Optimizerクラス５０３は、重みの更新を行うクラスである。Optimizerクラス５０３は、Chainerに存在するクラスであるが、状態初期化及び重み更新処理をNative層へ依頼する機能を追加する。
メソッド実装例は以下のとおりである。
（例１）init_state_native(…)
これにより、重み更新アルゴリズムの内部状態初期化処理をNative層に依頼することができる。
（例２）update_one_native(…)
これにより、重み更新処理をNative層に依頼することができる。
これらのメソッド呼び出し時の処理フローは上記「Functionクラス」で説明済みのものと同等である。
【０２２２】
９−５． Native層と連携する全体動作の具体例
具体例を図３９に例示する。
【０２２３】
９−６．バイトコード生成（出力）部
バイトコードし生成器５０４は、「Define-by-Run」で定義したニューラルネットワークのネットワーク構成をバイトコード（解釈実行可能なデータ形式）に変換し出力する仕組みである。バイトコードの形式は例えば「仮想マシンモジュール」に関して上述したものが考えられる。しかしながら、このような形式以外にも、例えば以下のような形式への出力を考えることができる。
（１）Caffeのニューラルネット定義フォーマット
Caffeで実行できる(Caffeはニューラルネット設計実行のための代表的なフレームワークの一つ)。
（２）C言語やJava（登録商標）などのプログラミング言語
全体動作を実行するソフトウェアを生成できる。
（３）HDLやVerilogといったハードウェア記述言語
全体動作を実行するハードウェアを合成できる。
【０２２４】
バイトコード生成部の関数定義例は以下のとおりである。
関数名：write_network_difinition(output_node, path, format)
関数仕様：output_nodeから入力側に向かってつながるネットワーク構成をformatに指定された形式でpathで指定したファイルに出力する。output_nodeはリストで指定可能である(複数のノードを起点にできる)。
【０２２５】
バックワード処理のための参照構造からバイトコードを出力する手続き例
上記第１部において説明したとおり、Chainerは自然なフォワード処理の計算の記述に従ってバックワード処理のための参照構造を生成する機能を持つ。フォワード処理はバックワード処理のための参照構造を逆順にたどれば計算できるので、この参照構造からバイトコードを生成すれば、フォワード処理及びバックワード処理双方の処理が実行可能となる。
この手順は大きく以下のステップに分けられる。
（１）バイトコード作成のための要素情報生成
入出力データ情報生成
重み情報生成
バックワード処理時Function呼び出し情報生成
（２）要素情報のバイトコードへの変換
【０２２６】
バイトコード作成のための要素情報生成手順
−「バックワード処理のための参照構造」をwrite_network_difinitionに渡されたoutput_nodeを起点にたどって以下の処理を実行する。
（１）現在のノードがVariableの場合には、その多次元配列の情報（サイズ・次元数,浮動小数点／固定小数点（Q値））を「入出力データ情報」のリストに加える。
（２）現在のノードがFunctionの場合には以下の処理を行う。
（i）重みの多次元配列の情報（サイズ・次元数, 浮動小数点／固定小数点（Q値）, 重みの実現値）を「重み情報」のリストに重複を許さないように加える（複数のFunctionインスタンスが同一の重みを共有し得るため）。
（ii）Functionの種別, 入出力データのindex, 重みのindex, Functionの種別毎に固有のパラメータを「Backward時Function呼び出し情報」のリストに加える。
output_nodeに複数の起点ノードが渡された場合、次段落の手順で同じノードが重複登録されることを避ける。
【０２２７】
複数の起点ノードが渡された場合の要素情報作成手順
（１）「バックワード処理時Function呼び出し情報」のリスト(空)を作成する。
（２）output_node内の起点ノードごと以下の手順を行う。
（Ａ）起点ノード固有の「バックワード処理時Function呼び出し情報」のリストを作成する。
（Ｂ）前段落で説明した登録手順を上記（Ａ）で作成したリストに対して行う。このとき、上記（１）で作成したリストに既に登録されているノードについては登録手順を実行しないようにして重複登録を避ける。
（Ｃ）上記（１）で作成したリストの前方に上記（Ａ）で作成したリストを連結する。
【０２２８】
Python層：バイトコード出力器（６）
要素情報のバイトコードへの変換
「バイトコード作成のための要素情報生成」の手順で作成した以下の情報を、write_network_difinitionのformat引数で指定されたフォーマットへ変換する。
（１）入出力データ情報生成
（２）重み情報生成
（３）バックワード処理時Function呼び出し情報生成
フォーマットとしては「バイトコード生成部」について先に例示したものが挙げられる。
【０２２９】
複数のネットワーク構成の出力
「バイトコード生成部」について上述したwrite_network_difinition関数は、引数pathで渡されたファイルに直接ネットワークの構成を書き出す仕様となっているが、このpath引数に複数のネットワークの構成をバイトコードに書き出すためのオブジェクトを渡すこともできる。ここでネットワーク構成とは「Python層：バイトコード出力器（６）要素情報のバイトコードへの変換」で解説した(1)、(2)、(3)の構成要素を示す。
この「複数のネットワークの構成をバイトコードに書き出すためのオブジェクト」は、「複数のネットワーク構成」の間で同一の「（２）重み情報」を共有化し、バイトコードに書き出す重み情報を削減する。「（１）入出力データ情報生成」と「（３）バックワード処理時Function呼び出し情報生成」は、部分的な情報に重複が見られる場合も、上述のステップにより独立に生成する。このオブジェクトを利用する場合のコード例を図４０に示す。このコード例では６行目では、nodeAからバックワード処理のための参照構造をたどりネットワークの構成を出力し、さらに7行目では、nodeBからバックワード処理のための参照構造をたどりネットワークの構成を出力する。８行目においてこれら２つのネットワーク構成が１つのファイル(./bytecode.bin)に出力される。
【０２３０】
同一ネットワークに対するフォワード処理とバックワード処理とで異なるFunction呼び出し順序を指定する方法
Chainerは、上記第１部において説明したとおり、特定のVariableインスタンスを起点にそこから入力層側へ向かうBackwardのための参照構造を打ち切る機能（unchain_backwardメソッド）を持っている。このunchain_backwardメソッドと前段落で説明した「複数のネットワーク構成の出力」を組み合わせることで同一ネットワークにおけるフォワード処理とバックワード処理の計算に対して異なるFunction呼び出し順序を指定することもできる。
図４１に示すコード例では、#1の呼び出しでAからDまでの全ての処理を実行するネットワーク定義が出力されるのに対して、#2の呼び出しではBからDまでの処理のみが実行されるネットワーク定義が出力される。仮想マシンによるバイトコード実行時に#1で出力されるネットワーク構成に対してForward処理を行い、#2のものに対してBackward処理を実行するなどといった使い分けが可能となる。
【０２３１】
１０．Native層及びPython層に共通する構成
１０−１．複数のNNアルゴリズムを融合したアルゴリズム実行部
一般のニューラルネットの構成には頻出するFunctionの組み合わせが見られる
（例１）Linear→ReLU, Linear→ReLU→Linear→ReLU 
（例２）Convolution2D→ReLU, Convolution2D→ReLU→Convolution2D→ReLU
こうした頻出するFunctionの組み合わせを１つのFunctionとして定義し、Python層及びNative層双方でその計算に特化した実装を行うことで、アルゴリズム設計においてもハードウェア実行効率においても以下のようなメリットを享受できる
（１）Functionを呼び出すためのオーバーヘッド(関数呼び出しや通信)を削減できる。
（２）複数のFunctionにまたがるデータの依存関係や並列性を考慮した実装により、高い実行効率を得られる（キャッシュメモリを有効活用しメインメモリに直接アクセスするデータ量を削減するなど）。
（３）アルゴリズム設計時により抽象化したFunctionを用いることで複雑なネットワーク構成を理解・定義しやすくなる。
【０２３２】
一般に近年の計算機は演算コアの速度向上が著しいのに対して、メモリアクセスの性能はそれほど高速化されていない。このため計算機全体の性能を見たときメモリアクセスに律速され十分な計算性能を達成できない課題がある。このような課題を解決するため演算コアに物理的に近い場所にキャッシュメモリやレジスタファイルと呼ばれる小容量であるが特別に高速なメモリを配置し、キャッシュメモリ上で多くの計算を行うことで、両者の速度ギャップを埋める仕組みが用いられている。
【０２３３】
ところで、ニューラルネットの構成には頻出する以下のようなFunctionの組み合わせが見られる。
・Convolution2D→ReLU
・Convolution2D→ReLU→Convolution2D→ReLU
Convolution2Dは、入出力するデータサイズに対して計算量が大きいので、キャッシュメモリなどの仕組みを有効活用し計算コアの性能を発揮できるチャンスが大きい。これに対してReLUは、入出力するデータサイズに対して計算量が小さいので、このチャンスは小さい。
Convolution2DとReLUを個別のFunctionとして実行する場合、Convolution2Dの処理結果のデータを全てメインメモリに書き出した後、その内容を再び演算コア周辺に転送しReLUの計算を行う必要がある。その理由はConvolution2Dの処理が終わった後にその結果を直ぐにReLUが用いるか否かが分からないためである。
【０２３４】
そこで、Convolution2DとReLUを一体のFunctionとして実行すれば、Convolution2Dの処理結果をメインメモリに書き出す前に、キャッシュメモリやレジスタファイル上で直接ReLUの処理の入力として用いることができるので、メインメモリへのデータ転送の頻度を少なくし、より効率的（高速）に処理を実行できるチャンスが増える。
Convolution2D→ReLU→Convolution2D→ReLUのようにさらに多くのFunctionを一体のFunctionとして実行できれば、処理効率向上のチャンスはさらに増える。キャッシュメモリのサイズや、Functionの組み合わせの中でのデータの依存関係を勘案し、さらに積極的にメインメモリへのアクセス量を削減できるからである。
【０２３５】
１０−２．Forward処理実行を特化させた最適化装置の構成１；重みの最適化処理手段を有する場合
ニューラルネットワークのレイヤーアルゴリズムの中には、バックワード処理を行わずフォワード処理のみを実行する場合に特化した重みの最適化を行うことで計算量やメモリ使用量を削減できるものが存在する。このような最適化が可能な理由は以下による。
確率的勾配降下法を用いてニューラルネットを学習するには重みのベクトルに高い数値精度と高い値域の自由度が必要である。なぜなら、学習時に小さな値の更新を積み重ねていく必要がある上、事前に重みのベクトルが変化する値域を十分に想定できないためである。これに対して、Forward処理だけを実行するのであればこのような精度と自由度の両立は必要なく重みの情報量を削減した上でForward処理を実行するようにすればメモリや計算量を削減することができる。計算量を削減できるのは重みの要素数を削減したり０の重みを計算しないなどの対応がとれるからである。例えば、Linear(レイヤー間の内積)の処理では、重みの情報（入力ノード数*出力ノード数の行列）を特異値分解し、対角成分が小さくなる要素を削除することで、重みのデータサイズを圧縮し、計算サイズを削減するテクニックが知られている。
(J. Xue, J. Li, and Y. Gong. Restructuring of deep neural network acoustic models with singular value decomposition. In Interspeech, 2013)
ChainerのFunctionクラスにこうしたForwardに特化した重みの最適化処理を実行するメソッドを加えることで、既に学習済みの重みを用いてForward処理のみを実行する場合の計算資源を削減することができる。このメソッドはFunctionクラスに既存のForwardメソッドやBackwardメソッドと同様に、Functionが保持する重みの多次元配列の型に依存してハードウェア実装（汎用計算機、GPU、Native）の違いを隠蔽する（再初期化の実装を呼び分ける）機能を持つ。
【０２３６】
ソフトウェアハードウェア構成に関する補足
これまでPython層、Native層の関数やクラスに特定の機能を従属されることを例示して実施形態の詳細を説明してきた。しかしながら、これらのソフトウェア階層、クラス、関数の役割分担は、本発明の実施形態に係る機能の構成を具体的に説明するための一例を示したものに過ぎず、以下の例に示すように本発明の実施形態に係る個々の機能がこれまでの説明とは別のクラスや、階層、あるいはハードウェアに実装されることも考えられる。
（１）「Forward処理実行を特化させた最適化装置の構成２；データメモリ領域の再利用手段を有する場合」で説明した処理内容は仮想マシンモジュールではなくバイトコード出力器であらかじめ実行できる。
（２）「複数のFunctionを組み合わせたFunction」で説明したFunctionはソフトウェアレベルの最適化ではなく特化したハードウェア(FPGA, ASIC)で実装できる。
よって、本発明の実施形態に係る構成はPython層、Native層の関数やクラス、あるいはソフトウェアを前提とした実装に直接依存するものではない。
【符号の説明】
【０２３７】
１０  学習装置
１００  評価ボード
１１０  取得部
１２０  記憶部
１３０  実行部
２００  組み込み系チップ（組み込み系半導体集積回路）
４０１  駆動部
４０２  Functionクラス／Optimizerクラス
４０５  Native層実行部
４０８  Native用多次元配列
４０９  Variableクラス
５０４  バイトコード生成部
５０５  デバイス管理モジュール
５０６  データ変換モジュール
５０７  多次元配列モジュール
５０８  Functionモジュール／Optimizerモジュール
５０９  仮想マシンモジュール
５１０  メモリプールモジュール
【図１】
2020170551.tif 000009
【図２】
2020170551.tif 000010
【図３】
2020170551.tif 000011
【図４】
2020170551.tif 000012
【図５】
2020170551.tif 000013
【図６】
2020170551.tif 000014
【図７】
2020170551.tif 000015
【図８】
2020170551.tif 000016
【図９】
2020170551.tif 000017
【図１０】
2020170551.tif 000018
【図１１】
2020170551.tif 000019
【図１２】
2020170551.tif 000020
【図１３】
2020170551.tif 000021
【図１４】
2020170551.tif 000022
【図１５】
2020170551.tif 000023
【図１６】
2020170551.tif 000024
【図１７】
2020170551.tif 000025
【図１８】
2020170551.tif 000026
【図１９】
2020170551.tif 000027
【図２０】
2020170551.tif 000028
【図２１】
2020170551.tif 000029
【図２２】
2020170551.tif 000030
【図２３】
2020170551.tif 000031
【図２４】
2020170551.tif 000032
【図２５】
2020170551.tif 000033
【図２６】
2020170551.tif 000034
【図２７】
2020170551.tif 000035
【図２８】
2020170551.tif 000036
【図２９】
2020170551.tif 000037
【図３０】
2020170551.tif 000038
【図３１】
2020170551.tif 000039
【図３２】
2020170551.tif 000040
【図３３】
2020170551.tif 000041
【図３４】
2020170551.tif 000042
【図３５】
2020170551.tif 000043
【図３６】
2020170551.tif 000044
【図３７】
2020170551.tif 000045
【図３８】
2020170551.tif 000046
【図３９】
2020170551.tif 000047
【図４０】
2020170551.tif 000048
【図４１】
2020170551.tif 000049
【図４２】
2020170551.tif 000050
【図４３】
2020170551.tif 000051
【図４４】
2020170551.tif 000052
【図４５】
2020170551.tif 000053
【図４６】
2020170551.tif 000054
【図４７】
2020170551.tif 000055
【図４８】
2020170551.tif 000056
【図４９】
2020170551.tif 000057
【図５０】
2020170551.tif 000058
【図５１】
2020170551.tif 000059
【図５２】
2020170551.tif 000060
【図５３】
2020170551.tif 000061
【図５４】
2020170551.tif 000062
【図５５】
2020170551.tif 000063
【手続補正書】
【提出日】令和2年8月7日(2020.8.7)
【手続補正１】
【補正対象書類名】特許請求の範囲
【補正対象項目名】全文
【補正方法】変更
【補正の内容】
【特許請求の範囲】
【請求項１】
ニューラルネットワークを用いた演算を実行するためのソースコードを半導体集積回路に実装する実装方法であって、
前記ソースコードに基づいて、入出力データ情報、重み情報、バックワード処理時Function呼び出し情報、重み更新の種別及びパラメータの少なくとも１つを含み、前記半導体集積回路の演算装置が解釈可能なデータ形式を生成すること、
を含む実装方法。
【請求項２】
前記ソースコードは、
少なくとも１台のコンピュータに、
前記ニューラルネットワークの計算グラフの定義が完了する前に、前記ソースコードに含まれるコードにより定義されたフォワード処理の出力値を入力値に基づいて計算すること、
を実行させるように記述されたものである、
請求項１に記載の実装方法。
【請求項３】
前記ソースコードは、
少なくとも１台のコンピュータに、
前記ソースコードに含まれるコードの実行により、前記ニューラルネットワークのフォワード処理の出力値を入力値に基づいて計算することと、
前記ニューラルネットワークのバックワード処理のための参照構造を生成することと、
を実行させるように記述されたものである、
請求項１に記載の実装方法。
【請求項４】
前記バックワード処理時Function呼び出し情報は、前記参照構造に基づく情報である、
請求項３に記載の実装方法。
【請求項５】
前記データ形式は、複数のネットワーク構成の定義を含む、
請求項１乃至請求項４のいずれかに記載の実装方法。
【請求項６】
前記データ形式は、レイヤーアルゴリズムを定義する複数の関数を融合した１つの関数を含む、
請求項１乃至請求項５のいずれかに記載の実装方法。
【請求項７】
前記重み情報は、最適化処理を実行した後の重みに関する情報を含む、
請求項１乃至請求項６のいずれかに記載の実装方法。
【請求項８】
前記データ形式は、前記演算装置が実行可能なバイトコードである、請求項１乃至請求項７のいずれかに記載の実装方法。
【請求項９】
請求項１乃至請求項８のいずれかに記載の実装方法を用いて生成されたデータ形式。
【請求項１０】
ニューラルネットワークを用いた演算を実行するためのソースコードを半導体集積回路に実装する実装装置であって、
前記ソースコードに基づいて、入出力データ情報、重み情報、バックワード処理時Function呼び出し情報、重み更新の種別及びパラメータの少なくとも１つを含み、前記半導体集積回路の演算装置が解釈可能なデータ形式を生成する手段、
を備える実装装置。