深層学習フレームワーク
Chainer  の紹介と
FPGA  への期待
FPGA  エクストリーム・コンピューティング  第7回
2015/08/02  @  ドワンゴ  セミナールーム
得居  誠也  /  Preferred  Networks,  Inc.
⾃自⼰己紹介
l  得居  誠也  (Seiya  Tokui)    @beam2d  (Twitter,  GitHub)
l  PFI  (2012-‐‑‒2014)  -‐‑‒>  PFN  (2014-‐‑‒)
l  専⾨門:機械学習
–  ⾃自然⾔言語処理理、近傍探索索のためのハッシング(修⼠士)
–  Deep  Learning(2012年年秋ごろ〜~)、画像・映像認識識
l  4  ⽉月に  Chainer  を作り始めて今はこれがメイン
2
今⽇日のおはなし
l  Deep  Learning  の実装を紹介します
–  Deep  Learning  でどんなことができるかみたいな話はしません(ウェブ上
のスライドや記事、書籍などを参照していただければと思います)
–  まずニューラルネットの(実装に向けた)定式化についてお話したあと、
Chainer  の実装を紹介します
l  FPGA  の話はしません
–  私は  FPGA  について完全に素⼈人なので……
–  皆様が  FPGA  上にどう実装するか想像しながら聞いていただくスタイルで
お願いします
3
おはなしの流流れ
l  ニューラルネットの実装のための定式化
–  Feed-‐‑‒forward  Net
–  ⼀一般の  DAG
–  誤差逆伝播法
–  全結合層、畳込み層
l  Chainer  の実装
4
Feed-‐‑‒forward  Net
l  ◯  (ユニット)から右に向かって値が流流れる
l  →  (エッジ、コネクション)に紐紐付いた重みパラメータがかけられる
l  ◯  に⼊入るときにそれらが⾜足しあわされる(バイアスと呼ばれるパラメータも⾜足
される)
l  ◯  の中で⾮非線形な関数が適⽤用され、右から出ていく
5
Feed-‐‑‒forward  Net
l  ユニット単位の描像よりも、各段階でのユニットの集まりをまとめてベクトル
として捉えるのが⼀一般的
l  ⾮非線形変換もベクトルに対して⾏行行う(elementwise  である必要はない)
l  つまり  Feed-‐‑‒forward  Net  はベクトルに対して次々に関数を適⽤用する合成関数
6
Feed-‐‑‒forward  Net
l  さらにまとめるとこう
l  使われる値は、ユニットの値とパラメータの⼆二種類
–  各ユニット(ベクトル)の値はデータごとに変わる
–  パラメータ(重み、バイアス)はニューラルネットがなにをどう認識識・予測
するかを決めるもので、学習によって決める(基本的に、⼀一度度決まったら
データごとには変更更しない)
7
⼀一般の  Neural  Net
l  任意の計算グラフ(つまり任意の関数合成)を考えられる
l  グラフは  DAG(有向⾮非巡回グラフ)になる
l  例例:Recurrent  Net,  Neural  Turing  Machine,  etc.
l  最近は単純な  feed-‐‑‒forward  でないニューラルネットが増えている
8
誤差逆伝播
l  良良い認識識・予測のためにパラメータを最適化する
l  最適化に勾配法を⽤用いるため、合成関数の微分が必要
l  合成関数の微分を後ろから前の⽅方向に動的計画法で計算するのが誤差逆伝播法
(backpropagation)
l  まず予測に対する誤差を計算する
l  誤差を逆向きに伝播する(重みのかけ⽅方は同じだが、バイアスは⼊入れない)
l  ⾮非線形関数を適⽤用するかわりに、⼊入⼒力力値におけるその微分を掛け算する
(そのために順伝播のときのユニットの値を覚えておく必要がある)
9
誤差逆伝播(分岐点)
l  グラフが分岐しているポイントでは、逆伝播してきた値を⾜足し合わせる
l  これは  (f  +  g)ʼ’  =  fʼ’  +  gʼ’  という計算をしているのと同様
10
ミニバッチ
l  現在、ニューラルネットの実装は基本すべてベクトル演算によって書かれてい
る
l  ベクトル演算の性能を上げるために、複数のデータをまとめて処理理することが
よく⾏行行われる(ミニバッチ)
–  データセット全体(バッチ)ではなく、⼀一部だけを取り出すのでミニバッチ
l  よって、グラフのノードはベクトルというより⾏行行列列として表されるのが普通
l  さらに画像の場合、チャンネル・⾼高さ・幅の  3  つの次元があるため、ミニバッ
チと合わせて  4  次元の配列列として表される
–  ただの系列列なら  3  次元配列列、動画なら  5  次元配列列
l  ミニバッチは実装の⼤大きな制約になる(たとえばデータが可変⻑⾧長の場合
など)ので、データごとに異異なる計算をしたい場合にこれをどう扱うか
(あるいは使わないで⾼高速化するか)は現状の課題
11
全結合層
l  冒頭で紹介したような、隣隣り合うユニット列列が全:全で結合している層を全結
合層  (fully-‐‑‒connected  layer)  と呼ぶ
l  全結合層は⾏行行列列積とベクトル和でかける
l  逆伝播も⾏行行列列積でかける
12
x y
bW (バイアス)
y = Wx + b
x = W y
W = y x
b = y
畳込み層
l  画像、動画、系列列データなどで⽤用いられる「スパース」「パラメータ共有」と
いう特徴を持った全結合層の制限版
l  実装⽅方法は⼤大きく3通り
–  愚直に実装する  (cuda-‐‑‒convnet)
–  ⾏行行列列積の形に直して⾏行行列列積を計算
(Caffe,  Chainer,  cuDNN)
u  cuDNN  はゼロコピーでそのまま
GEMM  を実装している
(implicit  GEMM)
–  FFT  により周波数ドメインに送り、
掛け算してから、逆  FFT  で戻す
(fbcunn)
13
http://deeplearning.net/tutorial/lenet.html
Chainer
l  Deep  Learning  のフレームワーク
l  Preferred  Networks  /  Preferred  Infrastructure
が中⼼心となって開発中
l  URL:
–  http://chainer.org/
–  https://github.com/pfnet/chainer
–  http://docs.chainer.org/
l  現在  v1.1.1
–  2  週に  1  回のリリースサイクル
14
Chainer  v1.1.1  の実装
l  前提:Python  で実装されている
l  主に以下のコンポーネントからなる
–  Variable(ユニットをまとめたベクトルに相当)
–  Function(適⽤用する関数に相当)
–  Optimizer(勾配法の実装)
l  Variable  は  NumPy  または  PyCUDA  の配列列を  2  つ持っている
–  順伝播⽤用と逆伝播⽤用
–  ともに必要になったタイミングで作られる
–  PyCUDA  実装の⽅方はメモリプールを使っている
l  順伝播と誤差逆伝播は  Variable  と  Function  によって実装されている
15
Chainer  での順伝播・逆伝播
l  Function  は  Variables  -‐‑‒>  Variables  のような関数を実装している
l  順伝播時に、関数の計算とあわせて  DAG  を作る
x = chainer.Variable(...)
y = chainer.Variable(...)
z = x**2 + 2*x*y + y
16
x
y
_ ** 2
2 * _ _ * _ _ + _ z
_ + _
Actually, Split nodes are automatically
inserted (they accumulate the gradients
on backprop)
Backward  Unchaining
l  Chainer  では、順伝播のときにできたグラフをあとで編集できる
l  逆伝播を途中までだけ実⾏行行したい場合に有効
(Fine-‐‑‒tuning  や  Truncated  Backprop-‐‑‒Through-‐‑‒Time  など)
17
x f y g z
y g z
y.unchain_backward()
Function  の実装
l  4  つのメソッドを実装
–  forward_cpu / forward_gpu
–  backward_cpu / backward_gpu
l  CPU/GPU  で全く同じコードが使える場合は forward / backward にまとめ
られる
l  型チェックを⾏行行う  check_type_forward の実装も推奨されている
–  ⼊入⼒力力される配列列の要素型と次元をチェックする
18
配列列の実装
l  v1.1.1  現在は  NumPy  と  PyCUDA/scikit-‐‑‒cuda  を使っている
l  CPU  実装は  NumPy
–  ⾃自由度度の⾼高い多次元配列列の実装
–  必要なベクトル演算がだいたい実装されている
l  GPU  実装は  PyCUDA
–  CUDA  Driver  API  のラッパー+簡単な配列列実装
–  ElementwiseKernel  や  ReductionKernel  など、ユーザがカーネルを実装
するための機能が充実している(その場でコンパイルが⾛走る)
–  ⼀一⽅方で配列列演算の機能は⾮非常に弱いので、現状  Chainer  ではほとんどの  
Function  でカーネルを書いている
19
配列列の実装  (2)
l  v1.3.0  (Sep.  2)  に  CuPy  に以降降する予定
l  CuPy:  Chainer  チーム内で作っている  GPU  多次元配列列実装
–  NumPy  互換のインターフェイス(サブセット)
–  必要そうなベクトル演算を⼤大体サポート
–  Chainer  の  CuPy  への移植はほぼ完了了
l  cupy  ブランチから使えるので、興味のある⽅方はお試しください
20
実装上の課題
l  データごとに異異なるネットワークを使いたい場合にミニバッチをどうするか
–  たとえば、データごとに⼊入⼒力力  Variable  の個数が違う場合(例例:⾃自然⾔言語な
どの可変⻑⾧長⼊入⼒力力)
–  ミニバッチを使わなければ⾃自然に記述できるが、GPGPU  によるベクトル演
算だと並列列度度や帯域を使いきらず⾮非常に遅くなる
–  ⼀一⽅方、ベクトル演算の形に書き直すと⾮非常に煩雑なプログラムになる
l  スケーラビリティ
–  GPU  による実装は、マシン内マルチ  GPU  での⾼高速化は可能
–  ⼀一⽅方マルチノードでの分散演算をはじめると通信ネックになり逆に遅くなる
–  Chainer  では現状、マシン内マルチ  GPU  のみに絞って実装している(しば
らくはその規模で実⽤用に⾜足りるだろうと考えている)
21
FPGA  実装
22
l  NeuFlow
–  Yann  LeCun  ら
–  Torch7  と組み合わせて使う  FPGA  実装の  ConvNet
–  https://github.com/clementfarabet/neuflow
–  現在は  TeraDeep  が合流流して後継実装を作っている
l  “Navigating  the  Design  Space  of  Reconfigurable  Neural  Networks  
Accelerators”
–  スイス連邦⼯工科⼤大学ローザンヌ校(EPFL)
–  FPGA  による実装、CPU/GPU/ASIC  との⽐比較
–  FPGA  は  GPU  並に柔軟で、ASIC  並みの低消費電⼒力力が達成できるという結
論論
まとめ
l  ニューラルネットは微分できる関数がたくさん合成されたもの
l  微分は誤差逆伝播法によって計算する
l  ベクトル演算ベースで実装する場合、ミニバッチによって⾼高速化する
l  全結合層、畳込み層は⾏行行列列演算でかける(畳込み層にはほかの実装⽅方法もあ
る)
l  Chainer  では順伝播のときに逆伝播⽤用のグラフを⼀一緒に構築する
l  Chainer  では  NumPy  と  PyCUDA  を配列列の実装として使っているが、後者は  
v1.3.0  で  CuPy  に置き換えられる予定
l  簡単には解決できない課題として、可変⻑⾧長⼊入⼒力力に対するミニバッチ(あるいは
ミニバッチを使わない⾼高速化)とスケーラビリティがある
l  FPGA  実装の試みはいくつかあり、柔軟性と消費電⼒力力の両⽴立立の点で注⽬目されて
いる。個⼈人的には柔軟性と使い勝⼿手がどこまであげられるかがきになる
23

