人権を購入した。人権はとても費用が掛かる。 これで我が家のメインメモリは32GBになり、ハードディスクからSSDデビューだ! (プライベートのSSDデビューは初めて)
とりあえず、これまでのHDDは何だったのか。ベンチマークを取得してみると爆速になっている。これはすごい。
7.3章はがっつりディープニューラルネットワークの内容だ。今回は多層パーセプトロン、畳み込みニューラルネットワーク、再帰型ニューラルネットワーク。
これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。 長々と書いたけれども、Tensor Processing Unitの論文よりも詳細なことは書いていない。そりゃそうか。
Tensor Processing Unit(TPU)はGoogleの最初のWSC向けDSAのASICである。 個のチップのターゲット領域はDNNの推論フェーズであり、またDNN向けに設計されたTensorFlowフレームワークを使ってプログラミングを行うことが出来る。 TPUの第1弾は2015年にGoogleのデータセンタにデプロイされた。
TPUは65,536(256×256)個の8-bit 行列積ユニットALUを備え、ソフトウェア管理のオンチップメモリが搭載されている。 TPUはシングルスレッドで、決定的な実行モデルは、99パーセンタイルのレスポンスタイムが必要とされる典型的なDNNの推論アプリケーションにうまく適合している。
2006年に、GoogleのエンジニアはデータセンタにおけるGPU、FPGA、カスタムASICのデプロイについて議論を行った。 彼らは、特殊なハードウェアを必要とするアプリケーションで、大容量データセンタの過剰な計算能力を使っても仮想的に実行することが出来るものは少なく、これらを自由に改善することは難しいとの結論に達した。 2013年にはこの議論の結論は変わり、ユーザが1日に3分ほどDNNの音声検索を使用するならば、その計算能力を間に合わせるためにはGoogleのデータセンタを倍増しなければならないという結論に達した。 このデータセンタの増強は伝統的なCPUを使って達成するには非常にコストのかかるものであった。 Googleは推論処理を実行するためのカスタムASICチップを開発するためのプロジェクトを急ピッチに立ち上げた(と、トレーニングに必要なGPUの在庫を購入した)。 目標はGPUの10倍以上のコスタ性能を達成することであった。 この目標を元に、TPUは設計、検証、組み立て、デプロイがたった15ヶ月の間に行われた(Steinberg, 2015)。
デプロイが遅延することを避けるために、TPUはPCIe I/Oバスに接続されるコプロセッサとして設計され、既存のサーバに接続されるように設計された。 さらに、シンプルなハードウェア設計とデバッグ機能をもっており、ホストサーバがPCIeバスを通じてTPUに指令を転送する。 これはTPU自身が命令をフェッチする機構を取っているわけではない。 したがって、命令をメモリから自分でフェッチするGPUとは異なり、TPUはFPU(浮動小数点ユニット: Floating Point Unit)コプロセッサのような考え方を元に設計されている。
図7.12はTPUのブロックダイアグラムを示している。 ホストのCPUはPCIeバスを通じてTPUの命令バッファに命令を転送している。 内部ブロックは256バイト(2048ビット)幅で接続されている。 右上ブロックから始まって、「行列積ユニット(Matrix Multiply Unit)」がTPUの心臓部である。 行列積ユニットは256×256個の符号あり・無しの8-bit整数積和演算ALUが内蔵されている。 32-bit幅の、4MBのアキュムレータによって、16ビットの結果が格納される。 8bitの重みと16bitの値を使って、ビット幅を混在させた場合は、行列積ユニットは半分の速度で実行する。 また、両方とも16bitの値を使った場合は行列積ユニットは4分の1の速度で計算を実行する。 1クロック当たりに256個の値を読み書きし、行列積と畳み込みのどちらかを計算することが出来る。 「活性化(Activation)」ユニットを使って、非線形関数の計算が行われる。
行列ユニットの重みデータは、オンチップメモリの「重みFIFO(Weight FIFO)」を通じて格納される。 この値は重みメモリ(Weight Memory)と呼ばれるオフチップの8GBのDRAMから読み込まれる(推論用で、重みは読み込み専用、8GBはは多くのアクティブモデルをサポートしている)。 中間結果は24MBのオンチップの「ユニファイドバッファ(Unified Buffer)」に格納され、行列積ユニットの入力値として使用される。 プログラマブルDMAコントローラはデータをCPUホストメモリとユニファイドバッファの間を転送する役割を持っている。
TPUの命令は比較的低速なPCIeバスを通じて転送されるため、TPU命令は伝統的なCISC命令形式であり、リピートフィールドを持っている。 TPUはプログラムカウンタを持っておらず、分岐命令も持っていない; 命令はホストCPUから転送され、これらのCISC命令の命令辺りに必要なクロックサイクル数(CPI)は典型的に10~20サイクルである。 命令種類は1ダース程度であるが、5つのカギとなる命令がある。
Read_Host_Memory
命令はCPUのホストメモリからユニファイドバッファにデータを転送する。Read_Weights
命令は重みメモリから重みデータを重みFIFOに転送し、行列ユニットの入力値として使えるようにする。MatrixMultiply/Convolve
命令は行列積ユニットを実行し、ユニファイドバッファのデータを使用して行列積、ベクトル行列積、要素毎の行列積、要素毎のベクトル積、もしくはの畳み込み演算を実行し、結果をアキュムレータに格納する。行列の演算は可変サイズを取ることが出来、B*256の入力と、256×256の行列積を実行し、B*256個の結果を出力する。これにはBサイクル必要である。例えば、入力が256要素の4ベクタであるならば、Bは4であり、計算の完了までに4サイクルが必要である。Activate
命令は人工ニューロンのための非線形関数を実行し、ReLU、シグモイド、tanhなどを実行することが出来る。このユニットの入力はアキュムレータから提供され、計算結果はユニファイドバッファに格納される。Write_Host_Memory
命令はデータをユニファイドバッファからCPUのホストメモリに書き込む。TPUのマイクロアーキテクチャの哲学は、なるべく行列積ユニットを動作させ続けるということである。
他の命令の実行を、行列積の実行であるMatrixMultiply
命令とオーバラップさせて隠すという考え方である。
したがって、実行命令以外の、4つの一般的なカテゴリの命令は個別の命令ハードウェアを持っている(ホストメモリとの読み書きは、同一のユニットを使って実行される)。
命令並列性を向上させるためには、Read_Weights
命令はDecoupledアクセス/実行方式(Smith, 1982b)に則って設計されている。
これは計算を完了するのは、アドレスを転送した後であるが、計算完了前に重み情報は重みメモリからフェッチされるという方式である。
行列ユニットはNot-Ready信号をユニファイドバッファからもらっており、重みFIFOは行列ユニットにストール信号を転送し、重みデータの到着を待たせることが出来る。
ここでTPUの命令は複数クロックサイクルで実行され、伝統的なRISCパイプラインのように1サイクルで1ステージを通過していくわけではないということに注意である。
大きなSRAMから読み書きを行うことは、演算よりもコストが高いため、行列積ユニットはシストリック実行方式を取っており、ユニファイドバッファからの読み書きの回数を削減している(Kung and Leiserson, 1980; Remacher et al., 1991; Ovtcharov et al., 2015b)。 「シストリックアレイ(Systoric Array)」は2次元状に演算器を並べており、各演算器は独立して計算を実行し、関数の部分計算結果を次の演算ユニットに転送する。 データは異なる方向からセルに対して一定の間隔で転送で転送される。 アレイ内のデータフローはウェーブフロントのように転送されるため、人間の血管構造に似ており、この構造がシストリックと呼ばれる由来になっている。
図7.13はシストリックアレイが動作する様子を示している。 下側の6つの丸が積和演算ユニットであり、重みで初期化されている。 ステージングされたデータが、このアレイの上側から転送されてきている。 この図では10ステップ毎のデータ転送の様子を示している。 シストリックアレイは入力値を下側に転送し、積と和を右側に転送している。 シストリックアレイは入力データはメモリからのみ読み込まれ、出力データは1度だけメモリに書き込まれることに注意である。
TPU内では、シストリックアレイはローテートされる。 図7.14では、重みデータは上部からロードされ、入力データは左側から転送されアレイ中を通過する。 256要素の積和演算器は行列中を通過し、斜め方向にウェーブフロントとして通過する。 重みデータはあらかじめロードされ、ウェーブ中でデータブロックの最初のデータとして進んでいく。 制御情報とデータも一緒に転送され、256個のアキュムレータのメモリのデータをアップデートしてく。 正確性という面からはソフトウェアは行列ユニットのシストリックの構成については意識しないが、ユニットのレイテンシについて考慮する必要がある。
TPUチップは28-nmプロセスを使って製造されている。 動作周波数は700MHzである。 図7.15はTPUのフロアプランを示している。 ダイサイズは公表されていないが、Intel Haswellサーバマイクロプロセッサの662mm2の半分以下の大きさである。
24MBのユニファイドバッファが1/3を占めており、行列乗算ユニットが1/4、データパスが台の2/3を占めている。 24MBの大きさは行列ユニットの大きさと適合するようにできており、コンパイラを単純化することで開発期間を単純化している。 制御ユニットは全体の2%である。 図7.16はTPUのプリント基板であり、既存のSATAディスクスロットに挿入して使用する。
TPUのソフトウェアスタックはCPUでの開発やGPUでの開発と互換性があり、アプリケーションを短期間で移植することが出来る。 典型的に、アプリケーションをTPU上で実行するときはTensorFlowとそのコンパイルされたAPIを使ってGPUもしくはTPU上で実行する(Larabel, 2016)。 図7.17はTesorFlowを使ってMLPを実行するコードである。
GPUのように、TPUスタックはユーザスペースドライバとカーネルドライバに分かれている。 カーネルドライバは軽量で、メモリ管理と割り込みを管理するだけである。 これは長期間において安定するように設計されている。 ユーザスペースドライバは頻繁に変更される。 ユーザスペースドライバはTPU実行のセットアップと制御を担当し、TPUの形に合うようにデータを変換し、APIコールをTPUの命令に変換してアプリケーションバイナリに変更する。 ユーザスペースドライバは、コードが評価されると、まずモデルをコンパイルし、プログラムイメージをキャッシュして重みイメージをTPUの重みメモリに書き込む; これにより2番目以降の評価ではフルスピードで動作することが出来る。 TPUは入力から出力までほとんどのモデルを完全に実行することができ、TPUの実行時間とI/O時間の比率を最大化する。 計算はしばしば一度に1レイヤで終了し、クリティカルパスではない処理によって行列演算の処理をオーバラップしてレイテンシを隠蔽する。
TPUアーキテクトはTPUをより向上させるために多くのマイクロアーキテクチャを検討した。
FPUと同様にTPUのコプロセッサは比較的簡単なマイクロアーキテクチャである。したがってTPUアーキテクトは性能モデルを作成し、メモリのバンド幅、行列ユニットのサイズ、クロックレートとアキュムレータの数を利用して性能を見積もった。 TPUハードウェアカウンタを使った測定では、作成したモデルとハードウェアとは約8%の誤差が存在した。
図7.18は、これらのパラメータによりTPUの性能にどの程度影響があるかを0.25倍から4倍の間で比較したものである(7.9章のベンチマークを使用した)。 クロックレートを向上させたもの(図.18のClock)に加えて、図7.18ではクロックレートを向上させたものとアキュムレータの数を増やしたものを追加しており、したがってコンパイラは実行中のメモリ参照を増やすことが出来る。 同様に、図7.18はアキュムレータの数が2乗に増加した場合に行列ユニットを拡張した場合の性能向上を示している。 一方で"matrix"は行列ユニットを向上させただけである。
まず、メモリバンド幅を向上させた場合(memory)は最も大きなインパクトがあった: メモリバンド幅を4倍にすると、性能は4倍になり、これは重みメモリの待ち時間が削減されたからである。 次に、アキュムレータの数を変更せずにクロックレートのボトルネックはわずかであったであるということである。 3番目に、行列ユニットを256×256から512×512にしても、アキュムレータの数を増やしてもそうでなくても、図7.18の平均的な性能はわずかに低下するだけであった。 この問題は大きなページを扱った場合の内部フラグメンテーションの問題に似ている。 TPUでは2次元のデータしか扱わないためである。
LSTM1において600×600の行列を使った場合は、256×256の行列ユニットでは600×600の行列を全て計算するために9ステップ必要で、合計で18usとなる。 より大きな512×512の行列ユニットを使った場合は4ステップで完了させることが出来るが、各ステップの計算時間が4倍になり、32usの時間がかかる。 TPUのCISC命令は長いため、デコードはDRAMからのロードのオーバヘッドを隠蔽することはできない。
性能モデルから得られる結果を見て、TPUアーキテクトはもしさらに15ヶ月を使って設計した場合の仮説を立てた。 よりアグレッシブな論理合成と、ブロックデザインのクロック周波数を約50%向上することが出来たと考えている。 アーキテクトは、K80で使われているようなGDDR5メモリのインタフェースを設計することで、重みメモリのバンド幅を5倍近く向上させることが出来ると考える。図7.18に示すように、クロックレートを1050MHzにしても、メモリの支援が無ければ性能にほとんど影響を与えない。 もしクロックレートが700MHzのままでも、GDDR5を重みメモリに使用すると、性能は約3.2倍に向上する。 これらを両方実施しても、さらに性能を向上させることはない。
ヘネパタ第6版こと、"Computer Architecture 6th Edition" では、第7章でドメイン固有アーキテクチャの章が新設された。 これを機会に、しっかり読んでいこう。
7.3章はがっつりディープニューラルネットワークの内容だ。今回は多層パーセプトロン、畳み込みニューラルネットワーク、再帰型ニューラルネットワーク。
これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。 2018/01/03 追記。フューチャーマップ(future map)→特徴マップ(feature map)の誤訳でした。訂正します。
MLPはDNNの原型である。
それぞれ新しいレイヤは非線形関数F
の集合であり、ひとつ前のレイヤの全ての出力と重みを掛け合わせた値 で構成されている。
重み付き加算値は、出力値と重みのベクトル-行列積で構成されている(図7.7を参照のこと)。
このようなレイヤは"Fully-Connected"と呼ばれており、これは各出力ニューロンの結果は、前のレイヤの入力ニューロンに依存しているからである。
DNNの形によって、レイヤ当たりのニューロン量、演算量、重みの量は計算することが出来る。 最も簡単なのはMLPで、入力ベクトルと重み行列のベクトル-行列積を実行するだけである。 以下に、推論に必要な重みの数と演算量のパラメータと式を示す(ここでは、積和演算については2演算として計算している)。
最後の項は「演算強度(operational intensity)」と呼ばれ、第4章でルーフラインモデルとして議論したものである。 私たちは、通常、チップに収まらない何百万という重みが存在する可能性があるため、重みあたりの演算量という指標を用いる。 例えば、1ステージ当たりでMLPの次元数は7.9章で であり、したがってニューロンの数は2048個、そして重みの数は8,388,608であり、演算量は16,777,216であり、演算強度は2である。 ルーフラインモデルで述べたように、演算強度が低い場合は、高い演算性能を出すのが難しくなる。
ReLUはMLPでは有名な非線形関数である。多くの場合は入力レイヤと出力レイヤの次元数は異なる。このようなレイヤはfully connectedレイヤと呼ばれ、これは出力レイヤは前のレイヤのすべての入力に依存しているからである。これは殆どの値がゼロでも同じことがいえる。ある研究では、前のレイヤの値の44%がゼロであるが、これはReLUにより負の数がすべてゼロにされるからであると推定することが出来る。
CNNはコンピュータビジョンのアプリケーションにおいて広く利用されている。 画像は2次元の構造をしており、隣接するピクセルは関係性を見出しやすい。CNNは前のレイヤからの出力値のうち、空間的に隣接する領域の情報を非線形関数を受け取り、何度も再利用している重みを掛け合わせる。
CNNのアイデアの背景には、各レイヤは画像の抽象レベルに対応していると考えることが出来る。 例えば、最初のレイヤは水平方向と垂直方向のラインを特定するためのレイヤと考えることが出来る。 2番目のレイヤは、コーナーを検出するためにこれらの情報を組み合わせるためのレイヤである。 次のステップでは四角形と丸を識別するためのレイヤである。 次のレイヤは犬の部品、例えば目屋耳などを識別するためのレイヤである。 より高いレイヤでは、犬の種類名の違いなどの特徴を識別するためのレイヤである。
各ニューラルレイヤは2次元の「特徴マップ(feature map)」と呼ばれる、特徴マップの各セルが入力画像の対応する領域化から1つの特徴を識別するための情報を生成する。
図7.8は入力画像から2×2のステンシル計算を行い、最初の特徴マップの要素を生成するための最初のポイントを示している。 「ステンシル計算(stencil computation)」は固定のパタンから、隣接するセルを使って、アレイ中のすべてのエレメントを更新する。 出力された特徴マップの数はあなたが画像から何個の異なる特徴を抽出するかと、ステンシルを抽出するために利用するストライドの量に依存する。
通常、画像は単一のものでは無く、フラットな2次元のレイヤであるため、この処理はより複雑なものになる。 典型的には、画像データは赤、青、黄色の3レベルの情報を持っている。 例えば、2×2のステンシルは12個の要素にアクセスすることになる: 2×2の赤ピクセル、2×2の青ピクセル、2×2の緑ピクセルである。 この場合には、2×2のステンシルで3レベルの3つの竜力レベルの画像では、出力特徴マップ当たり12個の重みが必要である。
図7.9は入力と、最初のレイヤから生成された出力特徴マップの任意数について示している(xxx)。 計算は1組の重みを有するすべての入力特徴マップに対する3次元ステンシルであり、1つの出力特徴マップを生成する。
数学が好きな読者のために説明すると、もし入力特徴マップと出力特徴マップが同一で1であり、ストライドが1である場合、2次元CNNの単一レイヤは2次元の離散した畳み込みである。
図7.9に見るように、CNNはMLPよりも複雑である。 重みと演算量についてパラメータと等式を示す。
7.9章のCNNは、, , , である。 このレイヤでは25,088個のニューロン、73,728個の重み、28,901,376演算量が必要である。したがって演算強度は392である。 私たちの例では、CNNはMLPのfully connectedなレイヤよりも重みの量は少なく、高い演算強度を持っている。
3次元の入力特徴マップから、単一の出力特徴マップへの生成を行う。各出力特徴ーマップはそれぞれ独立した重みの集合を持っており、ベクトル―行列積によりすべての要素が演算される。点線は将来衛星される特徴マップである。この図が示しているように、入力および出力特徴マップの次元及び数はしばしば異なるものになる。MLPと同様に、ReLUはCNNのための有名な非線形関数である。
3番目のDNNの型はRNNである。これは音声認識や言語翻訳などの分野で有名なネットワークである。 RNNはDNNモデルに対してステートを追加して順次入力を追加することにより、RNNが事実を記録することが出来るようになる。 これはハードウェアにおける組み合わせ論理とステートマシンの違いと似ている。 例えば、あなたが非との性別を学習したい場合、翻訳した言葉を記憶しておき、あとでもう一度パスさせたいということもあるであろう。 RNNの各レイヤは前のレイヤで生成した重みと入力の掛け合わしたものと、前の状態を入力として受け取る。 重みは、時間のステップで再利用される。
「Long short-term memory(LSTM)」はRNNの種類としては現在断然有名なネットワークである。 LSTMはこれまでのRNNが重要な長期情報を記憶することが出来なかった問題に解決策を示した。
これまでの2つのDNNと異なり、LSTMは仮想的なデザインである。 LSTMは「セル(cell)」と呼ばれるモジュールから構成されている。 セルは完全なDNNモデルを生成するためのテンプレートもしくはモデルと考えることが出来る。 これはMLPを並べて完全なDNNモデルを生成させる問題と似ている。
図7.10はLSTMセルがどのようにお互いにリンクしているのかを示している。 各セルは左から右に接続されており、ひとつのセルの出力が次のセルの入力へ接続されている。 またこれは図7.10においてトップダウンで時間軸として展開されている。 したがって、文章はアンロールされたループの1回の繰り返し当たりの入力となる。 LTSMの名前が示す通りの長期記憶と短期記憶の情報は、トップダウンであるイタレーションから次のイタレーションへ渡される。
図7.11にLSTMセルの内容を示す。 図7.10に示したように、入力値は左側、出力値は右側に示しており、2つのメモリの入力は上側、2つのメモリの出力は下側に示している。
各セルには5つのベクトル行列積を実行し、5つの独立した重み値を使っている。 入力値の行列積は図7.7のMLPのようになっている。 3つのそれ以外の行列積は「ゲート(gates)」と呼ばれており、あるソースから標準出力もしくはメモリ出力として渡される際の情報をゲートもしくは制限するためのものである。 ゲートあたりに通過する情報はこれらの重みにより設定される。 もし重みがほとんどゼロ、もしくは小さな値であった場合、多くの情報は通過しない; 一方で、これらの重みがほとんどが大きければ、ゲートはほとんどの情報を通過させる。 3つのゲートは「入力ゲート(input gate)」「出力ゲート(output gate)」「忘却ゲート(forget gate)」と呼ばれている。 最初の2つのゲートは入力と出力をフィルタリングし、最後のゲートはLong-termメモリパス中で何を忘却するかを決定する。
Short-termメモリの出力はShort-Termの重みとベクトル行列積を通じて、そのセルの出力となる。 SHort-termラベルはセルの入力を直接使用されないため適用される (xxx)。
LTSMセルの入力と出力はすべて互いに接続されているため、3つの入力・出力のペアのサイズは同一である。 セルの中身を見てみると、すべての入力と出力はしばしば同じサイズであるという十分な依存が存在する。 これらはすべて同じサイズ出ると仮定し、これを とする。
たとえそうであっても、ベクトル―行列積はすべて同じサイズではない。 3つのゲートの乗算はである。なぜならば、LSTMはすべての3つの入力を接続するからである。 入力のベクトルは である。なぜならばLSTMは入力とShort-termメモリの入力を1つのベクトルとして接続するからである。 最後の乗算の入力は単純に出力に接続されるため である。
したがって、重みと演算量は以下のように計算できる。
7.9章のLSTMでは6つのセルを持っておりDimは1024である。 重みの量は12,582,912であり、演算量は25,169,920である。演算強度は2.0003である。 LSTMはMLPと同様に重みを多く保持しており、CNNよりは演算強度が低い。
ヘネパタ第6版こと、"Computer Architecture 6th Edition" では、第7章でドメイン固有アーキテクチャの章が新設された。 これを機会に、しっかり読んでいこう。
7.3章はがっつりディープニューラルネットワークの内容だ。用語集も入っている。これを機にしっかり勉強しよう。
これは著者が読んだ内容をまとめているだけなので、誤訳、理解不足により誤っている可能性があります!鵜呑みにしないようにお願いします。
人工知能(Artificial Intelligent:AI)は次世代のコンピューティングの次なるビッグウェーブであるだけでなく、人類の歴史の大きなターニングポイントかもしれない...知能の進化は、データ、ニューラルネットワーク、そして計算パワーによって起きるのかもしれない。 IntelはAIに投資している... 我々は、AIの普及と発展に必要な最新のアクセラレータを開発した。
人工知能は正規の切り替わりをまたいで、ドラマティックな返り咲きをした。 人工知能を、多くのロジカルループとして「組み立てる」代わりに、議論の焦点は人工知能を通過させるサンプルデータから、「マシンラーニング(Machine Learning)」へと移り変わった。 学習に必要なデータの量は考えていたものよりも非常に多くのものが必要であった。 今世紀のウェアハウススケールコンピューティング(Warehouse Scale Computing: WSC)により、数十億のユーザと彼らのスマートフォンから、十分な量のデータがインターネット上で見つかったペタバイトの情報を収納して格納し、十分なデータ量を提供している。 私たちはこの非常に多くのデータから学習を行うのに必要な計算の量を低く見積もった。 しかし、GPUというWSCのサーバに組み込まれている単精度浮動小数点の計算コストが非常に高い計算機を使うことにより、十分な計算量を提供できるようになった。
機械学習の一部分であるDNNと呼ばれる領域は、過去5年間でAI分野のスターということが出来る。 DNNは例えば言語翻訳の能力を向上させ、過去10年間の進歩に比べて、さらに進歩を遂げている(Tung, 2016; Lews-Kraus, 2016); DNNに切り替えることにより、過去5年間で達成している画像認識のエラー率は26%から3.5%に減少した(Krizhevsky et al., 2012, Szegedy et al, 2015; He et al., 2016); そして2016年には、DNNは囲碁の分野において初めて人間を倒すことが出来るプログラムを生成することが出来るようになった(Silver et al., 2016)。 多くのこれらの技術がクラウドで実行されているが、第1章で述べたように、これらはスマートフォン上でGoogle翻訳を実行することが出来る。 2017年には、新しい重要なDNNの研究結果が毎週発表されるようになっている。
本章に書かれていること以上に、DNNについて興味を持った読者は TensorFlowのチュートリアルをダウンロードして実行してみるべきだ (TensorFlow Tutorials, 2016)。そこまで野心的でない場合でも、DNNの無料のオンラインテキストを読んでみることをお勧めする。
DNNは脳のニューロンからインスパイアされている。 人工ニューロンはデータ値と「重み(weights)」もしくは「パラメータ(parameters)」を掛け合わせたものを加算し、それを非線形関数に通して結果を出力する。 これから見ていくように、人工ニューロンはファンインとファンアウトが大きい。
画像認識のためのDNNでは、入力値は画像のピクセルであり、ピクセル値は重みが欠けられる。
多くの非線形関数が施行されたが、現在広く使われているのはf(x)=max(x, 0)
というシンプルなものであり、これはx
が負数であれば0となり、整数であればx
そのものの値が返される。
この関数はRectifier Linearユニットもしくは ReLUという複雑な関数名で呼ばれている。
人工ニューロンのクラスタは、入力値のそれぞれ異なる場所を処理し、クラスタの出力は次の人工ニューロンクラスタの入力値となる。 入力レイヤと出力レイヤの間のレイヤは「隠しレイヤ(hidden layer)」と呼ばれる。 画像処理のためには、各レイヤは異なるタイプの形を認識するレイヤと考えることが出来、エッジや角度などを認識する低レベルのレイヤから、目や鼻を認識する高レベルのレイヤへと進んでいく。 もし画像処理アプリケーションが、犬が移っている画像を認識する場合は、最後のレイヤの出力は0から1までの確率の値で表現されるか、どの犬の品種であるかを示す確率のリストとして表現される。
DNNではレイヤの数により名前が付けられる。 データ数と計算能力が低い時代には、ニューラルネットワークの層数は比較的浅かった。 図7.5は際k人のDNNのレイヤ数、重みの量およびフェッチされる重みあたりの演算量が示されている。 2017年では、いくつかのDNNは150のレイヤ数を持っている。
名前 | DNNレイヤ | 重みの数 | 演算量/重み |
---|---|---|---|
MLP0 | 5 | 20M | 200 |
MLP1 | 4 | 5M | 168 |
LSTM0 | 58 | 52M | 64 |
LSTM1 | 56 | 34M | 96 |
CNN0 | 16 | 8M | 2888 |
CNN1 | 89 | 100M | 1750 |
前章までの議論は、既にプロダクションレベルに入っているDNNについての議論であった。 DNNの開発はニューラルネットワークのアーキテクチャ; レイヤの数とその型、各レイヤの次元とデータのサイズを決めることから始まる。 専門家は多くの新しいニューラルネットワークアーキテクチャを開発するが、ほとんどの、実際にニューラルネットワークを使用する人は、既存の類似の問題に対するニューラルネットワークと同様のネットワークを選択することになる(例えば、図7.5)。
一度ニューラルネットワークの形を選択すると、次のステップでは、ニューラルネットワークグラフの各エッジの重みを決めていくことになる。 重みによって、モデルの挙動が決定される。ニューラルアーキテクチャの選択に依存して、単一のモデルで数千から何億個もの重みを決めていく必要が生じる(図7.5を参照のこと)。 トレーニングは、これらの重みをチューニングするためのプロセスであり、DNNが複雑な関数を近似するためにコストのかかる処理である (例えば、画像からその画像内のオブジェクトをマッピングする処理など)。
この開発フェーズは一般的に「トレーニング(training)」あるいは「学習(learning)」と呼ばれ、一方でプロダクションフェーズは多くの名前で呼ばれている「推論(inference)」「予測(prediction)」「scoring(採点)」「実装(implementation)」「評価(evaluation)」「実行(running)」「テスト(testing)」である。 殆どのDNNは「教師あり学習(supervised learning)」と呼ばれる、データがあらかじめ処理されており正しいラベルを取得することのできるデータ群を使って訓練が実行される。 したがって、ImageNet DNNのコンペティションではトレーニングセットは120万枚の画像と各画像は1000カテゴリに渡ってラベルが振り分けられている(Russakovsky et al., 2015)。 いくつかのラベルは非常に詳細に記述されており、例えば犬や猫の種類まで記述されている。 優勝者は、別に用意された50,000毎もの画像をDNNに通して、最も低い誤認識率を得られるかによって決定される。
ニューラルネットワークの重みづけは、トレーニングセットを使用してニューラルネットワーク内の「バックワード(backward)」処理を繰り返すことによって設定される。 この処理のことを「バックプロパゲーション(backpropagation)」と呼ばれる。 例えば、トレーニングセット内で犬の種類について情報が得られれば、DNN内でこの画像が何であるかが分かり、今後より正確な答えが出せるようにDNN内の重みが調整される。 驚いたことに、トレーニングプロセスの最初に重みを最初にランダム値で設定すべきであり、トレーニングセット内で誤認識率が十分に小さくなるまで繰り返して学習させるべきである。
数学が好きな読者のために説明すると、学習の目標は入力値が複数レイヤのニューラルネットワークアーキテクチャを通して正しい出力値にマッピングさせることである。 バックプロパゲーションは「誤差のバックプロパゲーション(back propagation of errors)」の略である。 バックプロパゲーションはすべての重みについて、入力値の勾配を計算し重みを更新することで、誤認識率を最小化させるためのアルゴリズムである。 DNNにおいてもっとも有名な最適化アルゴリズムは「確率的勾配降下法(stochastic gradient descent)」である。 このアルゴリズムによって、バックプロパゲーションによって得られた降下の勾配を最大化するような重みを比例的に設定する。 より詳細に学びたい読者はNielsen(2016)もしくはTensorFlowのチュートリアル(2016)を参照されたい。
図7.6に示すように、トレーニングには数週間を要する場合がある。 推論フェーズは、データあたりで100ms程度であり、数百万分の一の時間である。 トレーニングは、一回の推論操作に対して非常に多くの時間がかかるが、推論のための全体の計算時間はDNNを使用するユーザの数の積となり、DNNをどの程度使用するかに依存している。
トレーニングが終了すると、あなたはあなたが使用したトレーニングセットが実際に推論を実行するデータを代表したものである事を願ってDNNをデプロイする。 あなたのDNNは非常に人気があり、あなたが開発に費やした時間よりもはるかに多くの時間ユーザに使用される!
データタイプ | 問題領域 | ベンチマークトレーニング セットのサイズ | DNNアーキテクチャ | ハードウェア | トレーニングの時間 |
---|---|---|---|---|---|
text[1] | 単語の推論 (word2vec) | 1000億単語 (Wikipedia) | 2レイヤ skip gram | 1 NVIDIA Titan X GPU | 6.2時間 |
audio[2] | 音声認識 | 2000時間の音声 (Fisher Corpus) | 11レイヤ RNN | 1 NVIDIA K1200 GPU | 3.5日 |
images[3] | 画像分類 | 100万画像 (ImageNet) | 22レイヤ CNN | 1 NVIDIA K20 GPU | 3週間 |
video[4] | アクティビティ認識 | 100万動画 (Sports-1M) | 8レイヤ CNN | 10 NVIDIA GPU | 1ヶ月 |
トレーニングデータセットの無いタスクというものも存在する。例えば、現実世界のイベントにおいて未来を予測するようなタスクである。 ここでは言及しないが「強化学習(reinforcement learning(RL)」という有名なアルゴリズムが2017年には使用されるようになっている。 トレーニングセットによって学習する方式の代わりに、RLは現実世界において動作し、報酬関数と呼ばれる、あるアクションから状況が良くなるか悪くなるかを決定する関数から信号を受け取る。
急速に変化するフィールドにおいて予測をすることは難しいが、3種類のDNNが2017年には主流になっている: 「多層パーセプトロン(MultiLayer Perceptron:MLP)」、「畳み込みニューラルネットワーク(Convolutional Neural Networks: CNNs)」、「再帰型ニューラルネットワーク(Recurrent Neural Networks: RNNs)」である。 これらはすべて教師あり学習であり、トレーニングセットに依存するものである。
あけましておめでとうございます。本年も、「FPGA開発日記」をよろしくおねがい致します。
昨年は、
など、様々なことに手を出した一年でした。
今年の目標として、
去年の目標も継続しているけども!
頑張っていきたいと思います。よろしくお願いします。
年末年始なので、今年一年はどうだったかな、ということでまとめてみよう。
今年の元旦には、こんな目標を立てていたのだった。
あれれ!ほとんど出来て無いじゃないの!
今年は、この記事を含めて349記事を書いた。去年が308記事なのでかなり伸びている。今年はどうしたんだ?暇か?
Jan | Feb | Mar | Apr | Mar | Jun | Jul | Aug | Sep | Oct | Nov | Dec | Total | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2017 | 27 | 21 | 30 | 24 | 33 | 30 | 30 | 29 | 29 | 31 | 33 | 32 | 349 |
2016 | 32 | 31 | 22 | 28 | 25 | 20 | 23 | 19 | 23 | 30 | 29 | 26 | 308 |
2015 | 20 | 27 | 17 | 6 | 28 | 29 | 35 | 31 | 44 | 31 | 34 | 27 | 329 |
11月から12月にかけて、 RISC-V WorkshopやRISC-V メニーコア、Design Solution ForumやRISC-V Day 2017 での発表を行わせていただき、様々な方とお話しすることが出来た。
なんじゃこりゃ!すごい増加だ。さらに、今年のブログのアクセス数をグラフにしてみた。
2017年12月はすごい事になっている。やはりRISC-Vに注目が集まった年であるということが出来る。
12月はAdvent-Calendarに苦しんだ月だった。ただ皆さんのご協力のおかげで無事に完走。ありがとうございます。
今回はPythonを使って、今年1年のタイトル一覧を使って、MeCabを使ってワードクラウドを作った。 へんな文字が出てくるので、filterで処理して切り落としている。
mecab_wordlist = mecab_analysis(text.decode('utf-8')) mecab_wordlist = filter(lambda x: unicode(x, 'utf-8') != unicode('みる', 'utf-8'), mecab_wordlist) mecab_wordlist = filter(lambda x: unicode(x, 'utf-8') != unicode('やっ', 'utf-8'), mecab_wordlist) mecab_wordlist = filter(lambda x: unicode(x, 'utf-8') != unicode('する', 'utf-8'), mecab_wordlist)
というわけで、来年もよろしくお願いします。
今年開催されたRISC-Vに関係するイベント、 "Design Solution Forum 2017" および "RISC-V Tokyo 2017" で使用した発表資料を公開しようと思います。
Design Solution Forumについては既に登録者限定で公開されているけど、特に隠す必要はないので公開してしまう。
RISC-V Tokyo 2017の資料については、開催後に riscv.tokyo にアップロードされると聞いていたのだけれども、一向にそんな感じがしないので勝手に公開してしまえ、という感じ。 まあ riscv.org でもワークショップの全資料が公開されているからいいんじゃないでしょうか。
RISC-V Tokyo 2017 の資料については日本語版と英語版があり、両方公開します。 たぶん英語版はサブディスプレイで表示してあったと思う。英語の正しさについては、かなり無保証...
注意事項としては、最初の自己紹介の部分は不要なので削除している、バックアップスライドも削除している。
また、資料内の細かい点として、RoCCを使ったアクセラレータの性能測定では、
と差分があるけども、Design Solution Forumの時は対象データを64-bit整数、RISC-V Tokyoの時は対象データを32-bit整数として2-way SIMDとしたのでこのような差が出ている。
あまり大したことは書いていませんが、興味がある方はご覧になってみてください。