(19)【発行国】日本国特許庁(JP)
(12)【公報種別】公開特許公報(A)
(11)【公開番号】P2022153634
(43)【公開日】2022-10-12
(54)【発明の名称】情報処理装置及び情報処理方法
(51)【国際特許分類】
G06F 8/51 20180101AFI20221004BHJP
G06F 9/455 20060101ALI20221004BHJP
G06N 3/10 20060101ALI20221004BHJP
【FI】
G06F8/51
G06F9/455
G06N3/10
【審査請求】有
【請求項の数】1
【出願形態】OL
(21)【出願番号】P 2022124392
(22)【出願日】2022-08-03
(62)【分割の表示】P 2020118714の分割
【原出願日】2016-09-02
(31)【優先権主張番号】P 2015213293
(32)【優先日】2015-10-29
(33)【優先権主張国・地域又は機関】JP
【公序良俗違反の表示】
(特許庁注:以下のものは登録商標)
1.VERILOG
2.PYTHON
(71)【出願人】
【識別番号】515130201
【氏名又は名称】株式会社Preferred Networks
(74)【代理人】
【識別番号】100120031
【弁理士】
【氏名又は名称】宮嶋 学
(74)【代理人】
【識別番号】100118876
【弁理士】
【氏名又は名称】鈴木 順生
(74)【代理人】
【識別番号】100202429
【弁理士】
【氏名又は名称】石原 信人
(72)【発明者】
【氏名】加藤 辰哉
(72)【発明者】
【氏名】奥田 遼介
(72)【発明者】
【氏名】得居 誠也
(72)【発明者】
【氏名】海野 裕也
(72)【発明者】
【氏名】比戸 将平
(57)【要約】
【課題】効率的に機械学習を実行する情報処理装置を提供すること。
【解決手段】一実施形態に係る情報処理装置は、ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段と、各フォワード処理と該フォワード処理に対応するバックワード処理との対応関係を記憶する記憶手段と、前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、前記記憶手段に記憶された前記対応関係に基づいて該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段と、を具備する。
【選択図】
図2
【特許請求の範囲】
【請求項1】
ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段と、
前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段と、
を具備することを特徴とする情報処理装置。
【発明の詳細な説明】
【技術分野】
【0001】
本明細書に開示された技術は、機械学習に関する。
【背景技術】
【0002】
近年、ニューラルネットワークを用いた機械学習が様々な分野において利用されている。
このような機械学習を実行するに際して、開発者等は、所定のプログラミング言語を用いて、ニューラルネットワークのネットワーク構造等を定義したソースコードを作成し、そのように作成したソースコードをパーソナルコンピュータ等に実行させることによって、そのようなパーソナルコンピュータに機械学習を実行させることができる(非特許文献1)。
【先行技術文献】
【非特許文献】
【0003】
【非特許文献1】Yangqing Jia、”Caffe”、[online]、Berkeley Vision and Learning Center、[平成27年9月28日検索]、インターネット<URL: http://caffe.berkeleyvision.org/>
【発明の概要】
【発明が解決しようとする課題】
【0004】
近年、ニューラルネットワークのネットワーク構造等を定義したソースコードを効率的に作成することを可能にするフレームワークが必要とされている。
【課題を解決するための手段】
【0005】
そこで、本発明の様々な実施形態により、効率的に機械学習を実行する情報処理装置及び情報処理方法を提供する。
【0006】
一態様に係る情報処理装置は、ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段と、各フォワード処理と該フォワード処理に対応するバックワード処理との対応関係を記憶する記憶手段と、前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、前記記憶手段に記憶された前記対応関係に基づいて該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段と、を具備するものである。
また、一態様に係るコンピュータプログラムは、コンピュータを、ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得する取得手段、各フォワード処理と該フォワード処理に対応するバックワード処理との対応関係を記憶する記憶手段、及び、前記ソースコードに含まれた各コードを順次実行する実行手段であって、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算し、かつ、前記記憶手段に記憶された前記対応関係に基づいて該コードに対応する層におけるバックワード処理のための参照構造を生成する、ように構成された実行手段、として機能させるものである。
【発明の効果】
【0007】
本発明の様々な実施形態により、効率的に機械学習を実行する情報処理装置及び情報処理方法を提供することができる。
【図面の簡単な説明】
【0008】
【
図1】
図1は、従来技術に係る「Define-and-Run」と称される手法を概念的に示す模式図である。
【
図2】
図2は、本発明の実施形態に係る「Define-by-Run」と称される手法を概念的に示す模式図である。
【
図3】
図3は、ニューラルネットワークのネットワーク構成の一例を示す模式図である。
【
図4】
図4は、ニューラルネットワークのネットワーク構成の別の例を示す模式図である。
【
図5】
図5は、ニューラルネットワークのネットワーク構成のさらに別の例を示す模式図である。
【
図6】
図6は、Linearによりフォワード処理時に実行される計算を実現するための擬似コードを示す図である。
【
図7】
図7は、Linearによりバックワード処理時に実行される計算を実現するための擬似コードを示す図である。
【
図8】
図8は、ReLUによりフォワード処理時に実行される計算を実現するための擬似コードを示す図である。
【
図9】
図9は、ReLUによりバックワード処理時に実行される計算を実現するための擬似コードを示す図である。
【
図10】
図10は、Convolution 2Dによりフォワード処理時に実行される計算を実現するための擬似コードを示す図である。
【
図11】
図11は、本発明の一実施形態に係る学習装置のハードウェア構成例を示す模式図である。
【
図12】
図12は、本発明の一実施形態に係る学習装置が有する機能例を模式的に示すブロック図である。
【
図13】
図13は、本発明の一実施形態に係る学習装置に入力されるソースコードの一例を示す図である。
【
図14】
図14は、
図13に示されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。
【
図15】
図15は、従来技術に係るCaffeにより記述されたソースコードの一例を示す図である。
【
図16】
図16は、本発明の一実施形態に係る学習装置に入力されるソースコードの別の例を示す図である。
【
図17】
図17は、
図16に示されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。
【
図18】
図18は、従来技術に係るCaffeにより記述されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。
【
図19】
図19は、本発明の一実施形態に係る学習装置に入力されるソースコードのさらに別の例を示す図である。
【
図20】
図20は、本発明の実施形態に係る実装手法のステップIを説明する模式図である。
【
図21】
図21は、本発明の実施形態に係る実装手法のステップIIを説明する模式図である。
【
図22】
図22は、Pythonによる実行部とチップによる実行部とが通信する場合を説明する模式図である。
【
図23】
図23は、本発明の実施形態に係る実装手法のステップIIIを説明する模式図である。
【
図24】
図24は、本発明の一実施形態に係る実装手法(第1の手法)に用いられる実装装置の構成例を示す模式図である。
【
図25】
図25は、本発明の一実施形態に係る実装手法に用いられる手順の一例を示すフロー図である。
【
図26】
図26は、本発明の一実施形態に係る実装手法における組み込み系チップの動作状態を示す模式図である。
【
図27】
図27は、本発明の一実施形態に係る実装手法(第2の手法)に用いられる実装装置の構成例を示す模式図である。
【
図28】
図28は、本発明の一実施形態に係る実装装置が有する機能を概念的に示す模式図である。
【
図29】
図29は、本発明の一実施形態に係る実装装置に含まれるNative層実行部の構成例を示す模式図である。
【
図30】
図30は、本発明の一実施形態に係る実装装置の多次元配列モジュールの構造体定義例を示す図である。
【
図31】
図31は、本発明の一実施形態に係る実装装置の多次元配列モジュールにおける多次元配列データの相互互換及び参照関係を示す図である。
【
図32】
図32は、本発明の一実施形態に係る実装装置のメモリプールモジュールを説明するための図である。
【
図33】
図33は、本発明の一実施形態に係る実装装置のメモリプールモジュールの構造体定義例を説明するための図である。
【
図34】
図34は、本発明の一実施形態に係る実装装置におけるパイプライン化のコーディング例を示す図である。
【
図35】
図35は、本発明の一実施形態に係る実装装置における仮想マシンモジュールの内部状態を示す図である。
【
図36】
図36は、本発明の一実施形態に係る実装装置における仮想マシンモジュールの実行フロー例を示す図である。
【
図37】
図37は、本発明の一実施形態に係る実装装置における仮想マシンモジュールの実行フロー例を示す図である。
【
図38】
図38は、本発明の一実施形態に係る実装装置における仮想マシンモジュールにおいてアドレス設定例を示す図である。
【
図39】
図39は、本発明の一実施形態に係る実装装置におけるPython層とNative層とが連携する全体動作の具体例を示す図である。
【
図40】
図40は、本発明の一実施形態に係る実装装置におけるバイトコード生成部における複数ネットワーク構成の出力を示す図である。
【
図41】
図41は、本発明の一実施形態に係る実装装置におけるバイトコード生成部におけるコード例を示す図である。
【
図42】
図42は、本発明の一実施形態に係るNative I/Fの構成例を示す図である。
【
図43】
図43は、本発明の一実施形態に係るNNによる識別・学習を実行するための構成例を示す図である。
【
図44】
図44は、本発明の一実施形態に係る多次元配列を管理する構成例を示す図である。
【
図45】
図45は、本発明の一実施形態に係るデータ表現変換部の構成例を示す図である。
【
図46】
図46は、本発明の一実施形態に係る通信部の構成例を示す図である。
【
図47】
図47は、本発明の一実施形態に係る浮動小数点及び固定小数点の実行部及び型変換部の構成例を示す図である。
【
図48】
図48は、本発明の一実施形態に係るメモリプールの構成例を示す図である。
【
図49】
図49は、本発明の一実施形態に係る複数のNNアルゴリズムを融合したアルゴリズム実行部の構成例を示す図である。
【
図50】
図50は、本発明の一実施形態に係る多次元配列のデータ通信量削減部の構成例を示す図である。
【
図51】
図51は、本発明の一実施形態に係る既存実行部との連携例を示す図である。
【
図52】
図52は、本発明の一実施形態に係る既存実行部との連携例を示す図である。
【
図53】
図53は、本発明の一実施形態に係るバイトコード生成部と仮想マシンの構成例を示す図である。
【
図54】
図54は、本発明の一実施形態に係る比較部の構成例を示す図である。
【
図55】
図55は、本発明の一実施形態に係る関数合成部の構成例を示す図である。
【発明を実施するための形態】
【0009】
以下、本発明の様々な実施形態について添付図面を参照して説明する。なお、各図面において共通する構成要素には同一の参照符号が付されている。
まず、第1部において、実施形態に係る情報処理装置(以下、情報処理装置の一例である学習装置として説明を行う)について説明し、第2部において、実施形態に係る情報処理装置に実装されたアルゴリズムを組み込み系チップ(組み込み系半導体集積回路)に実装する手法について説明する。
【0010】
第1部(実施形態に係る学習装置)
1.背景及び概略
深層学習(ディープラーニング)を含む機械学習アルゴリズムは、モデル毎に定義される損失関数の総和の最小化問題として定式化できることが多い。損失関数とは、与えられた学習用データサンプルにおいて、モデルの出力と正解との誤差で表されるような指標のことである。ここでは、データをモデルに入力してから出力を得て正解との比較を行うまでの一連の処理を計算グラフと呼び、その結果を損失関数とする。損失関数の最小化問題は、損失関数を微分した勾配(gradient)さえ計算可能であれば、勾配法と呼ばれる一般的な手法で解ける。
【0011】
計算機プログラムとして実装しようとした場合は、損失関数も勾配も全てを自らコーディングするという方法があるが、複雑なモデルの勾配の算出は一般に困難であり、明示的に計算式を得ることが難しいことが多く、直接的にプログラムとして記述できない。そこで、Caffe(http://caffe.berkeleyvision.org/)、Torch(http://torch.ch/)、Theano(http://deeplearning.net/software/theano/)といったような計算ライブラリを使うのが第二の方法である。なお、これらのURLに開示された内容は、引用によりその内容の全体が本明細書に組み込まれる。
【0012】
これらのライブラリでは、専用のミニ・プログラミング言語において、用意された基本計算要素(Primitive)の組み合わせとして損失関数を記述するだけで、その勾配関数をも自動的に得ることができる。これは、各基本計算要素の勾配自体が定義されているため、その組み合わせ全体の勾配も自動微分として得ることができるためである。すなわち、ディープラーニングで用いられるような、大規模な計算グラフとして表現できるニューラルネットワークも、その損失関数の計算がこのミニ・プログラミング言語を用いて明示的に表現できれば、その勾配関数を用いて勾配法で学習できる。
【0013】
そのような計算ライブラリは、これまで、本件出願人が「Define-and-Run」と呼ぶ計算手順をベースとしてきた。これは、まず計算グラフを定義(Define)し、勾配を自動微分により導出した後、学習データによる学習(Run)を進めるというアプローチである。このアプローチは、計算グラフが複雑な制御構文(ifやforなど)を持たず、時間的にも変化しない場合には、Define時に一連の勾配計算をひとかたまりとして高速化コンパイルして準備しておける、メモリ管理が不要などのメリットをもたらすものであった。
【0014】
しかしながら、ディープラーニングの研究の発展に伴って増えてきたような、複雑な制御構文を持つ計算グラフの場合や、データに依存しないメタな条件でも計算グラフが動的に変化するモデルの場合には、ミニ・プログラミング言語の表現力の低さやデバッグの困難性、動的に構造を変更できないことによるメモリ効率の悪化などの課題が存在していた。そのため、モデルの複雑さやデータの規模によっては、実装や実行が困難である場合があった。
【0015】
そこで、実施形態では、本件出願人が「Define-by-Run」と呼ぶ新たな計算手順を提案する。具体的には、実施形態では、「Define-and-Run」のように固定されたグラフ構造を予め持つのではなく、毎回の学習(Run)においてグラフ構造を動的に抽出・記憶し、メタな変更を加え、勾配を都度計算し直すというアプローチを採用する。
【0016】
これによって、事前にグラフを定義するミニ・プログラミング言語が不要となり、開発者にとってはその設計と実装とメンテナンスのコスト、ユーザにとってはその学習コストやデバッグの困難性が取り除かれるという効果がある。また、制御構文についても、一般的なプログラミング言語(CやJava(登録商標)やPython)が持つものを自由に用いることができるようになるため、より複雑なグラフ構造を持つニューラルネットワークも容易に実装可能となる。さらに、グラフに対するある種の条件付けによるメタな変更操作を可能にすることで、メモリ効率の向上や、モデルの柔軟な学習・適用が実現される。
【0017】
上述した従来技術に係る「Define-and-Run」と称される手法と、実施形態に係る「Define-by-Run」と称される手法との概念的な違いは、
図1と
図2とを対比することによっても明らかである。
図1は、従来技術に係る「Define-and-Run」と称される手法を概念的に示す模式図であり、
図2は、本発明の実施形態に係る「Define-by-Run」と称される手法を概念的に示す模式図である。
図1に示すDefine-and-runの構成では、まずミニ・プログラミング言語がモデル定義のみを入力し、計算グラフの実体であるフォワード(識別)処理とバックワード(学習)処理の計算手順を出力する(Defineステップ)。次のステップでFoward/Backwardの処理系がフォワード(識別)処理とバックワード(学習)処理の計算手順に従いデータの入力とパラメータ(重み)の更新を行う(Runステップ)ものである。
これに対して
図2に示すDefine-by-runの構成では、汎用プログラミング言語の処理系がモデル定義、入力データ、パラメータを入力しながらフォワード(識別)処理を実行すると同時にバックワード(学習)処理の計算手順を生成する。ここでモデル定義は関数呼び出しや四則演算、ループや分岐といった汎用プログラミング言語の文法にそのまま準拠して定義されたものである。バックワード(学習)処理の計算手順はフォワード(識別)処理の実行とは独立して動的に変更することもできる。任意のタイミングでBackwardの処理系を呼び出すことができる。Backwardの処理系はBackwardの計算手順に従って入力データとFoward処理の結果からパラメータを更新する。
【0018】
2.ニューラルネットワークに関連した背景技術
2-1.ニューラルネットワークの基本的な処理の流れ
ニューラルネットワークにおいて行われる処理には、主に、フォワード(Forward)処理、バックワード(Backward)処理、及び、重みの更新が含まれる。
フォワード処理とは、ニューラルネットワークの入力層から出力層に向かって情報を加工して伝播する処理をいう。
【0019】
バックワード処理とは、ニューラルネットワークの出力層から入力層に向かって、誤差逆伝播及び重み勾配算出という2つの処理を行うものをいう。誤差逆伝播とは、出力側の層から得られた誤差(δ)を入力側レイヤーに伝播する処理をいう。重み勾配算出とは、重みを有する層について、出力側の層から得られた誤差(δ)と入力側レイヤーの出力値から重みの勾配(∂W)を求める処理をいう。
【0020】
重みの更新とは、重みを有する層について、上記重み勾配算出により得られた重みの勾配(∂W)を用いて、確率的勾配降下法(SGD)から派生したアルゴリズムにより重みを更新する処理をいう。この重みの更新は、バッチ処理の単位ごとに1回実行される。
【0021】
2-2.ニューラルネットワークの実例において頻出する計算モジュール
ニューラルネットワークを構成する各層は、例えば次に列挙するレイヤーアルゴリズムにより実現されるものである。
-Linear
-ReLu
-Dropout
-Softmax Cross Entropy
-Convolution 2D
-Pooling(Average Pooling及びMax Pooling等)等
【0022】
重みの更新アルゴリズムの代表例としては、次のものが挙げられる。
-momentum-SGD
-Adam等
【0023】
2-3.ニューラルネットワークのネットワーク構成例(1)
図3は、ニューラルネットワークのネットワーク構成の一例を示す模式図である。
図3には、一例として、入力層と出力層(Softmax)との間に6つの中間層(Linear、ReLU、Linear、ReLU、Dropout及びLinear)が配置されたニューラルネットワークが例示されている。紙面上、右向きの矢印がフォワード処理を示し、左向きの矢印がバックワード処理を示す。
入力層は、更新すべき重みを持たないものであるので、バックワード処理は、この入力層に最も近い重みを有する中間層(
図3に示した例では、入力層に隣接して配置されたLinear層)まで行われる。
【0024】
2-4.ニューラルネットワークのネットワーク構成例(2)
図4は、ニューラルネットワークのネットワーク構成の別の例を示す模式図である。
図4には、一例として、入力層と出力層(Softmax)に隣接して配置された中間層(Linear)との間に、直列に配置された複数の中間層(Convolution 2D、ReLU、Convolution 2D、ReLU)が、複数(3つ)並列に配置されたニューラルネットワークが例示されている。紙面上、上向きの矢印がフォワード処理を示し、下向きの矢印がバックワード処理を示す。
【0025】
2-5.ニューラルネットワークのネットワーク構成例(3)
図5は、ニューラルネットワークのネットワーク構成のさらに別の例を示す模式図である。
図5には、一例として、ループを有するニューラルネットワーク(これは、「Recurrent Neural Network」と呼ばれることがある。)が例示されている。同図には、フォワード処理におけるデータの流れが矢印により示されている。中間層(ここではLinear)は、前回のこの中間層の出力値と今回の入力層の出力値とを加算したものをこの中間層の入力とする計算を実行する。このようなニューラルネットワークにおいてバックワード処理を実現する方法としては、予めネットワークを時間軸方向に展開してループのないネットワークに変換する方法(BPTT)が知られている。
【0026】
2-6.レイヤーアルゴリズムの計算内容(Linear)
レイヤーアルゴリズムの1つであるLinearは、入力側レイヤーの全ノードの加重平均を取る操作をその中間層内のノード数分だけ繰り返す計算を実行するものである。
図6は、Linearによりフォワード処理時に実行される計算を実現するための擬似コードを示す図であり、
図7は、Linearによりバックワード処理時に実行される計算を実現するための擬似コードを示す図である。
【0027】
2-7.レイヤーアルゴリズムの計算内容(ReLU)
レイヤーアルゴリズムの1つであるReLUは、入力側レイヤーの各ノードにMax(0,val)の計算を実行するものである。このアルゴリズムは、ニューラルネットワークの計算に非線形性を加える処理(活性化関数)で近年最も使われている手法である。
図8は、ReLUによりフォワード処理時に実行される計算を実現するための擬似コードを示す図であり、
図9は、ReLUによりバックワード処理時に実行される計算を実現するための擬似コードを示す図である。
【0028】
2-8.レイヤーアルゴリズムの計算内容(Dropout)
レイヤーアルゴリズムの1つであるDropoutは、ランダムに一定の割合のノードを選択し、出力及び誤差逆伝播を不活性化する計算を実行するものである。このアルゴリズムは、識別のみを実行する場合(すなわち、学習を実行しない場合)には、不要となるものである。
2-9.レイヤーアルゴリズムの計算内容(Softmax Cross Entropy)
レイヤーアルゴリズムの1つであるSoftmax Cross Entropyは、入力側レイヤーの値を以下の式により補正するものである。
【数1】
このレイヤーアルゴリズムは、一般に出力層で用いられる。
また、このレイヤーアルゴリズムは、バックワード処理時には、正解ラベル(1又は0)と出力値との差分から誤差を計算する。
【0029】
2-10.レイヤーアルゴリズムの計算内容(Convolution 2D)
レイヤーアルゴリズムの1つであるConvolution 2Dは、Channel*Width*Heightのデータ構造を有する画像を畳み込むものである。入力側レイヤーも、当該レイヤーの出力も、Channel*Width*Heightのデータ構造を有する。このアルゴリズムでは、ストライド処理により画像サイズの縮小も可能である。また、このアルゴリズムでは、入力側レイヤーの画像にパディングを挿入することが行われる。このアルゴリズムは、Channel方向に関しては、Linearと同様の計算構造(出力Channel回数だけ入力Channelの内積計算を繰り返す)を有する。
図10は、Convolution 2Dによりフォワード処理時に実行される計算を実現するための擬似コードを示す図である。
なお、Convolution 2Dは、バックワード処理時には、Linearと同様に重みの勾配計算及び誤差逆伝播を実行する。それぞれの処理のループの規模は、フォワード処理時におけるものと同様である。
【0030】
2-11.レイヤーアルゴリズムの計算内容(Max Pooling)
レイヤーアルゴリズムの1つであるMax Poolingは、入力側レイヤーの画像の最大値を取ることによってその画像を縦横方向に縮小するものである。なお、最大値を取るフィルタサイズと画像縮小のストライド幅とが異なる場合もある。また、Channel数に変化はない。
【0031】
2-12.レイヤーアルゴリズムの計算内容(Average Pooling)
レイヤーアルゴリズムの1つであるMax Poolingは、入力側レイヤーの画像の平均値を取ることによってその画像を縦横方向に縮小するものである。なお、平均値を取るフィルタサイズと画像縮小のストライド幅とが異なる場合もある。また、Channel数に変化はない。
【0032】
2-13.重みの更新アルゴリズム
重みの更新アルゴリズムとしては、確率的勾配降下法(SGD)から派生した様々なアルゴリズムが存在する。これらのアルゴリズムでは、重みの要素ごとに計算は独立している。
先に挙げたmomentum-SGDの計算式は次のとおりである。
【数2】
また、先に挙げたAdamの計算式は次のとおりである。
【数3】
【0033】
3.実施形態に係る学習装置のハードウェア構成
次に、本発明の実施形態に係る学習装置のハードウェア構成について説明する。
図11は、本発明の一実施形態に係る学習装置のハードウェア構成例を示す模式図である。
【0034】
学習装置10は、
図11に示されているとおり、CPU11と、メインメモリ12と、入力I/F13と、出力I/F14と、通信I/F15と、外部メモリ16と、ユーザI/F17と、を含み、これらの各構成要素が内部バス18を介して互いに電気的に接続されている。なお、学習装置10は、選択的にGPU(図示せず)を含むことも可能である。
【0035】
CPU11は、外部メモリ16からオペレーティングシステム、及び、プログラミング言語(例えばPython)をサポートするプログラム(ソースコードの作成に用いられるプログラム)等の様々なプログラムをメインメモリ12にロードし、ロードしたプログラムに含まれる命令を実行する。メインメモリ12は、CPU11が実行するプログラムを格納するために用いられ、例えば、DRAMによって構成される。
【0036】
入力I/F13は、測定装置(図示しない)の出力データを取り込む機能を有し、内部バス18によって、各構成要素と接続される。ここで、測定装置の出力である各種測定データは、センサ等で取得した情報、例えば、温度、湿度、位置情報、画像データなどを含み、動画データや温度のある一定間隔で取得された温度データ列など時系列データでもよい。出力I/F14は、内部バス18を通して各構成要素からデータを受信し、学習装置の外部にある出力装置(図示しない)に出力するものである。ここで、出力装置に出力されるデータは、例えばモータを駆動する際の制御情報や、ブザー、制御スイッチ、自動車のアクセルやブレーキ、液晶ディスプレイなどの情報出力装置に対する制御情報などが想定される。
【0037】
通信I/F15は、ハードウェア、ファームウェア、又は、TCP/IPドライバやPPPドライバ等の通信用ソフトウェア又はこれらの組み合わせとして実装され、通信網20を介して、図示しないサーバ装置と様々な情報を通信することが可能となるように構成される。
外部メモリ16は、例えば磁気ディスクドライブやフラッシュメモリ等により構成され、オペレーティングシステム及びプログラミング言語(例えばPython)をサポートするプログラム(ソースコードの作成に用いられるプログラム)等の様々なプログラムを記憶する。
【0038】
以上の構成を有する一実施形態に係る学習装置10は、CPU11(選択的にはこれに加えてGPU)が、外部メモリ16からメインメモリ12にロードした所定のプログラムを実行することによって、機械学習を行う学習装置として機能することができる。例えば、機械学習を行う学習装置10は、CPU11(選択的にはこれに加えてGPU)が様々なプログラムを実行することにより、ニューラルネットワークによりモデル化された学習装置として実現され得る。
【0039】
上記構成を有する学習装置10は、対応する個体(機器)に搭載されるものとすることができる。また、学習装置10は、対応する測定装置、及び、対応する出力装置に接続されるものとすることができる。これらの測定装置及び出力装置は、対応する個体(機器)に搭載される場合もあるし、別の機器として通信手段を使って接続される場合もある。
【0040】
学習装置10は、一実施形態において、機械学習を実行可能な任意の情報処理装置であり、例えば、パーソナルコンピュータ、タブレット、携帯電話機、スマートフォン、携帯情報端末、タッチパッド、及び、情報処理サーバ等を含むが、これらには限られない。
【0041】
4.実施形態に係る学習装置の機能ブロック
次に、上記構成を有する学習装置10が有する機能について簡単に説明する。
図12は、本発明の一実施形態に係る学習装置が有する機能例を模式的に示すブロック図である。
【0042】
実施形態に係る学習装置10は、上述したように「Define-by-Run」と呼ばれる手法に基づくものである。具体的には、実施形態に係る学習装置10は、ニューラルネットワークのフォワード処理を、分岐、ループ及び関数呼び出しを含む一般的な手続き型言語により実行するタイミングで、バックワード処理及び重み更新の処理に必要なネットワーク構成の情報が動的に生成されることによって、実際にバックワード処理及び重み更新の処理を実行することができる仕組みを具備するものである。
【0043】
このような「Define-by-Run」を実現するために、
図12に示すように、一実施形態に係る学習装置10は、主に、取得部110と、記憶部120と、実行部130とを含む。取得部110は、ニューラルネットワークを構成する各層のフォワード処理を定義したコードを含むソースコードを取得するものである。具体的には、かかるソースコードは、開発者やユーザ等によりテキストエディタを用いて所定のプログラミング言語(例えばPython等)を用いて作成されたものであり、取得部110は、このようなソースコードを取得する。
かかる取得部110は、例えば、
図11に示したCPU11、メインメモリ12、外部メモリ16及びユーザI/F17等が協働することによって、実現されるものとすることができる。
【0044】
記憶部120は、ソースコードにおいて定義可能な複数のフォワード処理の各々と該フォワード処理に対応するバックワード処理との対応関係を記憶するものである。記憶部120に記憶された対応関係では、複数のフォワード処理に含まれる或るフォワード処理には、対応するバックワード処理が1対1の関係により対応付けられている。すなわち、記憶部120に記憶された対応関係では、例えば、Linearというレイヤー(中間層)については、Linearに対応したフォワード処理と、このフォワード処理に対応したバックワード処理とが、対応付けられている。(このようにフォワード処理とバックワード処理との1対1で対応付けられた対応関係は、バックワード処理のための参照構造を用いてバックワード処理を実行する際に、フォワード処理に対応した処理を実行するために用いられる。例えば、フォワード処理をA→B→Cという順番で実行すると、バックワード処理は、C→B→Aという順番で実行されるところ、A~Cのそれぞれの関数に対して、フォワード処理及びバックワード処理という両方の処理がペアで実装されていることによって、このようなバックワード処理を実現することができる。)
なお、記憶部120は、取得部110に取得されたソースコード、及び、このソースコードに対応するプログラミング言語において用いられる様々なライブラリ等を含む様々な情報を記憶することができる。
かかる記憶部120は、例えば、
図11に示したCPU11、メインメモリ12及び外部メモリ16等が協働することによって、実現されるものとすることができる。
【0045】
実行部130は、取得部110に取得され(記憶部120に記憶され)たソースコードに含まれた各コードを順次実行するものである。この実行部130は、各コードを実行した時点において、該コードにより定義されたフォワード処理の出力値を入力値に基づいて計算することができる。また、この実行部130は、各コードを実行した時点において、該コードに対応する層におけるオブジェクト間の参照構造を生成することができる。
かかる実行部130は、例えば、
図11に示したCPU11、メインメモリ12及び外部メモリ16等が協働することによって、実現されるものとすることができる。
【0046】
また、上述した「Define-by-Run」という手法を実現するために、一実施形態に係る学習装置10は、上述した取得部110、記憶部120及び実行部130を用いることによって、3つのクラス、すなわち、Function、Variable及びOptimizerという3つのクラスを利用する。なお、これらのクラスの名称は、便宜的に付されたものであって、限定的なものではない。
まず、Functionというクラスは、フォワード処理とバックワード処理とをペアにして定義したクラスである。このFunctionというクラスは、上記「2-6」~「2-12」で例示した具体的なレイヤーアルゴリズムをサブクラスで定義するものである。
次に、Variableというクラスは、Function間で入出力されるデータを管理するクラスである。このVariableというクラスは、GPUとCPUとの違いを隠蔽する役割を有するものであり、また、ループを含むネットワークのバックワード処理を有限範囲で打ち切るためのメソッド(後述するunchain_backward)を有する。
さらに、Optimizerというクラスは、重みの更新を行うクラスである。
【0047】
5.動作例1
次に、上記構成を有する実施形態に係る学習装置10によりなされる動作の具体例について説明する。
図13は、本発明の一実施形態に係る学習装置に入力されるソースコードの一例を示す図である。なお、
図13に例示されたソースコードは、本実施形態に係る学習装置の特徴を説明することを目的として意図的に簡略化されたものであることに留意されたい。また、
図13において左端に記載された行数は、本具体例を説明するために付されたものであって、実際のソースコードには含まれない。
以下、本実施形態では、ソースコードが一例としてPythonにより記述される場合について説明するが、ソースコードはPython以外のプログラミング言語により記載されるものであってもよい。Phythonの詳細は、https://www.python.org/に開示されている。このURLに開示された内容は、引用によりその内容の全体が本明細書に組み込まれる。
【0048】
まず、開発者等が
図13に例示されたソースコードをテキストエディタ等を利用して作成する。このように作成されたソースコードを学習装置10の取得部110(
図12参照)が取得して記憶部120に記憶させる。次に、実行部130が、記憶部120に記憶されたソースコードに含まれた各コードを1行ずつ実行する。
図13に例示されたようにソースコードにif文やfor文等の制御構文が含まれていない場合には、実行部130は、第1行から最終行まで上から下に向かって1行ずつ順次実行する。逆に、ソースコードに制御構文が含まれている場合には、実行部130は、制御構文に従った順序により各コードを実行する。
【0049】
図13に例示されているソースコードの内容について説明する。
第1行~第3行は、FunctionSetによるパラメータを含むFunctionの登録を記述している。具体的には、ここでは、FunctionSetというクラスのオブジェクトに重みを含むFunction(本例では内積を行うレイヤーアルゴリズムを定義したFunctionサブクラスであるLinearクラスのインスタンスl1,l2,l3)を登録している。重みを含むFunctionはOptimizerによりその重みを更新できる。FunctionSetは、Optimizerによって更新されるFunctionをひとまとめにすることでコードの可読性を高めるための仕組みである。
【0050】
第4行及び第5行は、Optimizerの初期化を記述している。第4行でAdamというアルゴリズムを実装したOptimizer(重みを更新するためのクラス)サブクラスのインスタンスを生成している。Adamの処理内容は、上記「2-13」に記載した数式による更新を重みの要素ごとに実行するものである。第5行では、第4行で生成したOptimizerサブクラスのインスタンスのsetupメソッドに対して、第1行~第3行で定義済みの重みを含むFunctionの一覧を渡している。このsetupメソッドの実行により、本メソッドに渡されたFunctionの一覧に含まれる重みを更新するためのOptimizerサブクラスの内部状態が初期化される。
【0051】
第6行は、入力データのロードを記述している。すなわち、第6行は、入力データxおよびtをファイルなどから読み込む処理を例示している。本例において、xには画像や音声など情報量の多いデータが保持され、tにはxに対応するラベルID(答え合わせのための情報量の少ないデータ)が保持される。
【0052】
第7行は、入力データのVariableオブジェクトによる保持を記述している。すなわち、第7行において、入力データを保持するVariableクラスのオブジェクトを生成する。「Define-by-Run」の機能は、VariableオブジェクトとFunctionオブジェクトとが相互依存することで実現されており、任意の入力データは「Define-by-Run」の機能を実現するための仕組みを有していないため、明示的にVariableクラスのインスタンスによって保持する手続きが必要となる。
【0053】
第8行~第11行は、フォワード処理の実行を記述している。具体的には、第8行~第11行において、一般的なプログラミング言語の記述によりForward処理を実行する。「Define-by-Run」の機能により、本定義の実行と同時にバックワード処理のための参照構造が生成される。FunctionクラスのインスタンスとVariableクラスのインスタンスが相互に参照することで、任意の処理とデータの対応関係を表現できる。Variableクラスはデータを代表し、Functionクラスは処理を代表するのであるからこのことは自明である。この参照構造を用いて
図2に示すBackwardの計算手順を表現するデータ構造を構築したものをバックワード処理のための参照構造と定義する。バックワード処理のための参照構造は、Variableオブジェクトに対する基本的な計算(四則演算やべき乗)及びVariableオブジェクトを引数や戻り値とするFunctionの呼び出しが行われる都度成長する。よって、分岐やループ、FunctionやVariableに対するもの以外の関数呼び出しを含むフォワード処理の記述であっても、バックワード処理のための参照構造を生成することができる。Variableオブジェクトに対する基本的な計算にもそれぞれFunctionサブクラスが対応付いている。
【0054】
第12行は、バックワード処理の実行を記述している。具体的には、第12行は、第8行~第11行で実行したフォワード処理の実行結果として得られたloss変数(Variableクラスのインスタンス)のバックワードメソッド呼び出しにより、バックワード処理を実行する。バックワード処理は、フォワード処理実行時に生成されたバックワード処理のための参照構造をたどることでフォワード処理とは逆の順序で自動的に実行される。
【0055】
第13行は、重みの更新を記述している。具体的には、第13行では、第12行でバックワード処理を実行した結果として重みの勾配が算出される。第13行のようにOptimizerサブクラスのインスタンスのupdateメソッドを呼び出すと、この重みの勾配を用いて重みが更新される。Optimizerサブクラスに対するupdateメソッドの呼び出しとVariableクラスのbackwardメソッドの呼び出しとは別関数となっているので、部分的にバックワード処理を実行した後、重みの更新を実行することもできる。これは、すでに学習済みのFunctionに対して重みの更新を行いたくない場合に有効である。
【0056】
ここで、フォワード処理時に処理される内容として、特に第8行に記述されたコードによって処理される内容に着目する。
第8行は、h1=F.relu(model.l1(x))と記述している。
【0057】
“model.l1(x)”の実行時には、以下のようなバックワード処理のための参照構造が生成される。
【数4】
上記参照構造において、x'はxをコピーしたVariableオブジェクトを表し、l1’はl1のコピー(浅いコピー)を表し、yはl1’のforwardメソッドが返す値(Variableオブジェクト)を表し、splitterはネットワークの分岐を管理するクラスのインスタンスを表す。
浅いコピーとはオブジェクトをコピーする際に、オブジェクトが内部的に参照するデータをコピーしないようなオブジェクトのコピー方法である。浅いコピーとすることで例えばFuntionのインスタンスが持つ重みのデータの重複を避けることができる。
また、矢印の意味はオブジェクトの参照の方向を表す。例えばA←Bという記述はBのオブジェクトのメンバにAのオブジェクトへの参照が含まれることを意味する。
【0058】
上記参照構造は、“F.relu(”の実行後には以下のようなバックワード処理のための参照構造となる。
【数5】
ここでは、第8行に記述されたコードの実行時にバックワード処理のための参照構造が生成される場合について説明したが、第9行及び第10行に記述されたコードの実行時においても同様に参照構造が生成されることはいうまでもない。
以上のように、フォワード処理の実行時には、自然な形式の関数呼び出しによってバックワード処理のための参照構造が生成される。
この時点で、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までたどるとバックワード処理は終了となる。
【0059】
なお、Splitterが参照構造に挿入される理由について念のため説明する。
上記参照構造の作成直後に“model.l1(x)”をもう一度コールすると以下のような参照構造が生成される。
【数6】
上記参照構造において、l1''はl1のコピー(浅いコピー)を表し(l1’とは別インスタンス)、x''はxをコピーしたVariableオブジェクトを表し(x’とは別インスタンス)、zはl1''のforwardメソッドが返す値(Variableオブジェクト)を表す。
【0060】
バックワード処理時に誤差値を出力側レイヤーから伝播する際、splitterのインスタンスがx’とx''にそれぞれ伝わる誤差の値を加算合成した結果をxの誤差として設定する。このようにsplitterを挿入することで、フォワード処理時にxを入力として用いた全てのFunctionからバックワード処理時に誤差を伝播することができる。
【0061】
次に、
図13に例示されたソースコードを実行した際に生成されるニューラルネットワークのネットワーク構成について補足する。
図14は、
図13に示されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。なお、
図14において、点線により描かれたブロックは、変数のインスタンスを示し、実線により描かれたブロックは、関数を示す。
【0062】
まず、第7行が実行された時点では、変数xのインスタンス30及び変数tのインスタンスが生成される。説明の便宜上、
図14には、変数xのインスタンス30のみしか示されていないが、実際には、変数tのインスタンスも同様に生成される。第7行が実行された時点では、変数xのインスタンスには、実際に画像や音声などのデータが保持されている。
【0063】
次に、実行部130により第8行が実行された時点では、変数xのインスタンス30の後に、関数「l1」31、関数「relu」32及び変数h1のインスタンス33が順次成長した状態のニューラルネットワークが生成される。第8行が実行された時点では、第8行に記述されたフォワード処理の実行結果が既に変数h1のインスタンス33により保持されていることに留意されたい。また、第8行が実行された時点では、上述したように、現時点において生成されているバックワード処理のための参照構造が生成される。
【0064】
次に、実行部130により第9行が実行された時点では、変数h1のインスタンス33の後に、関数「l2」34、関数「relu」35及び変数h2のインスタンス36が順次成長した状態のニューラルネットワークが生成される。第9行が実行された時点では、第9行に記述されたフォワード処理の実行結果が既に変数h2のインスタンス36に保持されていることに留意されたい。また、第9行が実行された時点では、上述したように、現時点において生成されているバックワード処理のための参照構造が生成される。
【0065】
同様に、実行部130により第10行が実行された時点では、変数h2のインスタンス36の後に、関数「l3」37及び変数yのインスタンス38が順次成長した状態のニューラルネットワークが生成される。第10行が実行された時点では、第10行に記述されたフォワード処理の実行結果が既に変数yのインスタンス38に保持されていることに留意されたい。また、第10行が実行された時点では、上述したように、現時点において生成されているバックワード処理のための参照構造が生成される。
【0066】
最後に、実行部130により第11行が実行された時点では、変数yのインスタンス38の後に、関数「Softmax」39及び変数lossのインスタンス40が順次成長した状態のニューラルネットワークが生成される。第11行が実行された時点では、第11行に記述されたフォワード処理の実行結果が既に変数lossの新スタンス40に保持されていることに留意されたい。また、第11行が実行された時点では、上述したように、現時点において生成されているバックワード処理のための参照構造が生成される。第11行が実行された時点において、ソースコードに記述されたフォワード処理は完了している。すなわち、第11行が実行された時点において、最終的に得られたニューラルネットワークにより行われた識別の結果と変数tによって与えられる真の識別結果との差分が変数lossのインスタンス40に保持されている。この差分を入力として次のステップのバックワード処理が実行される。
【0067】
第8行~第11行に記述されたフォワード処理が完了した後、次に、実行部130により第12行が実行されることにより、バックワード処理が実行される。生成されたバックワード処理のための参照構造が既に生成されているため、実行部130は、この参照構造に基づいてバックワード処理を実行することにより、ニューラルネットワークに含まれた各中間層(但し、重みを有する中間層のみ)の重みの勾配を算出することができる。
【0068】
次に、実行部130により第13行が実行される。これにより、第12行の実行により算出された重みの勾配を用いて、各中間層(但し、重みを有する中間層のみ)の重みが更新される。すなわち、学習が実行される。
【0069】
このように、本実施形態に係る学習装置にあっては、開発者等は、フォワード処理に関しては、いずれの変数のインスタンスをいずれの関数に与えることによって得られた実行結果をいずれの変数のインスタンスに保持させるかを1行ずつ記述する方式により、ニューラルネットワークを構築することができる。これにより、開発者等は、フォワード処理をソースコードにおいて直感的に記述することを容易に行うことができる。また、開発者等は、ソースコードにおいて(バックワード処理を意識する必要なく)フォワード処理を記述し、そのソースコードを本実施形態に係る学習装置に実行させることにより、自動的にバックワード処理を学習装置に実行させることができる。
【0070】
6.比較例1
次に、本実施形態に係る学習装置の優位性を示すために、
図13に例示したソースコードにより実行されるものと等価な処理を従来技術に係るCaffeにより記述した場合について説明する。
図15は、従来技術に係るCaffeにより記述されたソースコードの一例を示す図である。
【0071】
図15に示すように、「layer」という用語の直後に記載された{}で囲まれたブロックにレイヤー(本実施形態におけるFunctionに対応するもの)の定義が記述されている。この従来技術に係る手法では、レイヤー間の依存関係をコード中に明示する必要がある。例えば、「top」及び「bottom」という記述がレイヤー同士の依存関係を表している。「bottom」は、レイヤーに対する入力がどのレイヤーから得られるかを表し、「top」は、レイヤーでの処理結果がいずれのレイヤーに出力されるのかを表す。
【0072】
この従来技術に係る手法では、ニューラルネットワークで行われる学習及び識別の処理に先んじて静的にネットワークの構成を定義しておく必要がある。すなわち、ニューラルネットワークのネットワーク構成をまず定義し、その後に、そのニューラルネットワークの学習及び識別を実行させる必要がある。よって、データの性質に応じてネットワークの構成を動的に変更することが困難である。
これに対して、本実施形態に係る学習装置では、
図14を参照して上述したように、ニューラルネットワークの構成を定義する各コードを実行した時点において、そのコードに対応するフォワード処理が実行される。すなわち、ニューラルネットワークの構成の定義とその構成によるフォワード処理の実行とが同じタイミングで実行される。これにより、データの性質に応じてネットワークの構成を動的に変更することも容易に行うことができる。例えば
図13のコードに分岐を加えて変数tの値や、変数xのデータサイズに応じて、フォワード処理を実行するレイヤーを切り替えても良い。また例えば
図19のコードで9行目の定数「10」の代わりに可変な値を入力データとして与えることもできる。
【0073】
また、従来技術に係る手法では、開発者等は、ソースコードを作成する際に、フォワード処理及びバックワード処理の両方を適切に実行できるように、ニューラルネットワークのネットワーク構成の定義を記述する必要がある。これに対して、本実施形態に係る学習装置では、
図14を参照して上述したように、バックワード処理が適切に実行できるかどうかを意識する必要なく、単にフォワード処理(ネットワーク構成)を記述した後、ソースコードを学習装置に実行させることによって、学習装置が自動的にバックワード処理を実行する。したがって、開発者等は、簡単かつ効率的にニューラルネットワークを構築して識別及び学習を実行させることができる。
【0074】
さらに、従来技術に係る手法では、開発者等は、ソースコードを作成する際には、フォワード処理及びバックワード処理の両方を適切に実行できるように、ニューラルネットワークを定義した後、そのように定義されたニューラルネットワークに対してデータ(入力データ及び教師データ等)を代入する、という手順を踏む。したがって、ソースコードを直感的に記述することが困難である。
これに対して、本実施形態に係る学習装置では、開発者等は、フォワード処理(ネットワーク構成)を1行ずつ記載する時点において、いずれの変数のインスタンスをいずれの関数に与えることによって得られた実行結果をいずれの変数のインスタンスに保持させるかを1行ずつ記述する方式により、ソースコードを記述する。これにより、開発者等は、ソースコードを直感的に記述することができる。
【0075】
7.動作例2
次に、上記構成を有する実施形態に係る学習装置10によりなされる動作の別の具体例について説明する。
図16は、本発明の一実施形態に係る学習装置に入力されるソースコードの別の例を示す図である。なお、
図16に例示されたソースコードは、本実施形態に係る学習装置の特徴を説明することを目的として意図的に簡略化されたものであることに留意されたい。また、
図16において左端に記載された行数は、本具体例を説明するために付されたものであって、実際のソースコードには含まれない。
【0076】
図16に示されたソースコードを参照して、本実施形態に係る学習装置によれば、制御構文(ここではfor文)を用いて容易にニューラルネットワークを構築することも可能である点について説明する。
【0077】
第1行~第3行については、
図13に示したソースコードにおける第1行~第5行と同様であるので、詳細な説明を省略する。
第4行は、iの値が0~1000になるまで第5行~第10行に記述された処理をループ処理することを記述している。
第5行及び第6行については、
図13に示したソースコードにおける第6行及び第7行と同様であるので、詳細な説明を省略する。
第7行は、関数l1及び関数reluの処理結果であるyを再度l1の引数に足し込むことを記述している。
第8行~第10行については、
図13に示したソースコードにおける第11行~第13行と同様であるので、詳細な説明を省略する。
【0078】
図17は、
図16に示されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。なお、
図17において、点線により描かれたブロックは、変数のインスタンスを示し、実線により描かれたブロックは、関数を示す。また、
図17は、説明の便宜上、変数iが0~2である場合のみに生成されるニューラルネットワークの構成しか示していない。
【0079】
図16及び
図17から明らかであるように、本実施形態に係る学習装置では、変数のインスタンス及び関数を含んだ同一の構成(ここでは、変数xのインスタンス51と変数yのインスタンス50とを加算する関数52の後に、関数「l1」53及び関数「relu」54が順次続き、関数「relu」54の出力値が変数yのインスタンスに保持されるような構成)を複数繰り返すようなニューラルネットワークであっても、簡単な制御構文(ここではfor文)を用いて簡単に構築することができることが分かる。すなわち、本実施形態に係る学習装置において用いられるソースコードは、プログラミング言語の制御構文と親和性の高いものであることが分かる。
【0080】
8.比較例2
次に、本実施形態に係る学習装置の優位性を示すために、
図16に例示したソースコードにより実行されるものと等価な処理を従来技術に係るCaffeにより記述した場合について説明する。
図18は、従来技術に係るCaffeにより記述されたソースコードにより生成されるニューラルネットワークのネットワーク構成を概念的に示す模式図である。
【0081】
図16及び
図17に例示したものと同様のニューラルネットワークを従来技術に係るCaffeにより構築しようとする場合には、制御構文を用いてニューラルネットワークの構成を定義することができないため、開発者等は、まず、
図18に示すような基本的な構成を定義する。次に、開発者等は、関数72に対して変数yのインスタンス75の初期値を与えるとともに、関数72に対して前時間における変数yのインスタンス75と現時間における変数xのインスタンス71とを与える(
図18における太線で描かれた矢印の部分)処理を特別に記述しなくてはならない。上記基本的な構成が多数繰り返されるようなニューラルネットワークを構築する場合、又は、多層構造を有するニューラルネットワークを構築する場合には、開発者等は、そのように多数繰り返す都度、又は、多層構造における各層ごとに、かかる特別な記述をしなくてはならない。
【0082】
これに対して、本実施形態に係る学習装置では、
図16及び
図17に例示したとおり、記述されるソースコードは、プログラミング言語の制御構文を用いて特別な記述を必要とすることなく簡単に記述可能なものである。したがって、本実施形態に係る学習装置によれば、複雑な又は大規模なニューラルネットワークであっても、簡単かつ効率的に構築することができる。
【0083】
9.付加的な機能(1)について
一実施形態に係る学習装置は、バックワード処理のための参照構造を断ち切る関数を実行することが可能であってもよい。
具体的には、Variableクラスのインスタンスのunchain_backwardメソッドがコールされると、そのインスタンスを起点に入力側へと向かうバックワード処理のための参照構造が断ち切られる。例えば、以下のようなバックワード処理のための参照構造がフォワード処理の実行により生成されていたとする(splitterなどの詳細な構成は省略して示す)。
【0084】
A(入力層)←Convolution2D←B←Linear←C←Softmax←D(出力層)
ここで、A,B,C,DはVariableクラスのインスタンスを表し、Convolution2D, Linear, SoftmaxはFunctionクラスのインスタンスを表す。
【0085】
このとき、B. unchain_backward()をコールするとバックワード処理のための参照構造はBを起点に断ち切られる結果、以下のように変化する。
B←Linear←C←Softmax←D(出力層)
【0086】
このunchain_backwardメソッドを
図16に示したソースコードに適用する局面について検討する。このソースコードにおいて、第7行では、関数l1及び関数reluの処理結果であるyを再び関数l1の引数に足し込んでいる。「Define-by-Run」の仕組みでは、”x+y”の記述を実行する際に、yのコピーが生成された上で、これまで実行されたフォワード処理によって生成済みのバックワード処理のための参照構造が連結される。よって、本例ではループが繰り返されるごとにバックワード処理のための参照構造が成長し続ける。
第9行で実行されるバックワード処理は、成長したバックワード処理のための参照構造に対して実行される。第9行の処理は、ループ内に含まれているため、このループ処理全体の計算時間は、ループサイズの2乗に比例してしまう。
【0087】
図19は、本発明の一実施形態に係る学習装置に入力されるソースコードのさらに別の例を示す図である。なお、
図19において左端に記載された行数は、本具体例を説明するために付されたものであって、実際のソースコードには含まれない。
【0088】
図16に示したソースコードを変更し、
図19に示すように、第11行においてunchain_backwardを定期的に呼び出すことにより、計算時間の増加を抑えることができる。
第9行は、第4行以降のループが10回実行される度に、第10行~第12行の処理が実行されることを記述している。
第11行は、unchain_backwardをコールし、lossを起点にバックワード処理のための参照構造を破棄している。これにより、ループ処理全体の計算時間を短く抑えることができる。
【0089】
このようにunchain_backwardを用いることにより、参照構造にループを有するフォワード処理に対して学習を行う場合であっても、バックワード処理のための参照構造の過剰な成長を抑え、現実的な計算量で学習処理を実行することができる。
さらに、別の実施形態では、特定のFunctionについて重みの更新を行わないようにすることを目的として、unchain_backwardを用いることも可能である。
【0090】
10.付加的な機能(2)について
一実施形態に係る学習装置は、Variableクラスのインスタンス初期化時にvolatile属性を指定することができる。volatile属性が有効な場合には、そのVariableを入力するフォワード処理についてバックワード処理のための参照構造は生成されない。
【0091】
学習済みの重みを用いてフォワード処理のみを実行する場合(すなわち、バックワード処理を実行する必要がない場合)には、フォワード処理の実行時にバックワード処理のための参照構造を生成する処理が実行されてしまうと、実行速度及びメモリ使用量の両方において無駄が発生してしまう。このような場合に、フォワード処理の入力データを保持するVariableクラスのインスタンス初期化時にvolatile属性を指定しておくことにより、バックワード処理のための参照構造の生成を止めて、効率的にフォワード処理のみを実行することができる。
【0092】
11.付言
最も好ましい実施形態として、Pythonにより記述されたソースコードが学習装置に入力される実施形態を説明してきたが、本明細書に開示された技術は、Pythonにより記述されたソースコードを用いた場合のみに限定されるものではない。すなわち、本明細書に開示された技術は、学習装置が各コードを実行した時点においてそのコードに記述されたフォワード処理の出力値を入力値に基づいて計算すること、学習装置が各コードに記述されたフォワード処理を実行する度にバックワード処理のための参照構造を生成(してこの参照構造に基づいてバックワード処理を実行可能に)すること、及び、制御構文を用いてニューラルネットワークの構成を定義すること、のうちの少なくとも1つを実現することが可能なPythonと等価なプログラミング言語(例えば、R、Julia、Sparkz及びMLib等)により記述されたソースコードを用いた場合にも、同様に適用可能なものである。
【0093】
本明細書に開示された技術は、Python及びこれと等価なプログラミング言語により記述されたソースコードを実行することによって実現可能なものであり、これに代えて、Python及びこれと等価なプログラミング言語により記述されたモジュール又はライブラリを実行することによって実現可能なものであってもよい。
【0094】
本明細書において、変数、関数、メソッド、クラス、サブクラス等を識別するために用いられた名称は、本明細書に開示された技術を限定するものではなく、任意のものであってよい。
【0095】
本明細書で説明される処理及び手順は、実施形態において明示的に説明されたものによってのみならず、ソフトウェア、ハードウェア又はこれらの組み合わせによっても実現可能なものである。具体的には、本明細書で説明された処理及び手順は、集積回路、揮発性メモリ、不揮発性メモリ、磁気ディスク、光ストレージ等の媒体に、当該処理に相当するロジックを実装することによって実現される。また、本明細書で説明された処理及び手順は、それらの処理・手順をコンピュータプログラムとして実装し、各種のコンピュータに実行させることが可能である。
【0096】
本明細書中で説明される処理及び手順が単一の装置、ソフトウェア、コンポーネント、モジュールによって実行される旨が説明されたとしても、そのような処理又は手順は、複数の装置、複数のソフトウェア、複数のコンポーネント、及び/又は、複数のモジュールによって実行されるものとすることができる。また、本明細書中で説明されるデータ、テーブル又はデータベースが単一のメモリに格納される旨説明されたとしても、そのようなデータ、テーブル又はデータベースは、単一の装置に備えられた複数のメモリ又は複数の装置に分散して配置された複数のメモリに分散して格納されるものとすることができる。さらに、本明細書において説明されるソフトウェア及びハードウェアの要素は、それらをより少ない構成要素に統合して、又は、より多い構成要素に分解することによって実現されるものとすることができる。
【0097】
第2部(アルゴリズムの組み込み系チップへの実装手法)
1.背景
ディープラーニング(深層学習)は、その高い性能を得られる反面、大規模な演算量及びメモリ使用量、並びに、学習サンプル量を要求するアルゴリズムである。潤沢な計算資源を安価に得られるGPU及びクラウド、並びに、学習サンプルの共有を可能とするWebインフラの普及が、近年のディープラーニングの隆盛を支える背景にあったといえる。
ディープラーニングのアルゴリズム開発を支援する環境(ライブラリ、フレームワーク)には様々なものが存在する。多くの開発環境はGPUを用いて学習速度を向上させる機能を有している。
【0098】
自動車の完全自動運転や汎用性の高いロボット制御といった分野では、カメラやLIDAR(レーザー距離測定)といった様々なセンサーからの取得した情報をリアルタイムに解析し、無数のモーターをコントロールしてその課題を解決するための高度な情報処理能力が要求されるので、従来とは一線を画す性能を持つディープラーニングの応用が強く期待されている。
しかしながら、こうした分野は、安全性やチップ価格、消費電力などの要請からGPUやクラウドと比べると計算資源に乏しい組み込み環境に依存しているため、高い計算資源を必要とするディープラーニングの応用が遅れている。
組み込み環境へのディープラーニングの応用が遅れている要因は、こうしたアルゴリズムの計算資源への要求が現実的・経済的な組み込み環境の性能を超えているという側面の他に、ソフトウェア環境を初めとしてディープラーニングをサポートする実装が出揃っていない面も挙げられる。
組み込み環境においても、ハードウェアの性能は年々向上しており、ディープラーニングのアルゴリズムにおいても、計算資源への要請を緩和する改良が継続しているので、前者の要因は徐々に解決していくものと考えられる。
【0099】
本発明の実施形態が解決すべき課題は、組み込み系チップにおいて製品レベルの要求を満たした上で動作するディープラーニングのアルゴリズムを設計するためのフレームワーク開発により、主にソフトウェア環境面で残っているディープラーニングの組み込み環境適応への障壁を突破し、開発速度を促進するためのものである。
GPUベースではありながらディープラーニングのアルゴリズム開発において高い生産性をもたらすフレームワークである上記第1部において述べた実施形態に係る学習装置を、組み込み環境向けに機能拡張することが本課題を解決する上で最適な手段と考えられるので、次段落以降では実施形態に係る学習装置にフォーカスした組み込み環境適応への課題を述べる。
【0100】
2.実施形態に係る実装手法の課題
上記第1部において説明した実施形態に係る学習装置は、高度な言語機能やライブラリに依存しているので、この学習装置において動作するアルゴリズムをそのまま組み込み系半導体チップ上で動作させようとすることは、以下のような弊害をもたらす可能性がある。
まずセキュリティ面に関して、ライブラリや言語の規模が大きくなると事実上不可知な実装にアプリケーションが依存する度合いが高まる。それにつれて、そうした実装に含まれる不具合が、そのままチップ製品の不具合となってしまうリスクが高まる。
次に、フットプリント面に関して、ライブラリや言語の実装自体がチップ製品のメモリ資源を圧迫する。
さらに、オーバーヘッド面に関して、高度に抽象化したAPIを持つライブラリ経由では、チップ製品の計算資源をフル活用できない。少なくともニューラルネットワークで必要とされる大規模計算についてはチップに特化した低レベルなパフォーマンスチューニングが必須となる。
以上のような理由から、実施形態に係る学習装置において動作するアルゴリズムをそのまま組み込み系半導体チップ上で動作させるだけでは、製品レベルの要求を満たせない可能性が高い。
【0101】
3.実施形態に係る実装手法のコンセプト
実施形態に係る実装手法では、豊富な計算資源を有するパーソナルコンピュータ等において設計した新規のニューラルネットワーク(NN)のアルゴリズムを任意の組み込みチップ(組み込み系半導体集積回路)において製品レベルの要件を満たした上で動作できる状態を最短期間で実現する。そのためには、アルゴリズムを設計する開発者と、ハードウェアを深く意識する開発者とがなるべく独立して仕事を進められることが望ましい。本実施形態では、それを助ける装置(フレームワーク)に関する技術的思想を提案する。
【0102】
4.組み込みチップ開発で想定される開発ステップ
組み込み系チップを開発する際に辿るステップとして、以下の3つのステップが想定される。
ステップI:PC(+GPU)上で実施形態に係る学習装置に用いられるコード(一例としてPythonで記述されたコード)が動いている状態
この状態は、複雑な構成を有するニューラルネットワークを用いたアルゴリズムの設計・検証を少ないコード記述で実現した状態である。これは、上述した「Define-by-Run」という手法のコンセプトである。
ステップII:チップ向けに最適化した実装とPythonコードとが混在した状態
この状態は、実施形態に係る学習装置で設計したアルゴリズムのチップ上での動作確認及びパフォーマンス検証をPythonコードをほとんど変えずに実現した状態である。
ステップIII:チップ向けに最適化した実装のみで実施形態に係る学習装置で設計したアルゴリズムが動作する状態
この状態は、チップとしての製品レベルの仕様要件を満たした上でアルゴリズムが動作する(チップ上で他のモジュールや制御機構とのリアルタイム性の高い協調動作ができる)状態である。
本実施形態に係る実装手法では、実施形態に係る学習装置で新しいアルゴリズムを開発するときに、上記ステップI~IIIのステップ間において、なるべく再修正、再設計及び再学習の手間を省くことにより、短期間で開発を進められるようなフレームワークを提案する。
【0103】
4-1. ステップIについて
図20は、本発明の実施形態に係る実装手法のステップIを説明する模式図である。
図20に示された構成は、上記第1部において説明した実施形態に係る学習装置が前提としている構成である。すなわち、この構成は、プログラミング言語の一態様としてのPythonで記述されたソースコードが、ライブラリの一態様としてのPyCUDA及びライブラリの一態様としてのnumpy(BLAS)を利用し、これらのライブラリがそれぞれGPU及び汎用計算機をドライブするものである。なお、
図20に示された「Chainer」とは、上記第1部において述べた実施形態に係る学習装置において用いられるソースコードを記述するためのフレームワークに対して本件出願人により付された名称である。
【0104】
4-2.ステップIIについて
図21は、本発明の実施形態に係る実装手法のステップIIを説明する模式図である。
図21に示された構成では、Python上でChainerのフロントエンドを実行する。
図21に示すように、本実施形態では、Native I/F(例えばC言語など低水準の言語で記載されたChainerの主要機能と同等な実装を呼び出すためのインターフェイス)を設けることで、PC上の実行と組み込みチップ向けに最適化した実行とを同一コードで実行できる。
【0105】
図22は、Pythonによる実行部とチップによる実行部とが通信する場合を説明する模式図である。
図22に示すように、Native I/Fの実装に通信機能を設けることで組み込みチップ上の構成からPythonへの依存を取り除くことも可能(PC上のChainerから組み込みチップ上の最適化実装をドライブする)である。
【0106】
Native I/Fの実装について
ChainerのFunction及びOptimizerに対してリファレンスコード(例えばC言語など低水準の言語を想定)を実装する。このリファレンスコードは、numpyなどの外部ライブラリに依存しない形で実装する。また、動的ネットワーク定義に適したメモリプールの仕組みを実装する。また、Function/Optimizerとは別口でnumpyとのデータコンバート関数を作成する。さらに、上記Function/Optimizerの浮動小数点版リファレンスコードを作成する。
さらにまた、上記Function/Optimizerの固定小数点版リファレンスコードを作成する。また、Function/Optimizerとは別口で浮動小数点・固定小数点間のデータコンバート関数を作成する。これは、固定小数点版リファレンスコードを作成する理由は、FPUが付いてないチップも少なくないためである。
上記リファレンスコードを元に各種チップ向けに最適化したコードを実装する。
【0107】
4-3.ステップIIIについて
図23は、本発明の実施形態に係る実装手法のステップIIIを説明する模式図である。
図23に示すように、Chainerからネットワーク定義及び重みをバイトコードとして出力するメソッドが追加されている。また、バイトコードを解釈してニューラルネットワークの処理(フォワード処理、バックワード処理、重みの更新)を実行する仮想マシンが設けられる。Native I/Fのチップ向け最適化実装を流用することができる。
【0108】
構成1
(Native IFの構成)
図42は、本発明の一実施形態に係るNative I/Fの構成例を示す図である。
NNアルゴリズム毎に、計算機の種類に非依存のインターフェイスを設ける構成。
NNアルゴリズムを利用する処理系がこのインターフェイスを経由して特定の計算機にアルゴリズムの実行を指示する。
ここでいうインターフェイスとは、入力データの形式と出力データの形式、並びに、入力データの形式の加工方法と出力データの形式の対応を定義する手段。インターフェイスが同一であれば同一の入力に対して同一の出力結果が得られる。例えば、C言語で記載された関数と、その関数宣言が挙げられる。
NNアルゴリズムを利用する側の処理系は、特に限定しない。例えば、NN設計のための既存のフレームワーク(Chainerほか)などがあげられ。また、アルゴリズムの開発と併せて開発される処理系も挙げられる。
ここでいう計算機とは、計算を実行する装置を意味する。計算機は、演算コア、メモリ階層、及び、計算を実行するのに必要なハードウェア資源を含む装置である。
汎用計算機は、一般的に使用される計算機を意味する。Linux(登録商標)OS、及びPythonを含む従来のアルゴリズムが容易に動作する計算機である。
ここでいうアクセラレータとは、NNアルゴリズムの計算を含む特定の計算を高速に実行する装置を意味する。
ここでいうGPUとは、画像処理に特化した計算機だが汎用的計算を実行する能力も持つ計算機である。GPUは、前記アクセラレータの一形態も含む。CUDAなどのソフトウェア資産があるので、NNアルゴリズムを実装する容易さは、汎用計算機の場合と、一般的なアクセラレータの場合の中間程度である。
【0109】
構成1-1
(NNによる識別・学習を実行するための構成)
図43は、本発明の一実施形態に係る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を通じて呼び出される側の実装は、その動作を最適に実行できる実装を選択して実行することができる。
【0110】
構成1-1-1
(NNによる識別・学習を実行するための構成1;多次元配列を管理する構成(多次元配列管理部)の場合)
図44は、本発明の一実施形態に係る多次元配列を管理する構成例を示す図である。
Native I/Fは、更に、多次元配列管理部を有する。該多次元配列管理部は、多次元配列の生成、破棄、属性(軸数、軸毎の要素数)取得、集計結果(軸毎の総和や平均、分散など)取得、及び、多次元配列同士の要素ごとの四則演算、を含む群から選択される少なくとも1つを行うことができる。
【0111】
構成1-2
(データを共有するための構成)
【0112】
構成1-2-1
(データを共有するための構成1;データ表現変換部の場合)
図45は、本発明の一実施形態に係るデータ表現変換部の構成例を示す図である。
更に、Native I/Fは、データ表現変換部を有する。該データ表現変換部は、Native I/Fに特定の計算機に依存するデータ表現(デバイス依存データ表現)と、特定の計算機に依存しないデータ表現(デバイス非依存データ表現)を相互に変換することができる。
【0113】
構成1-2-2
(データを共有するための構成2;+外部記憶媒体を有する場合)
更に、Native I/Fを呼び出す側の処理系は、外部記憶媒体を有する。該外部記憶媒体は、デバイス非依存データに変換された重みデータを保存することができる。
【0114】
構成1-2-3
(データを共有するための構成3;+通信部を有する場合)
図46は、本発明の一実施形態に係る通信部の構成例を示す図である。
更に、Natieve I/Fを通じて呼び出される側の実装は、通信部を有する。該通信部は、呼び出される側の実装にNativeI/Fの呼び出し情報を通信することができる。また、NNアルゴリズムを利用する任意の処理系が、呼び出し情報の通信の有無と関係ないNative I/Fを呼び出そうとするとき、該NativeI/Fを通じて呼び出される側の実装は、必要に応じて最適な通信処理を実行することができる。この工程によって、計算機の物理的な距離、メモリ共有の有無、又は、通信プロトコルの違いを、NNアルゴリズムを利用する任意の処理系から隠蔽することができる。
例えば、呼び出し情報の通信の有無と関係ないNative I/Fは、レイヤーアルゴリズムを実行するためのインターフェイス、重みの更新アルゴリズムを実行するためのインターフェイス、又は、データ表現変換を実行するためのインターフェイスなどがある。
【0115】
構成2
(Native I/Fの拡張版の構成)
【0116】
構成2-1
(Native I/Fの拡張版の構成1;型変換部、並びに、浮動小数点用のNNアルゴリズム実行部、及び/又は、固定小数点用のNNアルゴリズム実行部を有する場合)
図47は、本発明の一実施形態に係る浮動小数点及び固定小数点の実行部及び型変換部の構成例を示す図である。
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アルゴリズムの全体動作が実行される。かかる工程は逆順に実行することもできる。
【0117】
構成2-2
(Native I/Fの拡張版の構成2;メモリプールモジュールを有する場合)
図48は、本発明の一実施形態に係るメモリプールの構成例を示す図である。
更に、Native I/Fを通じて呼び出される側の実装は、メモリプールモジュールを有する。該メモリプールモジュールは、動的なメモリ管理を実現することができる。
【0118】
構成2-3
(Native I/Fの拡張版の構成3;複数のNNアルゴリズムを融合したアルゴリズム実行部を有する場合)
図49は、本発明の一実施形態に係る複数のNNアルゴリズムを融合したアルゴリズム実行部の構成例を示す図である。
更に、Native I/Fは、複数のNNアルゴリズムを融合したアルゴリズム実行部を有する。該複数のNNアルゴリズムを融合したアルゴリズム実行部は、頻出するNNアルゴリズムの組み合わせに対して、複数のアルゴリズムを同時に実行する。
【0119】
構成2-4
(Native I/Fの拡張版の構成4;多次元配列データ圧縮解凍部を有する場合)
図50は、本発明の一実施形態に係る多次元配列のデータ通信量削減部の構成例を示す図である。
更に、Native I/Fを通じて呼び出される側の実装は、多次元配列データ圧縮解凍部を有する。該多次元配列データ圧縮解凍部は、前記通信部に備わる。
【0120】
構成3
(Native I/F+Chainer実行部の構成)
図51は、本発明の一実施形態に係る既存実行部との連携例を示す図である。
【0121】
構成3-1
(Native I/F+Chainer実行部の構成1;バイトコード生成部と仮想マシンを有する場合)
図53は、本発明の一実施形態に係るバイトコード生成部と仮想マシンの構成例を示す図である。
更に、Chainer実行部は、バイトコード生成部を有する。該バイトコード生成部は、Backwardの計算手順と重みを入力し、バイトコードとして出力する。例えば、バイトコード生成部を ChainerのPython層に有する。
また、Native I/Fは、仮想マシンを有する。該仮想マシンは、バイトコードを解釈してNNアルゴリズム処理を実行させる。ここでいうNNアルゴリズム処理とは、フォワード処理、バックワード処理、及び、重みの更新のいずれか、又は、その組み合わせである。
【0122】
構成3-2
(Native I/F+Chainer実行部の構成2;比較部を有する場合)
図54は、本発明の一実施形態に係る比較部の構成例を示す図である。
更に、Chainer実行部は、比較部を有する。該比較部は、同一のNNアルゴリズムに対応する既存実行部とNative層実行部の入出力結果を比較する、又は、同一のNativeI/Fにおいて異なる実装のNative層実行部を呼びだすNative層実行部同士の入出力結果を比較する。
【0123】
構成3-3
(Native I/F+Chainer実行部の構成3;関数合成部を有する場合)
図55は、本発明の一実施形態に係る関数合成部の構成例を示す図である。
更に、Chainer実行部は、関数合成部を有する。該関数合成部は、Backwardの計算手順を入力し、「複数のアルゴリズムを同時に実行するNative I/F」が対応可能なFunctionクラスのインスタンスの組み合わせを、「複数のアルゴリズムを同時に実行するNative I/F」に対応したFunctionクラスのインスタンスに置換する。しかし、Backwardの計算手順を実行する計算機のためのNative層の実装において、「複数のアルゴリズムを同時に実行するNative I/F」が存在しない場合は、上記の置換はしない。
ここでいう置換は、Backwardの計算手順を文字列として見立てた場合、部分一致検索により実行することができる。
例えば、該関数合成部は、ChainerのPython層に備わる。
【0124】
構成4
(Forward処理実行を特化させる最適化装置の構成)
【0125】
構成4-1
(Forward処理実行を特化させた最適化装置の構成1;重みの最適化処理手段を有する場合)
更に、Chainer実行部は、重みの最適化処理手段を有する。該重みの最適化処理手段は、Functionクラスに適した重みの最適化処理を実行する。
【0126】
構成4-2
(Forward処理実行を特化させた最適化装置の構成2;データメモリ領域の再利用手段を有する場合)
更に、Chainer実行部、並びにNative I/Fは、データメモリ領域の再利用手段を有する。該データメモリ領域の再利用手段は、レイヤー間で入出力されるデータのメモリ領域を再利用する。該再利用手段は、Forward処理実行部、又は、前記仮想マシンに備わる。
例えば、仮想マシンのForward処理を実行するインターフェイス(NativeI/Fにて定義されるもの)の引数にForward処理のみの実行であることを識別するためのフラグを設ける。この処理を実行する条件は、ChainerのFunctionクラスのインスタンスが入力するVariable変数にvolatile属性が指定されているとき、又は、仮想マシンのForward処理が実行される際にForward処理のみの実行であることを識別するためのフラグが有効となっているとき、である。
【0127】
作用1
(NativeIFの構成による作用)
NNのアルゴリズムを設計・利用する開発者と、計算機のハードウェア構成を深く意識する開発者の分業が容易となる。
例えば、アルゴリズムを設計・利用する開発者は、実行したいNNアルゴリズム毎のインターフェイスの同一性がNative I/Fにより保証されるので、Native I/Fを呼び出す側のソフトウェアを変更することなく様々な計算機で処理を実行することができる。
具体的には、特定の計算機に自ら開発しているソフトウェアが依存してしまうリスクを下げることができる。その結果、計算機の価格や特定用途での弱み強みといったより本質的な基準で計算機を選別することができるようになる。
計算機のハードウェア構成を深く意識する開発者にとっては、 Native I/Fに対応した計算機に最適化な実装を提供すれば、幅広いNNアルゴリズムの利用者に対して自ら開発した計算機を利用してもらえる。
【0128】
作用1-1
(NNによる識別・学習を実行するための構成による作用)
NNのアルゴリズムを設計・利用する開発者は、NNアルゴリズムを利用する任意の処理系を用いて、NativeI/Fに具備されているインターフェイスを呼び出すことにより、NNのアルゴリズム全体動作を実現することができる。
また、NNのアルゴリズムを設計・利用する開発者は、計算機の具体的な構成を意識せずとも利用している計算機に最適な実装を用いて、NNのアルゴリズム全体動作を実現することができる。
【0129】
作用1-1-1
(NNによる識別・学習を実行するための構成1による作用;多次元配列を管理する構成(多次元配列管理部)の場合)
NNのアルゴリズムを設計・利用する開発者は、NNアルゴリズムの全体動作を実行するとき、余計なデータ変換処理を経ることなく任意のNNアルゴリズムを組み合わせて実行することができる。
このとき、任意のNNアルゴリズムの処理結果である多次元配列の内容の集計結果を確認することにより、NNアルゴリズムが意図した通りの計算を実行できているかどうかを確認することができる。
【0130】
作用1-2
(データを共有するための構成による作用)
作用1-2-1
(データを共有するための構成1による作用;データ表現変換部の場合)
デバイス非依存データ表現を経由することで、異なるハードウェア構成の計算機の間でNNのアルゴリズム全体動作を実現するのに必要なデータを交換することができる。
【0131】
作用1-2-2
計算機毎に固有の情報を隠すことができる。
(データを共有するための構成2;+外部記憶媒体を有する場合)
重みのデータをデバイス非依存データ表現に変換した後、外部記憶媒体に保存することによって、特定の計算機を用いて学習済みの重みを用いて、任意の計算機上で識別処理を実行することができる。
【0132】
作用1-2-3
(データを共有するための構成3による作用;+通信部を有する場合)
計算機のハードウェア構成や、物理的な距離、メモリ共有の有無に関わらず、NNのアルゴリズム全体動作を実現するのに必要なデータを交換することができる。
NNアルゴリズムを利用する側の処理系が動作可能な計算機から、NNアルゴリズムを利用する側の処理系が動作不能な計算機に実装されたNNアルゴリズム実装を呼び出すこともできる。
したがって、コンピュータネットワークに繋がれた複数台の計算機を用いてNNのアルゴリズム全体動作を実現することができる。
【0133】
作用2
(Native I/Fの拡張版の構成による作用)
【0134】
作用2-1
(Native I/Fの拡張版の構成1による作用;型変換部、並びに、浮動小数点用のNNアルゴリズム実行部、及び/又は、固定小数点用のNNアルゴリズム実行部を有する場合)
浮動小数点演算器(FPU)を持たない計算機と、FPUを持つ計算機が混在するハードウェア構成において、それぞれの計算機に適したデータ型を用いて、NNのアルゴリズム全体動作を実現することができる。
浮動小数点演算、又は、固定小数点演算を用いて、NNのアルゴリズム全体動作を実現できる。
具体的には、計算機Aは、計算機Aの浮動小数点用のNNアルゴリズム実行部が生成した浮動小数点型データを計算機Bに転送する。次に、計算機Bは、計算機Aから転送された当該浮動小数点型データを型変換部により固定小数点型データに変換した後、当該固定小数点型データを計算機Cに転送する。
計算機Cは、計算機Cの固定小数点用のNNアルゴリズム実行部が生成した固定小数点型データを計算機Bに転送する。次に、計算機Bは、計算機Cから転送された当該固定小数点型データを型変換部により浮動小数点型データに変換した後、当該浮動小数点型データを計算機Aに転送する。
【0135】
作用2-2
(Native I/Fの拡張版の構成2による作用;メモリプールモジュールを有する場合)
動的なメモリ管理の仕組みに依存した処理系が、データの生成と破棄を含むNativeI/Fを呼び出しNNアルゴリズム全体動作を実行するとき、その動作を軽量に実現することができる。
【0136】
作用2-3
(Native I/Fの拡張版の構成3による作用;複数のNNアルゴリズムを融合したアルゴリズム実行部を有する場合)
グローバルなメモリへの不要なアクセスを回避することができる。また、関数呼び出しのオーバーヘッドを削減できる。したがって、頻出するNNアルゴリズムの組み合わせを高速に実行することができる。
【0137】
作用2-4
(Native I/Fの拡張版の構成4による作用;多次元配列データ圧縮解凍部を有する場合) コンピュータネットワークに繋がれた複数台の計算機を用いてNNのアルゴリズム全体動作を実行させるとき、多次元配列のデータ通信量を削減することができる。したがって、動作速度を向上させることができる。
【0138】
作用3
(Native I/F+Chainer実行部による作用)
NativeI/FのサポートがあるNNのアルゴリズムと、NativeI/FのサポートのないNNのアルゴリズムとを組み合わせて、NNの全体動作を定義及び実行することができる。
NativeI/Fのサポートを得ることができ次第、適宜NativeI/Fに置き換えることによって、NN全体動作を実行することができる。したがって、既存のソフトウェアの修正が不要になる。
NativeI/Fを組み合わせる場合も、Define-by-runの既存のメリットを享受することができる。
【0139】
作用3-1
(Native I/F+Chainer実行部の構成1による作用;バイトコード生成部と仮想マシンを有する場合)
Chainer実行部がバイトコード生成部を有し、NativeI/Fが仮想マシンを有することによって、高度なライブラリやプログラミング言語への依存度を減少させることができる。よって、アクセラレータなどの貧弱な実行環境を含む様々な計算機においても、製品レベルの要件を満たしつつ、Chainerで設計したNNの全体動作を実行することができる。
【0140】
作用3-2
(Native I/F+Chainer実行部の構成2による作用;比較部を有する場合)
比較部は、同一のNNアルゴリズムに対応する既存実行部とNative層実行部の入出力結果を比較する、並びに、同一のNativeI/Fにおいて異なる実装のNative層を呼びだすNative層実行部同士の入出力結果を比較する。
かかる比較部を有することによって、浮動小数点用のNNアルゴリズム実行部の処理結果の精度と、固定小数点用のNNアルゴリズム実行部の処理結果の精度を比較することができる。したがって、NNのアルゴリズムが正しく計算できることが既に十分テストされた実行部の処理結果と、新規に作成するNative層の処理結果とを比較することができる。故に、新規に作成するNative層の実装がNNのアルゴリズムを正しく計算することが可能であることを保証することができる。
【0141】
作用3-3
(Native I/F+Chainer実行部の構成3による作用;関数合成部を有する場合)
関数合成部は、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への変換も同様である。
【0142】
作用4
(Forward処理実行に特化した最適化装置の構成による作用)
Forward処理における重みの情報量、あるいは入力データのデータメモリ量を削減してForward処理を実行することによって、メモリを削減することができる。また、重みの要素数を削減したり0の重みを計算しないでFoward処理を実行することによって、計算量を削減することができる。
【0143】
作用4-1
(Forward処理実行を特化させた最適化装置1による作用;重みの最適化処理手段を有する場合)
Forward処理実行に特化した重みの最適化処理手段を、ChainerのFunctionクラスに有することによって、学習済みのネットワークの構成に含まれる任意のFunctionクラスのインスタンスに対して、重みの最適化処理を実行することができる。このように、重みの最適化処理を実行することができることで、Forward処理の際のメモリや計算量を削減することができる。これによって、NNのアルゴリズム全体動作を高速に実行することができる。
【0144】
作用4-2
(Forward処理実行を特化させた最適化装置2による作用;データメモリ領域の再利用手段を有する場合)
Forward処理のみを実行するフラグを、Forward処理の実行部(Chainer、又は、仮想マシン)に引数として与えることによって、Forward処理の際のメモリを削減することができる。これによって、NNのアルゴリズム全体動作を高速に実行することができる。
【0145】
5.実施形態に係る実装手法の具体的な手順について
実施形態に係る実装手法は、第1の手法及び第2の手法を含む。
5-1.第1の手法について
図24は、本発明の一実施形態に係る実装手法(第1の手法)に用いられる実装装置の構成例を示す模式図である。
図24に示すように、一実施形態に係る実装装置は、主に、評価ボード(マザーボード)100と、評価ボード100に着脱自在に搭載された組み込み系チップ(組み込み系半導体集積回路)200と、を含む。
【0146】
評価ボード100は、主に、CPU101と、メインメモリ102と、通信I/F103と、外部メモリ104と、を含む。これらの各構成要素が内部バス109を介して電気的に接続されている。
【0147】
CPU101は、外部メモリ103からオペレーティングシステム等の様々なプログラムをメインメモリ102にロードし、ロードしたプログラムに含まれる命令を実行する。メインメモリ102は、CPU101が実行するプログラムを格納するために用いられ、例えば、DRAMによって構成される。
【0148】
通信I/F103は、ハードウェア、ファームウェア、又は、TCP/IPドライバやPPPドライバ等の通信用ソフトウェア又はこれらの組み合わせとして実装され、イーサネット(登録商標)やインターネット等を含む通信網(図示しない)を介して、開発者等により操作される図示しない計算機及び入出力装置等と通信することが可能となるように構成される。また、通信I/F103は、組み込み系チップ200の後述する通信I/F204と通信することも可能である。外部メモリ104は、例えばフラッシュメモリ等により構成され、オペレーティングシステム等の様々なプログラムを記憶する。
【0149】
次に、組み込み系チップ200は、CPU201と、アクセラレータ(補助演算装置)202と、メインメモリ203と、通信I/F204と、外部メモリ205と、を含む。これらの各構成要素が内部バス209を介して電気的に接続されている。なお、組み込み系チップは、選択的に、GPU(図示せず)を含むことも可能である。
【0150】
CPU201は、評価ボード100(の通信I/F103)から通信I/F204を介して受信したソースコード(例えばPython等で記述されたソースコード)をメインメモリ203にロードし、ロードしたソースコードに含まれる各コードを実行する。
アクセラレータ202は、評価ボード100(の通信I/F103)から通信I/F204を介して受信したソースコード(例えばC言語やアセンブラ等)で記述されたソースコード)をメインメモリ203にロードし、ロードしたソースコードに含まれる各コードを実行する。メインメモリ203は、CPU201及びアクセラレータ202が実行するソースコードを格納するために用いられ、例えば、DRAMによって構成される。
【0151】
通信I/F204は、評価ボード100の通信I/F103と通信して様々な情報を送受信する。外部メモリ205は、例えばフラッシュメモリ等により構成され、様々なデータを記憶する。
【0152】
図25は、本発明の一実施形態に係る実装手法に用いられる手順の一例を示すフロー図である。
まず、ステップ301において、第1のプログラミング言語(例えばPython等)で記述されたソースコードをパーソナルコンピュータ等において実行させる。開発者等は、当該実行結果に基づいて、当該ソースコードがパーソナルコンピュータ等において動作するか否かを確認する。ここでいうパーソナルコンピュータ等とは、豊富な計算資源を有する計算機をいい、例えば、上記第1部において説明した実施形態に係る学習装置を含むものである。このステップ301においてソースコードがパーソナルコンピュータ等において動作する状態とは、上記「4-1」において説明したステップIと同一の状態である。
【0153】
ステップ302において、上記ステップ301においてパーソナルコンピュータ等において動作するものであることを確認したPython等で記述されたソースコードを、評価ボード100を用いて組み込み系チップ200のCPU201に実行させる。開発者等は、当該実行結果に基づいて、このソースコードがCPU201により動作可能なものであるか否かを確認する。なお、このような動作は、評価ボード100のCPU101が外部メモリ104に記憶された所定のプログラムをロードして実行することによって実現されるものとすることができる。ここで、Python等で記述されたソースコードは、評価ボード100の通信I/F103及び組み込み系チップ200の通信I/F204を介してCPU201に渡されるものとすることができる。このソースコードがCPU201により動作可能なものでないことが判明した場合には、開発者等は、このソースコードを修正して、ステップ302を繰り返す。このソースコードがCPU201により動作可能なものであることを確認した場合には、開発者等は、次のステップ303に移行する。
【0154】
ステップ303において、開発者等は、上記ステップ302においてCPU201により動作可能なものであると確認されたソースコード(の少なくとも一部)をアクセラレータ202で動作させるために第2のプログラミング言語(例えばC言語やアセンブラ)で書き換える。
【0155】
ステップ304において、上記ステップ303においてC言語等で書き換えたソースコードを、評価ボード100を用いて組み込み系チップ200のアクセラレータ202に実行させる。開発者等は、当該実行結果に基づいて、この書き換えられたソースコードがアクセラレータ202により動作可能なものであるか否かを確認する。このような動作は、評価ボード100のCPU101が外部メモリ104に記憶された所定のプログラムをロードして実行することによって実現されるものとすることができる。ここで、C言語等で記述されたソースコードは、評価ボード100の通信I/F103及び組み込み系チップ200の通信I/F204を介してアクセラレータ202に渡されるものとすることができる。このソースコードがアクセラレータ202により動作可能なものでないことが判明した場合には、開発者等は、このソースコードを修正して、ステップ304を繰り返す。このソースコードがアクセラレータ202により動作可能なものであることを確認した場合には、開発者等は、次のステップ305に移行する。
【0156】
ステップ305において、評価ボード100において、CPU201がPython等で記述されたソースコードにおける第1の特定コード(検証対象のコード)を実行した結果と、アクセラレータ202がC言語等で記述されたソースコードにおける第2の特定コードであって第1の特定コードがPython等からC言語等に書き換えられた第2の特定コードを実行した結果とを(例えば組み込み系チップ200により実行されるユニットテストと称されるモジュールを用いて)比較させて、比較結果を出力させる。開発者等は、当該比較結果に基づいて、両方の実行結果において同一の入力に対して同一の出力が得られているかを検証する。このような動作は、評価ボード100のCPU101が外部メモリ104に記憶された所定のプログラムをロードして実行することによって実現されるものとすることができる。この検証が完了するまで、開発者等は、上述したステップ303~305を繰り返す。この検証が完了した場合には、開発者等は、次のステップ306に移行する。
【0157】
ステップ306において、開発者等は、ステップ305において、C言語等で記述されたソースコードがアクセラレータ202によりさらに高速に動作するように、このソースコードをチューニングする。
【0158】
ステップ307において、評価ボード100において、CPU201がPython等で記述されたソースコードを実行した結果と、アクセラレータ202が上記ステップ306においてチューニングされたC言語等で記述されたソースコードを実行した結果とを(例えば組み込み系チップ200により実行されるユニットテストと称されるモジュールを用いて)を比較させて、比較結果を出力させる。開発者等は、当該比較結果に基づいて、両方の実行結果において同一の入力に対して同一の出力が得られているかを検証する。このような動作は、評価ボード100のCPU101が外部メモリ104に記憶された所定のプログラムをロードして実行することによって実現されるものとすることができる。この検証が完了するまで、開発者等は、上述したステップ306及びステップ307を繰り返す。この検証が完了した場合には、開発者等は、次のステップ308に移行する。
【0159】
ステップ307が完了した状態では、組み込み系チップ200は、Python等及びC言語等の2つのソースコードによって動作する状態にある。この状態について、
図26を参照して説明する。
図26は、本発明の一実施形態に係る実装手法における組み込み系チップの動作状態を示す模式図である。
【0160】
図26に示すように、上記ステップ301(これはステップIに相当する)では、関数の呼出し側(すなわち、関数を呼び出す主体)は、Python等により記述されており、被呼出し側(すなわち、呼び出される関数)もまた、Python等により記述されている。
次に、上記ステップ302~307では、関数の呼出し側は、依然としてPython等により記述されており、被呼出し側は、Python等により記述されたものとC言語等により記述されたものとが混在した状態となっている。すなわち、ステップ307が完了した状態では、組み込み系チップ200は、Python等及びC言語等の2つのソースコードによって動作する状態にある。
【0161】
本実施形態に係る実装手法が最終的に目的とするのは、
図26の右端に示すように、呼出し側、及び、被呼出し側の両方がともにC言語等により記述された状態、すなわち、組み込み系チップ200がC言語等に記述されたソースコードのみによって動作する状態である。
【0162】
そこで、
図25に戻り、ステップ308では、開発者等は、組み込み系チップ200がC言語等で記述されたソースコードのみによって動作するように、Pythonで記述されたソースコードであってまだC言語等に書き換えられていない部分をすべてC言語等に書き換える。このステップ308では、組み込み系チップ200がPythonから切り離されることになる。このようにして生成されたC言語等により記述されたソースコードは、組み込み系チップ200の外部メモリ205等に記憶される。これにより、組み込み系チップ200は、外部メモリ205等に記憶されたソースコードを読み出してアクセラレータ202に実行させ、機械学習を実行することができるようになる。この状態は、実施形態に係る実装手法が目標とする状態であって、上記「1」及び「2」において述べた課題が解決されている状態である。
【0163】
5-2.第2の手法について
図27は、本発明の一実施形態に係る実装手法(第2の手法)に用いられる実装装置の構成例を示す模式図である。第2の手法において用いられる実装装置(
図27)が、第1の手法において用いられる実装装置(
図24)と異なるのは、組み込み系チップ200がCPUを備えない点である。第2の手法では、第1の手法で組み込み系チップ200のCPU201が担っていた動作は、外部に設けられた図示しない計算機(パーソナルコンピュータ等)に設けられたCPUによりなされる。例えば、ここでいう計算機(パーソナルコンピュータ等)は、上記第1部において説明した学習装置(
図11に例示したパーソナルコンピュータ等)であってもよい。
【0164】
第2の手法で行われる実装方法では、
図25を参照して説明した実装方法について、ステップ302、305及び307において組み込み系チップ200のCPU201で実行された動作を、上記外部に設けられた計算機(図示せず)に設けられたCPUにおいて行うように変更される。これを実現するために、
図27に示した評価ボード100は、例えば通信I/F103を介して、上記外部に設けられた計算機(図示せず)と通信可能に接続されることにより、この計算機に設けられたCPUにPythonで記述されたソースコードを実行させ、その実行結果を受信することができるものであってもよい。
【0165】
6.実装装置の構成
次に、上述した実施形態に係る実装装置100が上記「5」において説明した手法を実現するために必要な構成について説明する。
【0166】
6-1.本発明を構成を説明するための用語定義
(クラスとモジュールの違い)
モジュールは特定の目的を実現するために定義・実装された手続きとデータの集合 (特定のプログラミング言語による支援の有無とは無関係の概念)
クラスはPythonなどのオブジェクト指向言語の支援を用いて定義・実装されたモジュール
【0167】
(Python層とNative層)
Native層とは、Native I/Fとそこから呼び出される実装(ソフト及びハード)の階層をいう。Python層とは、Python言語上で実行されることが想定されるソフトウェア階層をいう。現状ChainerはPython言語で記述されているが、将来Chainerが別のプログラミング言語に移植されることも考えられる。ここでPython層として説明する機能は必ずしもPython言語に特化することを意味するわけではない。Python層及びNative層の役割分担として、Python層はよりアルゴリズム設計に適した抽象化レベルの高い開発環境を想定し、Native層はよりハードウェア構成を具体的に意識する抽象化レベルの低い開発環境を想定する。
【0168】
(計算機と実行部の対応)
図52は、本発明の一実施形態に係る既存実行部との連携例を示す図である。
実行部とはニューラルネットのアルゴリズムを実際に計算するためのFunction/Optimizerクラスのメソッドである。
既存実行部とは汎用計算機実行部もしくはGPU実行部もしくはその両方である。汎用計算機実行部は、汎用計算機を用いてNNのアルゴリズムを計算する。GPU実行部はGPUを用いてNNのアルゴリズムを計算する。
Native実行部は、Native層の実装を用いてNNのアルゴリズムを計算する。Native層は計算機の種類毎に実装するので、全ての計算機の種別(汎用計算機、GPU、アクセラレータ)についてNativeI/Fを通じて動作可能である。
【0169】
6-2.実装部の構成
図28は、本発明の一実施形態に係る実装装置が有する機能を概念的に示す模式図である。
図28に示すように、実装部400は、主に、駆動部401と、Functionクラス/Optimizerクラス402と、汎用計算機実行部403と、GPU実行部404と、Native層実行部405と、汎用計算機用多次元配列406と、GPU用多次元配列407と、Native用多次元配列408と、Variableクラス409と、を含む。
【0170】
駆動部401は、主に、あるアルゴリズム(関数)の実行をFunctionクラス/Optimizerクラス402に命令する実行部と、そのアルゴリズム(関数)についての汎用計算機実行部403による実行結果(又はGPU実行部404による実行結果)とNative層実行部405による実行結果とを例えばユニットテストと称されるモジュール等を用いて比較し、その比較結果を出力する比較部と、を含む。
【0171】
Functionクラス/Optimizerクラス402は、駆動部401から命令されたアルゴリズム(関数)を汎用計算機実行部403、GPU実行部404及びNative層実行部405のうちの少なくとも1つに実行させる。
【0172】
汎用計算機実行部403は、Functionクラス/Optimizerクラス402から命令されたアルゴリズム(関数)に対応する多次元配列を汎用計算機用多次元配列406から取得してそのアルゴリズム(関数)をCPUを用いて実行する。その実行結果は、Functionクラス/Optimizerクラス402を介して駆動部401に戻される。
【0173】
GPU実行部404は、Functionクラス/Optimizerクラス402から命令されたアルゴリズム(関数)に対応する多次元配列をGPU用多次元配列407から取得してそのアルゴリズム(関数)をGPUを用いて実行する。その実行結果は、Functionクラス/Optimizerクラス402を介して駆動部401に戻される。
【0174】
Native層実行部405は、Functionクラス/Optimizerクラス402から命令されたアルゴリズム(関数)に対応する多次元配列をNative用多次元配列408から取得してそのアルゴリズム(関数)をアクセラレータを用いて実行する。その実行結果は、Functionクラス/Optimizerクラス402を介して駆動部401に戻される。
【0175】
Variableクラス409は、汎用計算機用多次元配列406、GPU用多次元配列407及びNative用多次元配列408により用いられるすべての多次元用配列を保持しており、汎用計算機用多次元配列406、GPU用多次元配列407及びNative用多次元配列408に対して対応する多次元用配列を供給する。
【0176】
なお、実装手法として、上記「5-1」で述べた第1の手法が採用される場合には、
図28に示されたすべての構成要素が組み込み系チップ200(
図24参照)に配置される。この場合、汎用計算機実行部403は、組み込み系チップ200に搭載されたCPU201を用いてアルゴリズム(関数)を実行し、GPU実行部404は、組み込み系チップ200に搭載されたGPU(図示せず)を用いてアルゴリズム(関数)を実行し、Native層実行部405は、主として組み込み系チップ200に搭載されたアクセラレータ202を用いてアルゴリズム(関数)を実行する。
【0177】
一方、実装手法として、上記「5-2」で述べた第2の手法が採用される場合には、
図28に示された構成要素のうち、Functionクラス/Optimizerクラス402、汎用計算機実行部403、GPU実行部404、汎用計算機用多次元配列406、GPU用多次元配列407及びVariableクラス409が、外部に設けられた計算機(パーソナルコンピュータ等)に配置される。この場合、Native層の実装は、組み込み系チップ200にも依然として配置されている。さらに、この場合、汎用計算機実行部403は、上記外部に設けられた計算機のCPUを用いてアルゴリズム(関数)を実行し、GPU実行部404は、上記外部に設けられた計算機のGPUを用いてアルゴリズム(関数)を実行する。
【0178】
6-3.Native層実行部の構成
次に、上述したNative層実行部405の構成について説明する。
図29は、本発明の一実施形態に係る実装装置に含まれるNative層実行部の構成例を示す模式図である。
図29に示すように、Native層実行部405は、Python層において、主に、NativeDeviceクラス501と、NativeArrayクラス502と、Functionクラス/Optimizerクラス503と、バイトコード生成部504と、を含む。なお、
図29に記載されたFunctionクラス/Optimizerクラス503と
図28に記載されたFunctionクラス/Optimizerクラス402とは同一の構成要素であり、
図29に記載されたNativeArrayクラス502と
図28に記載されたNative用多次元配列408とは同一の構成要素である。
さらに、Native層実行部405は、Native層において、主に、デバイス管理モジュール505と、データ変換モジュール506と、多次元配列モジュール507と、Functionモジュール/Optimizerモジュール508と、仮想マシンモジュール509と、メモリプールモジュール510と、を含む。
【0179】
NativeDeviceクラス502は、Native層のデバイス管理モジュールをPython層でラップするとともにNative層への関数呼び出しやデータ入出力を隠蔽する。NativeArrayクラス502は、Native層の多次元配列をPython層でラップする。Functionクラス/Optimizerクラス503のうち、Functionクラスは、Native層のFunctionモジュールをPython層でラップし、Optimizerクラスは、Native層のOptimizerモジュールをPython層でラップする。ここで、Functionクラス及びOptimizerクラスは、Chainerにおいて実装済みであり、汎用計算機とGPUによる実行の違いを隠蔽する機能を有する。この機能を拡張することでNative層での実行も隠蔽できる。
バイトコード生成部は、バイトコードを生成する。
なお、
図29に例示した各構成要件の詳細については後述する。
【0180】
7.実施形態に係る実装装置の効果
ディープラーニングは研究開発が盛んな発展途上の技術であるので、組み込み系チップ向けの開発期間中に従来よりも優れた性能を持つ新規のレイヤーアルゴリズムが発明され、こうした新規のアルゴリズムを開発中のソフトウェア、あるいはハードウェア実装に取り込む需要が発生することが想定される。
新規のレイヤーアルゴリズムを含むニューラルネットワークの構成を組み込み環境で製品レベルの仕様を満たした上で動作する状態を実現するためには以下のような開発ステップを踏む必要がある。
1.GPUなど潤沢な計算資源を得られる環境でアルゴリズムの実装と検証を行う。
2.1で実装検証したアルゴリズムを組み込みチップで既に最適化実装が終わったニューラルネットワークのモジュールと結合し動作検証を行う。その結果に応じて該当チップ向けに特化した最適化を1で実装検証したアルゴリズムに適応する。
3.2の作業完了後、該当チップ向けに最適化されたニューラルネットの実装のみを用いて、これ以外のモジュール(センサーやモータの制御系など)とも結合した上で製品レベルの仕様を満たしているか否かを様々な試験項目により検証する。
【0181】
実施形態に係る実装装置は、Python上でニューラルネットワークのアルゴリズムを動作させるとき、汎用計算機上で動作するPython言語を用いた実行部と、GPUを用いた実行部と、特定チップ向けの最適化実装を用いた実行部とをレイヤーごとに呼び分ける構成を有し、バイトコードを経由することでこの特定チップ向けの最適化実装のみを用いてニューラルネットワークのアルゴリズム全体を動作させる構成を有する。
前段落で説明したステップ1、2間で1のステップで作成したアルゴリズム実装コードを2のために流用でき、ステップ1、2間の動作結果の違いも容易に比較検討できる。さらに、ステップ2、3間では、ステップ2のために作成した最適化実装をステップ3のために流用でき、逆にステップ3で見つかった最適化実装に関する不具合修正もステップ2のために流用することができる。その結果、新規のレイヤーアルゴリズムを含むニューラルネットの構成を組み込み環境で製品レベルの仕様を満たした上で動作する状態を最小の開発コストで実現できる。
【0182】
用語の定義
本発明の実施形態を詳細説明する上で以下の用語を定義する。
「全体動作」とは、フォワード処理単独、又は、フォワード処理、バックワード処理及び重みの更新処理を繰り返して実行するような処理単位を表す。この全体動作は、典型的なニューラルネットワークの学習及び識別の実施形態として想定されるものである。
【0183】
8.Native層
次に、
図29に例示した実施形態に係る実装装置のNative層に関する構成について説明する。
8-1.デバイス管理モジュール
デバイス管理モジュール505は、デバイス(最適化実装に依存するソフトウェア及びハードウェア状態)の初期化と解放処理を行う。具体的には、デバイス管理モジュール505内で行う処理は、デバイスの形態次第で異なるが、典型的な処理内容として例えば後述するメモリプールの確保や解放を行う。デバイスは、Chainer及びPythonを実行する汎用計算機と同一チップや、同一基板上に存在する必要はない。別基板にあるデバイスと通信し初期化・解放するような最適化実装も可能である。
【0184】
デバイスを初期化又は解放する関数の定義例を以下に示す。
(例1)Device* chnr_init_device(void)
これによりデバイスを初期化することができる。
(例2)void chnr_release_device(Device* device)
これによりデバイスを解放することができる。
【0185】
8-2.Functionモジュール
Functionモジュール508は、ニューラルネットワークのレイヤーごとの計算を行う関数群であり、レイヤーの種類別に以下の関数を定義する。
chnr_forward_xxxx(…)
-フォワード処理(浮動小数点版)を実装
chnr_backward_xxxx(…)
-バクワード処理(浮動小数点版)を実装
chnr_forward_xxxx_fx(…)
-フォワード処理(固定小数点版)を実装
chnr_backward_xxxx_fx(…)
-バックワード処理(固定小数点版)を実装
ここで、xxxxはレイヤーの種類別に付与される名称を表す。
各関数での具体的な処理内容は、上記第1部の上記「2-6」~「2-12」において例示したものを含む。
【0186】
8-3.多次元配列(MDArray)モジュール
多次元配列モジュール507は、Native層のFunctionの間で入出力される多次元配列を管理する。多次元配列モジュール507は、任意のサイズ・次元数を管理できる。また、多次元配列モジュール507は、後述するように、Numpy(Chainerが依存しているpython層の多次元配列クラス)やGPU向け多次元配列ライブラリとの相互変換の仕組みを有する。
さらにまた、この多次元配列モジュール507は、浮動小数点型だけではなく固定小数点型も保持できる。これにより、FPU(浮動小数点演算ユニット)を持たないハードウェアでもニューラルネットの計算を容易に実現できる。また、この多次元配列モジュール507は、浮動小数点の多次元配列との相互変換の関数を有する。
【0187】
多次元配列モジュール507の実装例について説明する。
本発明の一実施形態に係る実装装置の多次元配列モジュールの構造体定義例が
図30に示されている。
次に、関数定義例は以下のとおりである。
(例1)MDArray chnr_create_md_array(dimensions[], numaxis, type)
これにより、多次元配列を生成・初期化することができる。
(例2)void chnr_delete_md_array(MDArray* mdrray)
これにより、多次元配列を削除することができる。
(例3)void chnr_md_array_add(MDArray* dst, MDArray* a, MDArray* b)
これにより、多次元配列の要素同士の加算を行うことができる。
【0188】
次に、多次元配列モジュール507の多次元配列のメモリ管理について説明する。
多次元配列の実体を格納するメモリ領域の管理(生成・破棄)はNative層で実現する。組み込み環境の場合、Linux(登録商標) OSなどが標準提供するメモリ管理機構(malloc/free)では管理できないようなメモリ構成を有する環境も考えらえる。Python層では、アルゴリズム開発、Native層では、ハードウェアを強く意識する開発というソフトウェア階層の役割分担を考えると、こうしたハードウェア環境の特徴に対して責任を持つ管理機構はNative層で実装することが適切である。後述する仮想マシンを利用する場合(Python層への依存を取り除いた場合)も、このメモリ管理機構を使い回すことができる。
Python層でNative層の多次元配列をラップするクラスを用意し、メモリ領域の生成・解放タイミングはこのPythonクラスのインスタンス生存期間に一致させる。Python上のコードで多次元配列を自然に扱うために、こうした仕組みが必要となる。「Define-by-Run」の機能もPythonのメモリ管理機構に依存している。
【0189】
多次元配列データの相互互換及び参照関係を
図31に示す。
【0190】
8-4.メモリプールモジュール
メモリプールモジュール510は、一旦確保したメモリ領域を使い回すことで、コスト(処理サイクル数など)が高いメモリ管理機構のコール回数を削減するための仕組みである。
関数定義例は以下のとおりである。
(例1)void chnr_momory_pool_init(MemoryPool* momory_pool)
これにより、メモリプールを初期化することができる。
(例2)void chnr_momory_pool_release(MemoryPool* momory_pool)
これにより、メモリプールを破棄することができる。
(例3)void* chnr_momory_pool_alloc_buffer(MemoryPool* momory_pool, int byte_size, void* old_addr)
これにより、メモリを確保することができる。
(例4)void chnr_momory_pool_free_buffer(MemoryPool* momory_pool, void*addr) これにより、メモリを解放することができる。
【0191】
Native層でメモリプールモジュールが必要となる背景(1)
Chainerの「Define-by-Run」はPythonが持つ動的メモリ管理の仕組みに依存している。その例(Linear Functionのフォワード処理)を
図32に示す。この例では、3行目のWx = x.dot(self.W.T)の記述でWxのインスタンス(中身は多次元配列)が新たに生成されている。Wxはどの変数からも参照されなくなった時点でPythonのメモリ管理機構により自動破棄される。
Functionが出力するデータ(上記の例ではWx)のサイズは入力データサイズやパラメータに依存して動的に変更可能であって、その実体(メモリ領域)の確保もフォワード処理やバックワード処理のコードフロー内で実行される。「Define-by-Run」(ネットワーク構成の実行時に定義)を実現するためには、こうした必要なタイミングで必要なサイズだけメモリを確保する仕組みが必要である。
【0192】
Native層でメモリプールモジュールが必要となる背景(2)
Python層でNative層の多次元配列をラップするクラスを用意し、Native層の多次元配列の生存期間をPython層と一致させる工夫をすることで、「Define-by-Run」の柔軟性を享受しながらNative層の実装を利用することができる。
しかしながら、通常Functionは高い頻度でコールされるため、その度にNative層のmallocやfreeなどコストの高いメモリ管理機構をコールしてしまうと、処理速度の低下を招く可能性がある。このため、一旦確保したメモリ領域を使い回す機能(メモリプール)を用意する必要が生じる。
【0193】
メモリプールの実装例(1)
構造体定義例を
図33に示す。
メモリ確保時の処理フローは次のとおりである。
1.Buffer_sizeの配列の中から、解放済みフラグが1でかつ前回確保したときのサイズが今回確保したいサイズと一致しているインデックスを検索し、見つかれば、解放済みフラグを0にセット後、同じインデックスのbuffer_addrの値(メモリバッファのアドレス)を返す。ここで、解放済みフラグは例えばbuffer_size配列要素の符号ビットで管理する。前回確保したときのサイズとアドレスの組み合わせにより配列要素を検索することで、アドレスの入れ替わりを少なくすることもできる。
2.上記一致しているインデックスが見つからなければ、実際にメモリを確保(mallocなどをコール)して、そのアドレスとサイズを配列に加えた後、アドレスを返す。
【0194】
メモリプールの実装例(2)
メモリ解放時の処理として、buffer_addrの配列の中から解放すべきアドレスを検索し、そのアドレスが見つかれば、解放済みフラグを1にセットする。
メモリプール解放時の処理として、buffer_addrの配列の中からアドレスが設定されている要素に対してメモリの解放(free関数のコールなど)を行う。
【0195】
メモリプール実装の効果
大半のニューラルネットワークにおいては、メモリサイズの組み合わせは、学習のイテレーション毎に変化することはなく固定的なので、上述のようなメモリプールの実装例を用いることで、mallocなどの呼び出しを最初のイテレーション時だけにとどめることができる。
【0196】
8-6.Optimizerモジュール
Optimizerモジュール508は、ニューラルネットワークの重みを有するレイヤーごとに重み更新を行う関数群である。Optimizerモジュール508は、重みの更新アルゴリズム別に以下の関数を定義する。
(例1)chnr_op_init_state_xxxx(…)
これにより、重み更新アルゴリズムの内部状態初期化処理を実装(浮動小数点版)することができる。
(例2)chnr_op_update_one_xxxx(…)
これにより、重み更新処理を実装(浮動小数点版)することができる。
(例3)chnr_op_init_state_xxxx_fx (…)
これにより、重み更新アルゴリズムの内部状態初期化処理を実装(固定小数点版)することができる。
(例4)chnr_op_update_one_xxxx_fx (…)
これにより、重み更新処理を実装(固定小数点版)することができる。
ここで、xxxxは重みの更新アルゴリズム別に付与される名称を表す。
なお、重みの更新アルゴリズムは、上記第1部の上記「2-13」において説明したものを含むことができる。
【0197】
8-7.データ変換(Converter)モジュール(1)
データ変換モジュール506は、データ形式の変換を行う関数群である。
関数定義例は以下のとおりである。
(例1)chnr_float_to_fixed(MDArray* dst, MDArray* src, int Q)
これにより、浮動小数点型から固定小数点型へ変換することができる。
(例2)chnr_fixed_to_float(MDArray* dst, MDArray* src)
これにより、固定小数点型から浮動小数点型へ変換することができる。
(例3)chnr_host_to_device(MDArray* dst, float* src_data, int src_dimensions[], int src_num_axis, int Q, int async, …)
これにより、デバイス非依存データ表現(後述)からデバイス依存データ表現(後述)へ変換することができる。
(例4)chnr_device_to_host(float* dst_data, int dst_dimensions[], int*dst_num_axis, MDArray* src, int async, …)
これにより、デバイス依存データ表現からデバイス非依存データ表現へ変換することができる。
【0198】
浮動小数点型と固定小数点型変換の効果
組み込み向け半導体チップには、FPU(浮動小数点演算ユニット)を省いたり、少なくとも大規模並列計算に関してFPUを用いない回路設計とすることで、計算量に対するハードウェア資源(トランジスタ数や消費電力)削減を狙ったものが多く見られる。FPUを用いないでニューラルネットワークなど数値計算のアルゴリズムを実行する場合、整数演算器とシフト演算器を利用して小数点以下の情報を含む数値を表現する固定小数点型と呼ばれるデータ型がよく用いられる。浮動小数点型は、実数値をより直感的に扱えるようにするという意味で、アルゴリズム設計に適したデータ型であり、固定小数点型はハードウェア資源の有効活用に適したデータ型といえる。ニューラルネットワークを設計実行するフレームワーク内にこのようなデータ型間の変換関数を用意しておくことで、ニューラルネットのアルゴリズム開発を、統一された環境下で数理面からハードウェアを意識した実装面へ、型変換の影響度をFunction単位で確認しながら段階的に進めることができる。
【0199】
デバイス非依存データ表現とは、特定の計算機に依存する情報をもたないデータ表現をいう。このデータ表現の代表的な実装は、メモリアドレスが連続なC言語形式の多次元配列である。Python層にてnumpyなどのライブラリを利用すればこのようなデータ表現を容易に扱うことができるが、ライブラリやホスト言語を特定するものではない。
デバイス依存データ表現とは、特定の計算機に特化した最適化実装に適したデータ表現をいう。
これら2つのデータ表現を相互変換する関数を用意することで、ハードウェアを強く意識した最適化実装と、アルゴリズムを意識した実装(例えばPythonで記述された数式に近い構造の読みやすいコードなど)を連携して全体動作を実行できる。
【0200】
デバイス依存データ表現への変換で考慮すべき要件例
(1)メモリ構成
共有メモリに配置するのか?ハードウェア特有のメモリ領域に配置するのか?
(2)メモリアライメント
先頭アドレス、各次元ごとの先頭アドレス、パディング
(3)バイトオーダ
リトルエンディアン、ビッグエンディアン
(4)データ型
固定小数点(Q値)/浮動小数点,バイト幅(32bit, 16bit, 8bit, …)
(5)マルチコア実行におけるデータ入出力のスケジューリング
(6)データ通信
最適化実装を持つデバイスが別チップや別基板などにある場合の通信処理
【0201】
8-8.通信手段
これまでに説明したNative層の関数群(Native I/F)の実装を以下のような変更を適応することで、別チップや別基板などにあるデバイスと通信しながら全体動作を高速に実行できる
(1)RPC(remote procedure call)
(2)命令キュー
(3)多次元配列のデータ通信量の削減
(4)転送と計算の非同期処理
これらの変更方針について解説するために以下の用語を定義する
「ホストデバイス」:全体動作を実行するデバイス(通常の実装ではPython上でChainerのコードが実行されるデバイス)
「遠隔デバイス」:別チップや別基板などにあるなどの理由で通信処理が必要なデバイス
【0202】
RPC(remote procedure call)
Native I/Fで定義された関数を呼び出したとき、その処理要件(メモリ確保や演算の実)を直接実行するのではなく、処理要求を表す情報(関数の種類や引数)を生成し、遠隔デバイスへ送信し、遠隔デバイスではその指示に基づいた処理を実行した後、その処理結果をホストデバイスが受信する仕組みを設ける。
命令キュー
RPCによる処理要求の通信は、Native I/Fで定義された関数を呼び出す都度実行するのではなく、処理要求を表す情報を一旦キュー(FIFOバッファ)に蓄えることで通信のスケジュールを効率化する。
多次元配列のデータ通信量の削減
多次元配列は膨大なデータサイズを持つため、その通信量を削減することは全体動作の速度を向上させる上で重要な課題である。通信量を削減するためには大きく以下の2つの方策がある。
(1)多次元配列の転送回数を削減する
(2)個々の多次元配列のデータ通信量を削減する
【0203】
多次元配列の転送回数を削減する方法
中間層(ニューラルネットの入力層と出力層以外)のレイヤー間で入出力するデータ及び重みの勾配は、遠隔デバイスのみに存在すればよくデバイス間の通信は不要である。また「重み」についても、ネットワーク構造を定義する最初の段階で遠隔デバイスへ転送し、学習終了時にホストデバイスへ転送すればよい。
データ変換(Converter)モジュール506について説明したデバイス非依存データ表現及びデバイス依存データ表現の変換関数は、このような転送タイミングのマネージを行うのに最適である。具体的には各関数で以下の処理を行う。
デバイス非依存データ表現からデバイス依存データ表現へ変換する際に、ホストデバイスから遠隔デバイスへのデータ転送を行う。
デバイス依存データ表現からデバイス非依存データ表現へ変換する際に、遠隔デバイスからホストデバイスへのデータ転送を行う。
【0204】
個々の多次元配列のデータ通信量を削減する方法
様々なデータ圧縮のためのアルゴリズムが知られている。
(1)可逆圧縮(ハフマン符号化、ランレングス圧縮、etc)
(2)不可逆圧縮(DCT, スカラー量子化、ベクトル量子化, etc)
データ通信を依頼する関数(デバイス非依存データ表現とデバイス依存データ表現の変換関数を想定)の引数にて、これらの圧縮アルゴリズムの種別とパラメータを指定することで、データの性質や精度要件の考慮に基づいた最適なデータ圧縮手段を用いて通信量を削減できる。
【0205】
転送と計算の非同期処理
多くの組み込み系チップでは、データ通信及び演算処理を別々のハードウェアが非同期に実行する構成を持つ。データ通信を依頼する関数(デバイス非依存データ表現とデバイス依存データ表現の変換関数を想定)に非同期実行(non-blocking)するものを用意すれば、こうしたハードウェア構成を意識したコーディング(一般にパイプライン化と呼ばれる手法)により、アリゴリズム全体の高速化を実現できる。
疑似コードによるパイプライン化のコーディングを
図34に示す
【0206】
8-9.仮想マシンモジュール
仮想マシンモジュール509は、バイトコードを解釈しニューラルネットの学習/識別処理(フォワード処理、バックワード処理及び重みの更新)を実行する機能を実現する関数群である。バイトコードは、後述するPython層のバイトコード出力器によって生成されるものを前提とするが、他のソフトウェアで生成されたバイトコードであっても形式が正しければ仮想マシンモジュールで解釈実行できる。
関数定義例は以下のとおりである。
(例1)void chnr_init_with_bytecode(VMState* state, char* byte_code)
これにより、バイトコードを構文解析し仮想マシンの内部状態を初期化することができる。
(例2)void chnr_forward(VMState* state)
これにより、フォワード処理を実行することができる。
(例3)void chnr_backward(VMState* state)
これにより、バックワード処理を実行することができる。
(例4)void chnr_update_weight(VMState* state)
これにより、重みの更新処理を実行することができる。
【0207】
バイトコードのフォーマット例
以下のような情報をバイナリーフォーマットにて格納する。
(1)入出力データ情報
{配列次元数・サイズ, データ型(float32, FixedPoint)}*Variable数
(2)重み情報
{配列次元数・サイズ, データ型(float32, FixedPoint), 実現値}*重み個数
(3)バックワード処理時Function呼び出し情報
{Functionの種別,入出力データのindex, 重み情報のindex, Functionの種別毎に固有のパラメータ}*Function数
(4)重み更新の種別及びパラメータ
さらにバイトコードには、ニューラルネット全体処理の入出力となる多次元配列のindexを加えてもよい。このindexをバイトコードに格納しておくことにより、仮想マシンを利用するユーザコードではニューラルネット全体処理の入力となる多次元配列と、出力となる多次元配列を関数呼び出しに関して適切に紐付けることができる。例えば、以下のようなフローにより、この紐付けを行うことができる。
(ステップ1)ユーザコードは仮想マシンの構成に用意された関数を呼び出すことにより、全体処理の入力多次元配列を取得する。
(ステップ2)ユーザコードは前記ステップ1で取得した多次元配列に入力データをコピーする。
(ステップ3)ユーザコードは仮想マシンの構成に用意された全体動作を実行する関数を呼び出す。
(ステップ4)ユーザコードは仮想マシンの構成に用意された関数を呼び出すことにより、全体処理の出力多次元配列を取得する(この多次元配列は前記ステップ3で実行される全体動作の処理結果が格納された状態となっている。前記ステップ3とステップ4の関数は必ずしも分離する必要はなく一体の関数であってもよい。)。
(ステップ5)ユーザコードは前記ステップ4で取得した多次元配列から出力データの中身を取得する。
【0208】
仮想マシンの内部状態初期化の処理フロー実装例
(1)バイトコード内の「入出力データ情報」を解釈して、Functionで入出力する多次元配列のリストを生成する。
(2)バイトコード内の「重み情報」を解釈して重みと重みの勾配(何れも多次元配列)のリストを生成する。
(3)バイトコード内の「Backward時Function呼び出し情報」を解釈して以下の情報を持つ構造体(FunctionState)のリストをForward用とBackward用にそれぞれ生成する(フォワード処理/バックワード処理を実行する関数の識別ID, 入出力データのアドレス, 重みのアドレス, 重みの勾配のアドレス, Functionの種別毎に固有のパラメータ)。
(4)バイトコード内の「重み更新の種別とパラメータ」を解釈して、重み更新アルゴリズムの内部状態の多次元配列と、以下の情報を持つ構造体(OptimizerState)を初期化する(重みの更新を実行する関数のアドレス,重みのアドレス,重みの勾配のアドレス,重み更新アルゴリズムの内部状態, 重みの更新種別毎に固有のパラメータ)。
【0209】
【0210】
仮想マシンモジュールの実行フロー例(1)(フォワード処理及びバックワード処理) 仮想マシンモジュールは、
図36に示す擬似コードのような処理を実行する。
【0211】
仮想マシンの実行フロー例(2)(Optimizer)
仮想マシンモジュールは、
図37に示す擬似コードのような処理を実行する。
【0212】
Forward処理実行を特化させた最適化装置の構成2;データメモリ領域の再利用手段を有する場合(1)
全体動作を実行する際、学習(重みの更新)を行わず識別処理のみを実行するのであればフォワード処理のみを実行すれば良い。この場合、以下のデータは不要となる。
(1)レイヤー間で入出力されるデータのうち現在実行中のFunctionがアクセスしないもの
(2)重みの勾配
(3)重み更新アルゴリズムの内部状態
仮想マシンの内部状態初期化の際、重みの勾配及び重み更新アルゴリズムの内部状態は確保の必要がない。レイヤー間で入出力されるデータについても例えば次段落に記載するような手順でメモリ確保量を抑えることができる。
【0213】
Forward処理実行を特化させた最適化装置の構成2;データメモリ領域の再利用手段を有する場合(2)
仮想マシンモジュールの内部状態初期化時の手順例
(1)Functionごとに入出力するデータサイズ(メモリサイズ)の和を計算し、最大サイズのものを選ぶ。
(2)多次元配列をハンドルする構造体(MDArray)を初期化する際に1で確保したメモリ領域を使い回すようにアドレスを設定する。
レイヤー毎にメモリ領域の左端と右端を入出力として交互に切り替えて使うようなアドレス設定を行うことで、配列データのコピーが発生しないようにする。ループのある入出力を行うFunctionが含まれている場合には、次イテレーションに持ち越す出力データに関しては、この手順で示した再利用の対象外とし個別にメモリ領域を確保する。
【0214】
Forward処理実行を特化させた最適化装置の構成2;データメモリ領域の再利用手段を有する場合(3)
Functionが入出力するデータのアドレス設定例を
図38に示す。
【0215】
バイトコードのフォーマットに関する補足
これまでの説明では「バックワード処理時Function呼び出し情報」に格納された情報を単純に昇順あるいは降順に実装する例を示した。しかしながら、複数の実行順序をバイトコードに格納しておいたり、繰り返し、分岐の指示をバイトコードに格納しておくことで、仮想マシン実行時に入力データの性質に応じてニューラルネットの構成を動的に変更するといった、より高度な処理を実行することも可能である。メモリプールモジュールに関して上述したメモリ管理機構はこうした動的なメカニズム実現のために利用することができる。
【0216】
仮想マシンから外部のコードへ入出力するデータのひも付けについて
「仮想マシンの内部状態初期化処理」にてFunction間で入出力するデータのリストが作成されるが、仮想マシンの関数をコールする外部のコードが、このリストの要素に直接アクセスするのが最も簡易な方法である。バイトコード生成時にPythonのVariableインスタンスの変数名を「入出力データ情報」に格納しておけば、この名前を使って入出力をひも付けることもできる。
【0217】
9.Python層
次に、
図29に例示した実施形態に係る実装装置のPython層に関する構成について説明する。
9-1.NativeArrayクラス
NativeArrayクラス502は、Python層でNative層の多次元配列をラップするクラスである。NativeArrayクラス502は、Native層の多次元配列と1:1対応するインスタンスとして生成する。また、NativeArrayクラス502は、Pythonオブジェクトとしての基本機能として参照カウントによる生存期間管理機能を持つ。さらにまた、NativeArrayクラス502は、生存期間が終了した時点でNative層の多次元配列の解放を依頼する機能を持つ。
また、NativeArrayクラス502は、Native層の多次元配列の型情報のコピーを持ち、Python層の他のオブジェクトへ伝える機能を持つ。
さらにまた、NativeArrayクラス502は、データコピーや配列要素ごとの加算などの機能を持ち、その実行をNative層へ依頼する機能を持つ。
加えて、NativeArrayクラス502は、その他、Chainerが依存するNumpyやGPUArrayといったPython層の多次元配列ライブラリとコンパチブルに動作する機能を持つ。
【0218】
9-2.NativeDeviceクラス
NativeDeviceクラス501は、Native層の最適化実装及び参照実装を抽象化するクラスである。NativeDeviceクラス501は、以下のような処理をPython層の他のオブジェクトからの依頼に応じてNative層へ依頼する機能を持つ。
(1)デバイスの初期化と解放
(2)多次元配列の生成とコピー(これをラップしたPython層のNativeArrayインスタンスを生成する)
(3)デバイス非依存データ表現とデバイス依存データ表現間の変換(浮動小数点と固定小数点間の変換も指示できる)
(4)FunctionやOptimizerの処理実行(Native層の個々の関数を呼び分ける)
【0219】
9-3.Functionクラス
Functionクラス503は、フォワード処理とバックワード処理とをペアにして定義したクラスである。Functionクラス503は、Chainerに存在するクラスだが、フォワード処理とバックワード処理をNative層へ依頼する機能を追加する。
メソッド実装例は以下のとおりである。
(例1)forward_native(…)
これにより、フォワード処理をNative層に依頼することができる。
(例2)backward_native(…)
これにより、バックワード処理をNative層に依頼することができる。
【0220】
Forward_nativeやbackward_native呼び出し時に想定される処理フロー
(1)入力データサイズやFunctionインスタンス初期化時のパラメータから、出力データサイズを計算する。
(2)(1)で求めた出力データサイズと、入力データのインスタンス(NativeArray)、Functionの区分(Linear, ReLU, …)をNativeDeviceインスタンスに渡してNative層の関数呼び出しを依頼する。
(3)NativeDeviceインスタンスはこの呼び出しに応じて以下の処理を実行する。
(A)Native層に出力データの多次元配列生成を依頼する。入力データを上書きするFunctionであればこの処理は行わない。
(B)入力データの型(浮動小数点、固定小数点)とFunctionの区分より実際にコールするNative層の関数を決定し呼び出す(Native層の関数はAで確保した多次元配列に処理結果を書き込む)
(C)上記(A)で確保した多次元配列をラップするNativeArrayインスタンスを生成する。
(4)上記(C)で生成したNativeArrayインスタンスをFunctionの戻り値として返す。
【0221】
9-4.Optimizerクラス
Optimizerクラス503は、重みの更新を行うクラスである。Optimizerクラス503は、Chainerに存在するクラスであるが、状態初期化及び重み更新処理をNative層へ依頼する機能を追加する。
メソッド実装例は以下のとおりである。
(例1)init_state_native(…)
これにより、重み更新アルゴリズムの内部状態初期化処理をNative層に依頼することができる。
(例2)update_one_native(…)
これにより、重み更新処理をNative層に依頼することができる。
これらのメソッド呼び出し時の処理フローは上記「Functionクラス」で説明済みのものと同等である。
【0222】
9-5. Native層と連携する全体動作の具体例
具体例を
図39に例示する。
【0223】
9-6.バイトコード生成(出力)部
バイトコードし生成器504は、「Define-by-Run」で定義したニューラルネットワークのネットワーク構成をバイトコード(解釈実行可能なデータ形式)に変換し出力する仕組みである。バイトコードの形式は例えば「仮想マシンモジュール」に関して上述したものが考えられる。しかしながら、このような形式以外にも、例えば以下のような形式への出力を考えることができる。
(1)Caffeのニューラルネット定義フォーマット
Caffeで実行できる(Caffeはニューラルネット設計実行のための代表的なフレームワークの一つ)。
(2)C言語やJava(登録商標)などのプログラミング言語
全体動作を実行するソフトウェアを生成できる。
(3)HDLやVerilogといったハードウェア記述言語
全体動作を実行するハードウェアを合成できる。
【0224】
バイトコード生成部の関数定義例は以下のとおりである。
関数名:write_network_difinition(output_node, path, format)
関数仕様:output_nodeから入力側に向かってつながるネットワーク構成をformatに指定された形式でpathで指定したファイルに出力する。output_nodeはリストで指定可能である(複数のノードを起点にできる)。
【0225】
バックワード処理のための参照構造からバイトコードを出力する手続き例
上記第1部において説明したとおり、Chainerは自然なフォワード処理の計算の記述に従ってバックワード処理のための参照構造を生成する機能を持つ。フォワード処理はバックワード処理のための参照構造を逆順にたどれば計算できるので、この参照構造からバイトコードを生成すれば、フォワード処理及びバックワード処理双方の処理が実行可能となる。
この手順は大きく以下のステップに分けられる。
(1)バイトコード作成のための要素情報生成
入出力データ情報生成
重み情報生成
バックワード処理時Function呼び出し情報生成
(2)要素情報のバイトコードへの変換
【0226】
バイトコード作成のための要素情報生成手順
-「バックワード処理のための参照構造」をwrite_network_difinitionに渡されたoutput_nodeを起点にたどって以下の処理を実行する。
(1)現在のノードがVariableの場合には、その多次元配列の情報(サイズ・次元数,浮動小数点/固定小数点(Q値))を「入出力データ情報」のリストに加える。
(2)現在のノードがFunctionの場合には以下の処理を行う。
(i)重みの多次元配列の情報(サイズ・次元数, 浮動小数点/固定小数点(Q値), 重みの実現値)を「重み情報」のリストに重複を許さないように加える(複数のFunctionインスタンスが同一の重みを共有し得るため)。
(ii)Functionの種別, 入出力データのindex, 重みのindex, Functionの種別毎に固有のパラメータを「Backward時Function呼び出し情報」のリストに加える。
output_nodeに複数の起点ノードが渡された場合、次段落の手順で同じノードが重複登録されることを避ける。
【0227】
複数の起点ノードが渡された場合の要素情報作成手順
(1)「バックワード処理時Function呼び出し情報」のリスト(空)を作成する。
(2)output_node内の起点ノードごと以下の手順を行う。
(A)起点ノード固有の「バックワード処理時Function呼び出し情報」のリストを作成する。
(B)前段落で説明した登録手順を上記(A)で作成したリストに対して行う。このとき、上記(1)で作成したリストに既に登録されているノードについては登録手順を実行しないようにして重複登録を避ける。
(C)上記(1)で作成したリストの前方に上記(A)で作成したリストを連結する。
【0228】
Python層:バイトコード出力器(6)
要素情報のバイトコードへの変換
「バイトコード作成のための要素情報生成」の手順で作成した以下の情報を、write_network_difinitionのformat引数で指定されたフォーマットへ変換する。
(1)入出力データ情報生成
(2)重み情報生成
(3)バックワード処理時Function呼び出し情報生成
フォーマットとしては「バイトコード生成部」について先に例示したものが挙げられる。
【0229】
複数のネットワーク構成の出力
「バイトコード生成部」について上述したwrite_network_difinition関数は、引数pathで渡されたファイルに直接ネットワークの構成を書き出す仕様となっているが、このpath引数に複数のネットワークの構成をバイトコードに書き出すためのオブジェクトを渡すこともできる。ここでネットワーク構成とは「Python層:バイトコード出力器(6)要素情報のバイトコードへの変換」で解説した(1)、(2)、(3)の構成要素を示す。
この「複数のネットワークの構成をバイトコードに書き出すためのオブジェクト」は、「複数のネットワーク構成」の間で同一の「(2)重み情報」を共有化し、バイトコードに書き出す重み情報を削減する。「(1)入出力データ情報生成」と「(3)バックワード処理時Function呼び出し情報生成」は、部分的な情報に重複が見られる場合も、上述のステップにより独立に生成する。このオブジェクトを利用する場合のコード例を
図40に示す。このコード例では6行目では、nodeAからバックワード処理のための参照構造をたどりネットワークの構成を出力し、さらに7行目では、nodeBからバックワード処理のための参照構造をたどりネットワークの構成を出力する。8行目においてこれら2つのネットワーク構成が1つのファイル(./bytecode.bin)に出力される。
【0230】
同一ネットワークに対するフォワード処理とバックワード処理とで異なるFunction呼び出し順序を指定する方法
Chainerは、上記第1部において説明したとおり、特定のVariableインスタンスを起点にそこから入力層側へ向かうBackwardのための参照構造を打ち切る機能(unchain_backwardメソッド)を持っている。このunchain_backwardメソッドと前段落で説明した「複数のネットワーク構成の出力」を組み合わせることで同一ネットワークにおけるフォワード処理とバックワード処理の計算に対して異なるFunction呼び出し順序を指定することもできる。
図41に示すコード例では、#1の呼び出しでAからDまでの全ての処理を実行するネットワーク定義が出力されるのに対して、#2の呼び出しではBからDまでの処理のみが実行されるネットワーク定義が出力される。仮想マシンによるバイトコード実行時に#1で出力されるネットワーク構成に対してForward処理を行い、#2のものに対してBackward処理を実行するなどといった使い分けが可能となる。
【0231】
10.Native層及びPython層に共通する構成
10-1.複数のNNアルゴリズムを融合したアルゴリズム実行部
一般のニューラルネットの構成には頻出するFunctionの組み合わせが見られる
(例1)Linear→ReLU, Linear→ReLU→Linear→ReLU
(例2)Convolution2D→ReLU, Convolution2D→ReLU→Convolution2D→ReLU
こうした頻出するFunctionの組み合わせを1つのFunctionとして定義し、Python層及びNative層双方でその計算に特化した実装を行うことで、アルゴリズム設計においてもハードウェア実行効率においても以下のようなメリットを享受できる
(1)Functionを呼び出すためのオーバーヘッド(関数呼び出しや通信)を削減できる。
(2)複数のFunctionにまたがるデータの依存関係や並列性を考慮した実装により、高い実行効率を得られる(キャッシュメモリを有効活用しメインメモリに直接アクセスするデータ量を削減するなど)。
(3)アルゴリズム設計時により抽象化したFunctionを用いることで複雑なネットワーク構成を理解・定義しやすくなる。
【0232】
一般に近年の計算機は演算コアの速度向上が著しいのに対して、メモリアクセスの性能はそれほど高速化されていない。このため計算機全体の性能を見たときメモリアクセスに律速され十分な計算性能を達成できない課題がある。このような課題を解決するため演算コアに物理的に近い場所にキャッシュメモリやレジスタファイルと呼ばれる小容量であるが特別に高速なメモリを配置し、キャッシュメモリ上で多くの計算を行うことで、両者の速度ギャップを埋める仕組みが用いられている。
【0233】
ところで、ニューラルネットの構成には頻出する以下のようなFunctionの組み合わせが見られる。
・Convolution2D→ReLU
・Convolution2D→ReLU→Convolution2D→ReLU
Convolution2Dは、入出力するデータサイズに対して計算量が大きいので、キャッシュメモリなどの仕組みを有効活用し計算コアの性能を発揮できるチャンスが大きい。これに対してReLUは、入出力するデータサイズに対して計算量が小さいので、このチャンスは小さい。
Convolution2DとReLUを個別のFunctionとして実行する場合、Convolution2Dの処理結果のデータを全てメインメモリに書き出した後、その内容を再び演算コア周辺に転送しReLUの計算を行う必要がある。その理由はConvolution2Dの処理が終わった後にその結果を直ぐにReLUが用いるか否かが分からないためである。
【0234】
そこで、Convolution2DとReLUを一体のFunctionとして実行すれば、Convolution2Dの処理結果をメインメモリに書き出す前に、キャッシュメモリやレジスタファイル上で直接ReLUの処理の入力として用いることができるので、メインメモリへのデータ転送の頻度を少なくし、より効率的(高速)に処理を実行できるチャンスが増える。
Convolution2D→ReLU→Convolution2D→ReLUのようにさらに多くのFunctionを一体のFunctionとして実行できれば、処理効率向上のチャンスはさらに増える。キャッシュメモリのサイズや、Functionの組み合わせの中でのデータの依存関係を勘案し、さらに積極的にメインメモリへのアクセス量を削減できるからである。
【0235】
10-2.Forward処理実行を特化させた最適化装置の構成1;重みの最適化処理手段を有する場合
ニューラルネットワークのレイヤーアルゴリズムの中には、バックワード処理を行わずフォワード処理のみを実行する場合に特化した重みの最適化を行うことで計算量やメモリ使用量を削減できるものが存在する。このような最適化が可能な理由は以下による。
確率的勾配降下法を用いてニューラルネットを学習するには重みのベクトルに高い数値精度と高い値域の自由度が必要である。なぜなら、学習時に小さな値の更新を積み重ねていく必要がある上、事前に重みのベクトルが変化する値域を十分に想定できないためである。これに対して、Forward処理だけを実行するのであればこのような精度と自由度の両立は必要なく重みの情報量を削減した上でForward処理を実行するようにすればメモリや計算量を削減することができる。計算量を削減できるのは重みの要素数を削減したり0の重みを計算しないなどの対応がとれるからである。例えば、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)の違いを隠蔽する(再初期化の実装を呼び分ける)機能を持つ。
【0236】
ソフトウェアハードウェア構成に関する補足
これまでPython層、Native層の関数やクラスに特定の機能を従属されることを例示して実施形態の詳細を説明してきた。しかしながら、これらのソフトウェア階層、クラス、関数の役割分担は、本発明の実施形態に係る機能の構成を具体的に説明するための一例を示したものに過ぎず、以下の例に示すように本発明の実施形態に係る個々の機能がこれまでの説明とは別のクラスや、階層、あるいはハードウェアに実装されることも考えられる。(1)「Forward処理実行を特化させた最適化装置の構成2;データメモリ領域の再利用手段を有する場合」で説明した処理内容は仮想マシンモジュールではなくバイトコード出力器であらかじめ実行できる。
(2)「複数のFunctionを組み合わせたFunction」で説明したFunctionはソフトウェアレベルの最適化ではなく特化したハードウェア(FPGA, ASIC)で実装できる。
よって、本発明の実施形態に係る構成はPython層、Native層の関数やクラス、あるいはソフトウェアを前提とした実装に直接依存するものではない。
【符号の説明】
【0237】
10 学習装置
100 評価ボード
110 取得部
120 記憶部
130 実行部
200 組み込み系チップ(組み込み系半導体集積回路)
401 駆動部
402 Functionクラス/Optimizerクラス
405 Native層実行部
408 Native用多次元配列
409 Variableクラス
504 バイトコード生成部
505 デバイス管理モジュール
506 データ変換モジュール
507 多次元配列モジュール
508 Functionモジュール/Optimizerモジュール
509 仮想マシンモジュール
510 メモリプールモジュール