深層学習フレームワークChainerの紹介とFPGAへの期待

  • 1.
    深層学習フレームワーク Chainer  の紹介と FPGA  への期待 FPGA エクストリーム・コンピューティング  第7回 2015/08/02  @  ドワンゴ  セミナールーム 得居  誠也  /  Preferred  Networks,  Inc.
  • 2.
    ⾃自⼰己紹介 l  得居  誠也 (Seiya  Tokui)    @beam2d  (Twitter,  GitHub) l  PFI  (2012-‐‑‒2014)  -‐‑‒>  PFN  (2014-‐‑‒) l  専⾨門:機械学習 –  ⾃自然⾔言語処理理、近傍探索索のためのハッシング(修⼠士) –  Deep  Learning(2012年年秋ごろ〜~)、画像・映像認識識 l  4  ⽉月に  Chainer  を作り始めて今はこれがメイン 2
  • 3.
    今⽇日のおはなし l  Deep  Learning の実装を紹介します –  Deep  Learning  でどんなことができるかみたいな話はしません(ウェブ上 のスライドや記事、書籍などを参照していただければと思います) –  まずニューラルネットの(実装に向けた)定式化についてお話したあと、 Chainer  の実装を紹介します l  FPGA  の話はしません –  私は  FPGA  について完全に素⼈人なので…… –  皆様が  FPGA  上にどう実装するか想像しながら聞いていただくスタイルで お願いします 3
  • 4.
    おはなしの流流れ l  ニューラルネットの実装のための定式化 –  Feed-‐‑‒forward Net –  ⼀一般の  DAG –  誤差逆伝播法 –  全結合層、畳込み層 l  Chainer  の実装 4
  • 5.
    Feed-‐‑‒forward  Net l  ◯ (ユニット)から右に向かって値が流流れる l  →  (エッジ、コネクション)に紐紐付いた重みパラメータがかけられる l  ◯  に⼊入るときにそれらが⾜足しあわされる(バイアスと呼ばれるパラメータも⾜足 される) l  ◯  の中で⾮非線形な関数が適⽤用され、右から出ていく 5
  • 6.
    Feed-‐‑‒forward  Net l  ユニット単位の描像よりも、各段階でのユニットの集まりをまとめてベクトル として捉えるのが⼀一般的 l ⾮非線形変換もベクトルに対して⾏行行う(elementwise  である必要はない) l  つまり  Feed-‐‑‒forward  Net  はベクトルに対して次々に関数を適⽤用する合成関数 6
  • 7.
    Feed-‐‑‒forward  Net l  さらにまとめるとこう l 使われる値は、ユニットの値とパラメータの⼆二種類 –  各ユニット(ベクトル)の値はデータごとに変わる –  パラメータ(重み、バイアス)はニューラルネットがなにをどう認識識・予測 するかを決めるもので、学習によって決める(基本的に、⼀一度度決まったら データごとには変更更しない) 7
  • 8.
    ⼀一般の  Neural  Net l 任意の計算グラフ(つまり任意の関数合成)を考えられる l  グラフは  DAG(有向⾮非巡回グラフ)になる l  例例:Recurrent  Net,  Neural  Turing  Machine,  etc. l  最近は単純な  feed-‐‑‒forward  でないニューラルネットが増えている 8
  • 9.
    誤差逆伝播 l  良良い認識識・予測のためにパラメータを最適化する l  最適化に勾配法を⽤用いるため、合成関数の微分が必要 l 合成関数の微分を後ろから前の⽅方向に動的計画法で計算するのが誤差逆伝播法 (backpropagation) l  まず予測に対する誤差を計算する l  誤差を逆向きに伝播する(重みのかけ⽅方は同じだが、バイアスは⼊入れない) l  ⾮非線形関数を適⽤用するかわりに、⼊入⼒力力値におけるその微分を掛け算する (そのために順伝播のときのユニットの値を覚えておく必要がある) 9
  • 10.
  • 11.
    ミニバッチ l  現在、ニューラルネットの実装は基本すべてベクトル演算によって書かれてい る l  ベクトル演算の性能を上げるために、複数のデータをまとめて処理理することが よく⾏行行われる(ミニバッチ) – データセット全体(バッチ)ではなく、⼀一部だけを取り出すのでミニバッチ l  よって、グラフのノードはベクトルというより⾏行行列列として表されるのが普通 l  さらに画像の場合、チャンネル・⾼高さ・幅の  3  つの次元があるため、ミニバッ チと合わせて  4  次元の配列列として表される –  ただの系列列なら  3  次元配列列、動画なら  5  次元配列列 l  ミニバッチは実装の⼤大きな制約になる(たとえばデータが可変⻑⾧長の場合 など)ので、データごとに異異なる計算をしたい場合にこれをどう扱うか (あるいは使わないで⾼高速化するか)は現状の課題 11
  • 12.
    全結合層 l  冒頭で紹介したような、隣隣り合うユニット列列が全:全で結合している層を全結 合層  (fully-‐‑‒connected layer)  と呼ぶ l  全結合層は⾏行行列列積とベクトル和でかける l  逆伝播も⾏行行列列積でかける 12 x y bW (バイアス) y = Wx + b x = W y W = y x b = y
  • 13.
    畳込み層 l  画像、動画、系列列データなどで⽤用いられる「スパース」「パラメータ共有」と いう特徴を持った全結合層の制限版 l  実装⽅方法は⼤大きく3通り – 愚直に実装する  (cuda-‐‑‒convnet) –  ⾏行行列列積の形に直して⾏行行列列積を計算 (Caffe,  Chainer,  cuDNN) u  cuDNN  はゼロコピーでそのまま GEMM  を実装している (implicit  GEMM) –  FFT  により周波数ドメインに送り、 掛け算してから、逆  FFT  で戻す (fbcunn) 13 http://deeplearning.net/tutorial/lenet.html
  • 14.
    Chainer l  Deep  Learning のフレームワーク l  Preferred  Networks  /  Preferred  Infrastructure が中⼼心となって開発中 l  URL: –  http://chainer.org/ –  https://github.com/pfnet/chainer –  http://docs.chainer.org/ l  現在  v1.1.1 –  2  週に  1  回のリリースサイクル 14
  • 15.
    Chainer  v1.1.1  の実装 l 前提:Python  で実装されている l  主に以下のコンポーネントからなる –  Variable(ユニットをまとめたベクトルに相当) –  Function(適⽤用する関数に相当) –  Optimizer(勾配法の実装) l  Variable  は  NumPy  または  PyCUDA  の配列列を  2  つ持っている –  順伝播⽤用と逆伝播⽤用 –  ともに必要になったタイミングで作られる –  PyCUDA  実装の⽅方はメモリプールを使っている l  順伝播と誤差逆伝播は  Variable  と  Function  によって実装されている 15
  • 16.
    Chainer  での順伝播・逆伝播 l  Function は  Variables  -‐‑‒>  Variables  のような関数を実装している l  順伝播時に、関数の計算とあわせて  DAG  を作る x = chainer.Variable(...) y = chainer.Variable(...) z = x**2 + 2*x*y + y 16 x y _ ** 2 2 * _ _ * _ _ + _ z _ + _ Actually, Split nodes are automatically inserted (they accumulate the gradients on backprop)
  • 17.
    Backward  Unchaining l  Chainer では、順伝播のときにできたグラフをあとで編集できる l  逆伝播を途中までだけ実⾏行行したい場合に有効 (Fine-‐‑‒tuning  や  Truncated  Backprop-‐‑‒Through-‐‑‒Time  など) 17 x f y g z y g z y.unchain_backward()
  • 18.
    Function  の実装 l  4 つのメソッドを実装 –  forward_cpu / forward_gpu –  backward_cpu / backward_gpu l  CPU/GPU  で全く同じコードが使える場合は forward / backward にまとめ られる l  型チェックを⾏行行う  check_type_forward の実装も推奨されている –  ⼊入⼒力力される配列列の要素型と次元をチェックする 18
  • 19.
    配列列の実装 l  v1.1.1  現在は NumPy  と  PyCUDA/scikit-‐‑‒cuda  を使っている l  CPU  実装は  NumPy –  ⾃自由度度の⾼高い多次元配列列の実装 –  必要なベクトル演算がだいたい実装されている l  GPU  実装は  PyCUDA –  CUDA  Driver  API  のラッパー+簡単な配列列実装 –  ElementwiseKernel  や  ReductionKernel  など、ユーザがカーネルを実装 するための機能が充実している(その場でコンパイルが⾛走る) –  ⼀一⽅方で配列列演算の機能は⾮非常に弱いので、現状  Chainer  ではほとんどの   Function  でカーネルを書いている 19
  • 20.
    配列列の実装  (2) l  v1.3.0 (Sep.  2)  に  CuPy  に以降降する予定 l  CuPy:  Chainer  チーム内で作っている  GPU  多次元配列列実装 –  NumPy  互換のインターフェイス(サブセット) –  必要そうなベクトル演算を⼤大体サポート –  Chainer  の  CuPy  への移植はほぼ完了了 l  cupy  ブランチから使えるので、興味のある⽅方はお試しください 20
  • 21.
    実装上の課題 l  データごとに異異なるネットワークを使いたい場合にミニバッチをどうするか –  たとえば、データごとに⼊入⼒力力 Variable  の個数が違う場合(例例:⾃自然⾔言語な どの可変⻑⾧長⼊入⼒力力) –  ミニバッチを使わなければ⾃自然に記述できるが、GPGPU  によるベクトル演 算だと並列列度度や帯域を使いきらず⾮非常に遅くなる –  ⼀一⽅方、ベクトル演算の形に書き直すと⾮非常に煩雑なプログラムになる l  スケーラビリティ –  GPU  による実装は、マシン内マルチ  GPU  での⾼高速化は可能 –  ⼀一⽅方マルチノードでの分散演算をはじめると通信ネックになり逆に遅くなる –  Chainer  では現状、マシン内マルチ  GPU  のみに絞って実装している(しば らくはその規模で実⽤用に⾜足りるだろうと考えている) 21
  • 22.
    FPGA  実装 22 l  NeuFlow – Yann  LeCun  ら –  Torch7  と組み合わせて使う  FPGA  実装の  ConvNet –  https://github.com/clementfarabet/neuflow –  現在は  TeraDeep  が合流流して後継実装を作っている l  “Navigating  the  Design  Space  of  Reconfigurable  Neural  Networks   Accelerators” –  スイス連邦⼯工科⼤大学ローザンヌ校(EPFL) –  FPGA  による実装、CPU/GPU/ASIC  との⽐比較 –  FPGA  は  GPU  並に柔軟で、ASIC  並みの低消費電⼒力力が達成できるという結 論論
  • 23.
    まとめ l  ニューラルネットは微分できる関数がたくさん合成されたもの l  微分は誤差逆伝播法によって計算する l ベクトル演算ベースで実装する場合、ミニバッチによって⾼高速化する l  全結合層、畳込み層は⾏行行列列演算でかける(畳込み層にはほかの実装⽅方法もあ る) l  Chainer  では順伝播のときに逆伝播⽤用のグラフを⼀一緒に構築する l  Chainer  では  NumPy  と  PyCUDA  を配列列の実装として使っているが、後者は   v1.3.0  で  CuPy  に置き換えられる予定 l  簡単には解決できない課題として、可変⻑⾧長⼊入⼒力力に対するミニバッチ(あるいは ミニバッチを使わない⾼高速化)とスケーラビリティがある l  FPGA  実装の試みはいくつかあり、柔軟性と消費電⼒力力の両⽴立立の点で注⽬目されて いる。個⼈人的には柔軟性と使い勝⼿手がどこまであげられるかがきになる 23