Contenu connexe Similaire à Chainerの使い方と自然言語処理への応用 (20) Chainerの使い方と自然言語処理への応用2. ⾃自⼰己紹介
海野 裕也
l -2008 東⼤大情報理理⼯工修⼠士
l ⾃自然⾔言語処理理
l 2008-2011 ⽇日本アイ・ビー・エム(株)東京基礎研
l テキストマイニング、⾃自然⾔言語処理理の研究開発
l 2011- (株)プリファードインフラストラクチャー
l ⾃自然⾔言語処理理、情報検索索、機械学習、テキストマイニングなど
の研究開発
l 研究開発系案件、コンサルティング
l JubatusやChainerの開発
NLP若若⼿手の会共同委員⻑⾧長(2014-)
「オンライン機械学習」(2015, 講談社)
2
4. 今⽇日のおはなし
l Chainer の使い⽅方を紹介します
l Deep Learning のおさらいも簡単にしますが、学術
的な詳細は既存の⽂文献を参考にしてください
l CUDA サポートについても解説しますが、CUDA の
詳細は NVIDIA のドキュメントを参照してください
l ⾃自然⾔言語処理理への応⽤用⽅方法を紹介します
l Recurrent Net などのよく知られた結果を Chainer
で実装する⽅方法を紹介します
4
8. ⼀一般のニューラルネットは DAG = 計算グラフ
⼀一般にはグラフが分岐したり合流流したりする
l 分岐:同じ変数を複数の場所でつかう
l 合流流:⼆二つ以上の変数を受け取る関数を適⽤用する
8
9. 計算グラフの例例
z = x ** 2 + 2 * x * y + y
9
x
y
_ **
2
2 * _ _ * _ _ + _ z
_ + _
20. Chainer はニューラルネットのフレームワーク
l 機能
l ニューラルネットを記述する
l ニューラルネットの順伝播・逆伝播を実⾏行行する
l 勾配法を実⾏行行してパラメータを最適化する
l Chainer の特徴
l 順伝播は単純に Python のスクリプトとして書ける
l そのスクリプトの実⾏行行結果は計算⼿手順を記憶してい
て、逆伝播を⼿手で書く必要はない
20
21. Chainer のインストール
l 環境は Linux(特に Ubuntu)がおすすめ
l インストール⽅方法
l 新しめの Python 環境を⽤用意(CPython 2.7+, 3.4+, 3.5+)
l pip も⽤用意
l コマンドを実⾏行行: pip install chainer
l chainer パッケージが import できれば完了了です
l Python スタックの環境構築は、Anaconda がお
すすめ
l Python のバージョン管理理は pyenv がおすすめ
l pyenv からコマンド⼀一つで Anaconda もインストールできます
21
24. Variable オブジェクト
l 計算グラフの(データ)ノード
l NumPy または CuPy(後述)の配列列を保持する
l 初期化時に配列列を渡す
l data 属性に保存される
l 多くの Function は配列列の最初の軸をミニバッチとして
使うので注意
l 下の x は、20 次元ベクトルが 10 個⼊入ったミニバッチとみなす
l 現状、Chainer は多くの場所で float32 配列列を要求する
ので注意
24
x = Variable(np.zeros((10, 20),
dtype=np.float32))
x.data
25. Function オブジェクト
l 計算グラフの「演算」ノード
l chainer.functions (以降降 F) にいろいろ定義され
ている
l F.relu, F.max_pooling_2d, F.lstm, ...
l Functionの呼び出し結果が、再びVariableになる
l v1.5からパラメータはLinkとして分離離された(後述)
25
x = Variable(...)
y = F.relu(x) # yもVariable
26. Link オブジェクト
l パラメータ付きの関数
l 最適化の対象となる
l save/loadができる(v1.5からsave/loadをサポート)
l chainer.links(以降降L)に⾊色々⽤用意されている
l L.Linear, L.Convolution2D, L.EmbedID, ...
l Linkの呼び出し結果が、再びVariableになる
l v1.5からFunctionとパラメータは分離離され、パラメータ
付きの関数はLinkオブジェクトになった
26
v1.5~
29. Optimizer の設定
l 勾配が計算できたら、あとは勾配法をまわす
l 勾配法のアルゴリズムは Optimizer クラスの⼦子クラス
l chainer.optimizers に定義されている
l 実装されている最適化⼿手法:SGD, MomentumSGD, AdaGrad,
RMSprop, RMSpropGraves, AdaDelta, Adam
l 最適化対象をsetup メソッドに渡す
l 正則化はhook関数として登録する
optimizer = optimizers.SGD()
optimizer.setup(model)
optimizer.add_hook(optimizer.WeightDecay())
29
31. Chainer を使う場合の全体の流流れ
1. Linkを使ってChainを定義する
2. Optimizer に、Chain を設定する
3. forward 関数を定義する
4. データセットを読み込み、訓練⽤用と評価⽤用にわける
5. 訓練ループを回す
a. 勾配をゼロ初期化
b. 順伝搬して、得られたロス値の backward メソッドを呼ぶ
c. Optimizerを、update
6. 適当な頻度度で評価ループを回す
a. テストデータで順伝搬関数を呼んで結果を記録
31
32. 新しい Function を⾃自分で定義する
l Function は Python で新しく作ることができる
l forward(_cpu/_gpu) と backward(_cpu/_gpu) を実装
する必要がある
l 配列列のタプルを受け取って、配列列のタプルを返す
l Linkは内部でFunctionを呼んで作る
32
34. 新しい Function を⾃自分で定義する
l Function を書いたらテストしましょう
l とくに勾配チェック (gradient check) は必須
l 有限差分法で forward のみから計算した勾配が、backward で
計算した勾配と⼀一致するかを確かめる
l chainer.gradient_check.numerical_grad を使うと簡単
に書ける
l 公式リポジトリの tests/chainer_tests/
function_tests にたくさん例例が書いてあります
34
35. CUDA サポート
l CuPy: 新しい CUDA 配列列実装
l NumPy と同じようなインターフェイスで使える
l 関数・メソッドのサブセットを実装
l 配列列のスライス、転置、reshape 等も⾃自由にできます
l カスタムカーネルも記述できる(elementwise,
reduction)
35
36. CuPy を使う準備
l まず CUDA が使える GPU を⽤用意する
l CUDA 6.5 以上をインストール
l Ubuntu なら公式に deb パッケージがお薦め
l パスを通す
l PATH と LD_LIBRARY_PATH を通す必要があります
l 公式インストーラからはデフォルトで /usr/local/cuda にインストー
ルされるので、以下のように設定
l PATH=/usr/local/cuda/bin:$PATH
l LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
l Chainer をインストールしたら cupy モジュールを
import してみて動くか確認
36
37. CuPy の使い⽅方
l 基本的に numpy の代わりに cupy を使う以外は
NumPy と⼀一緒
l CPU/GPU の両⽅方で動く関数の書き⽅方
l chainer.cuda.get_array_module() を使うと、引数に
cupy.ndarray があるかないかで numpy / cupy のどちらかを返してく
れます
l 例例えば下は NumPy と CuPy の両⽅方で動く logsumexp の実装例例(よ
り省省メモリな実装を考えてみてください)
def logsumexp(x, axis=None):
xp = cuda.get_array_module(x)
x_max = x.max(axis=axis)
return x_max + xp.log(xp.exp(x –
x_max).sum(axis=axis))
37
41. LSTM-RNN⾔言語モデル
class RNNLM(chainer.Chain):
def __init__(self, n_vocab, n_units, train=True):
super(RNNLM, self).__init__(
embed=L.EmbedID(n_vocab, n_units),
l1=L.LSTM(n_units, n_units),
l2=L.LSTM(n_units, n_units),
l3=L.Linear(n_units, n_vocab))
self.train = train
41
埋め込みベクトル
2段のLSTM
出⼒力力
43. LSTM-RNN⾔言語モデルを学習する
for i in range(jump * n_epoch):
x = chainer.Variable(...)
t = chainer.Variable(...)
loss_i = model(x, t)
accum_loss += loss_i
...
model.zerograds()
accum_loss.backward()
accum_loss.unchain_backward() # truncate
accum_loss = 0
optimizer.update()
43
truncated BPTT
45. word2vec
class ContinuousBoW(chainer.Chain):
def __init__(self, n_vocab, n_units, loss_func):
super(ContinuousBoW, self).__init__(
embed=F.EmbedID(n_vocab, args.unit),
loss_func=loss_func)
def __call__(self, x, context):
h = None
for c in context:
e = self.embed(c)
h = h + e if h is not None else e
return self.loss_func(h, x)
45
コンテキストの平均を取って出
⼒力力に投げるだけ
埋め込みベクトル
46. Recursive Neural Network
l 事前に与えられた構造(普通は構⽂文⽊木)に沿って、再帰
的にベクトルを結合する
l Recurrent Netは直鎖に対するRecursive Netともとれる
46
x1 x2
p1
x3
p2
p1 = f(x1, x2)
p2 = f(p1, x3)
47. Recursive Neural Network
class RecursiveNet(chainer.Chain):
def __init__(self, n_vocab, n_units):
super(RecursiveNet, self).__init__(
embed=L.EmbedID(n_vocab, n_units),
l=L.Linear(n_units * 2, n_units),
w=L.Linear(n_units, n_label))
def leaf(self, x):
return self.embed(x)
def node(self, left, right):
return F.tanh(self.l(F.concat((left, right))))
47
leafで埋め込み
nodeで合成
48. Recursive Netで構⽂文⽊木をたどる
def traverse(model, node):
if isinstance(node['node'], int): # leaf node
word = xp.array([node['node']], np.int32)
loss = 0
x = chainer.Variable(word)
v = model.leaf(x)
else: # internal node
left_node, right_node = node['node']
left_loss, left = traverse(model, left_node)
right_loss, right = traverse(model, right_node)
v = model.node(left, right)
loss = left_loss + right_loss
48
49. 公式の Examples
公式リポジトリの examples ディレクトリにいくつか例例が
あります
l mnist: MNIST を多層パーセプトロンで学習するもっと
も基本のサンプル
l imagenet: ImageNet からの⼤大規模ConvNet学習
l modelzoo: Caffe 公式モデルを読み込んでつかう
l ptb: Penn-Tree Bank から LSTM ⾔言語モデルを学習する
l 無限⻑⾧長の⼊入⼒力力に対する Truncated BPTT の例例にもなっています
l word2vec: word2vec の実装と PTB からの学習
l sentiment: Recursive Net を使った極性判定
49