鶴岡研における ニューラルネット+NLP

鶴岡研における
ニューラルネット+NLP
橋本和真 (東京大学 鶴岡研)
2016/04/13 @PFI
自己紹介
• 橋本 和真 (はしもと かずま)
• 東京大学 鶴岡研 博士課程2年
– 2012 4月 – 10月 (卒論生)
• 画像中の物体認識
– ちょうどこのころ、GPU + Deep Learningが猛
威を振るい始めていた危険な時期
– 2012 11月
• Richard Socherの講演を聞く (転機)
– 2012 12月 – 現在
• NLP + ニューラルネットワーク系の研究に転向
2016/04/13 @PFI
2 / 26
今日に繋がる経緯
• 研究はニューラルネットやEmbedding関連
– C++とEigenで実装
• SocherのMATLABコードのC++への移植から開始
• 2014年からRNN翻訳が出現
– 卒論生とRNN翻訳に取り組む (NLP2015@京都)
– アテンション翻訳の実装に取り組むも、断念
• 最近のNLPのニューラルネットは難しい・・・
• Chainerが話題になるも、特に触らず
– まだLSTMとか触る必要ないかな・・・
• 時代に取り残されつつある
2016/04/13 @PFI
3 / 26
今日に繋がる経緯
• 2015年12月某日, 突然LSTMの実装を始める
– https://github.com/hassyGo/N3LP
2016/04/13 @PFI
4 / 26
鶴岡研におけるニューラルネット事情
• 基礎編: LSTMの実装など
– 本発表
• 応用編: 構文情報+ニューラルネット翻訳の話
– 次の発表
• 将棋の解説文生成 (亀甲)
– 次回のTokyoCL勉強会@LINE (5月)
• 昨年度の卒論生
– CNNによる囲碁の着手予測
– ニューラルネット翻訳におけるPOSタグの利用
2016/04/13 @PFI
5 / 26
NLPにおけるニューラルネットワーク
• やりたいことを考える
– この問題にはこのモデルが適用できるかも
– この情報とこの情報を繋ぐとよいかも
– この構文情報を取り入れるとよいかも (など)
• モデルの絵と式を書く
– 絵をどのような式で実現するか
– 目的関数は何か
• バックプロパゲーションの導出と実装
– 手計算したとおりに実装する
• ブラックボックスにするにはまだ早い
2016/04/13 @PFI
6 / 26
自身の研究
• 構文構造を用いたニューラルネットによるNLP
– 主にEnjuを使用
• 句構造
• 述語項構造
– 構造を使わないモデルもたまにやる
• 最近だとLSTMなど
– 今日のメインの話
– 実装はC++
• 行列演算にはEigenを使用
2016/04/13 @PFI
7 / 26
流行のLSTMの実装
• 日本人なら今流行のChainerか?
– 研究室でも流行りかけた
– しかし, 自分で一から実装することに
• Pythonにしばられたくない
• しっかり中身を知りたい
• GPUは必要か?
– 大量のGPU無しで出来ないようなことはおそらくしない
• Googleならできるけど自分ではできないことがある
– きっとCPUでもまだまだいけるはず
2016/04/13 @PFI
8 / 26
LSTMのforwardの計算式
• https://github.com/hassyGo/N3LP/blob/master/LSTM.cpp
Tai et al., 2015, Improved Semantic
Representations From Tree-Structured Long
Short-Term Memory Networks, ACL.
2016/04/13 @PFI
9 / 26
LSTMのforwardの計算の実装
• あ
2016/04/13 @PFI
10 / 26
LSTMのbackwardの計算の実装
2016/04/13 @PFI
11 / 26
LSTM Encoder-Decoder翻訳モデルの実装
• https://github.com/hassyGo/N3LP/blob/master/EncDec.cpp
• Encoder用のLSTMとDecoder用のLSTMを繋げて機械翻訳
forループで
繰り返す
目的言語の単語列
原言語の単語列
Sutskever et al., 2014, Sequence to
Sequence Learning with Neural Networks,
NIPS.
2016/04/13 @PFI
12 / 26
Encoderの実装
• 原言語の単語列を入力していく
原言語の
word embedding
2016/04/13 @PFI
前状態
次状態
13 / 26
学習: EncoderからDecoderの単語予測
• Encoder目的言語の単語列 (正解) のロスを計算
– LSTMのバックプロパゲーションへの準備
Encoder
目的言語の
word embedding
f
前状態
次状態
Softmaxからのバックプロパゲーション
2016/04/13 @PFI
14 / 26
学習: LSTMのバックプロパゲーション
Decoderの学習
Encoderの学習
2016/04/13 @PFI
15 / 26
実装は正しいか?
• Gradient checking
– バックプロパゲーションが正しく実装されているか確認
• ε=10-4をよく使う
• floatだとぜんぜん値が合わない (doubleでやる)
2016/04/13 @PFI
16 / 26
Encoder-Decoder翻訳の実験規模
• 対訳コーパス:
– 100万文ペア~
• それなりのデータ数が無いと学習が難しい
• 総語彙数
– 数十万~
• 隠れ層の次元:
– ~1,000
• これが4層も積まれたりする
2016/04/13 @PFI
17 / 26
Encoder-Decoderモデルを学習すると・・
• Softmax (単語予測) が非常に重い
– 10万語彙10万クラス分類×出現単語数
• 世間での対応策
– Sampled Softmax (Tensor Flowに入っている)
– Noise Contrastive Estimation (NCE, 有名なやつ)
– Negative Sampling (言語モデルを放棄するので却下)
• BlackOut: 簡単・高速・高精度 (RNN言語モデル)
2016/04/13 @PFI
18 / 26
BlackOut: Softmax学習の近似手法
• 負例サンプリングベースのSoftmax近似手法
– NCEに似ている
• 正例 (正解単語) に対して, K個の負例をサンプリング
して学習
– 100万語彙でも動く
• 普通のニューラルネット翻訳では数万語彙
• 学習後は普通のSoftmaxとして使用可能
Ji et al., 2016, BlackOut: Speeding up
Recurrent Neural Network Language
Models With Very Large Vocabularies, ICLR.
2016/04/13 @PFI
19 / 26
実際にBlackOutで学習すると・・
• ニューラルネット翻訳 (次の発表で紹介するモデル)
– ASPEC対訳コーパス (英日)
• 学習データ:10万文ペア
• 隠れ層の次元:256
Eriguchi et al., 2016, Tree-to-Sequence
Attentional Neural Machine Translation, arXiv.
• 語彙数:2万程度
– この規模でこれくらいの差がつく
– 精度については論文を参照
BlackOut
Softmax
2016/04/13 @PFI
サンプル数 K 分/エポック
500
55
2,000
-
70
180
20 / 26
Softmaxを使用する際の注意点
• exp(x) の計算で値がとぶことがある
– Softmaxを使うタイミング
• 単語予測
• アテンション (次の発表)
irb(main):002:0> exp(1.0)
=> 2.71828182845905
irb(main):003:0> exp(700.0)
=> 1.014232054735e+304
irb(main):004:0> exp(710.0)
=> Infinity
2016/04/13 @PFI
>>> math.exp(1.0)
2.718281828459045
>>> math.exp(700.0)
1.0142320547350045e+304
>>> math.exp(710.0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: math range error
21 / 26
expの引数がそんなに大きくなるのか?
• 従来のtanh層ならこんなことを心配したことはなかった
• LSTMではメモリセルの足しこみで値が非常に大きくなる
– 単語予測時に出力層の値が非常に大きく成り得る
– アテンションスコアが非常に大きくなることがある
• 解決策:Stable Softmax
– Softmaxをとる際に各要素から最大値を引いておく
• expへの入力の最大値が常に0になる
– Softmaxでは相対値が大事
2016/04/13 @PFI
22 / 26
値爆発に対する他の対処法
• Forward/backward clipping
– LSTMの隠れ層の値, 勾配の値をある範囲にclip
• 音声系の論文でいくつか発見
• 最近のニューラルネット翻訳の論文で用いられてい
るのをあまり見ないが、コードを見ると使っている
ケースがある・・・
– どれくらい効果があるのか?
• 悪影響は無いのか?
“…, and the output and LSTM gradients were again clipped
in the range [−100, 100] and [−10, 10] respectively.”
Graves, 2013, Generating Sequences With
Recurrent Neural Networks, arXiv.
2016/04/13 @PFI
23 / 26
Column-Major と Row-Major
• EigenはデフォルトではColumn-Major
– 行列の行ベクトルにアクセスすると遅い
– なるべく列ベクトルにアクセスすべき
• 例: BlackOutではベクトルの内積計算を頻繁に行う
– 計算式通りにSoftmaxの行列を確保
• 行ベクトルにアクセスすることになって遅い
隠れ層のサイズ
語彙
サイズ
2016/04/13 @PFI
各単語の重みベクトル
(行ベクトル)
24 / 26
double  float, ミニバッチ並列化
• 今までは全てdoubleでやっていた
– どうも普通はfloatでやるらしい?
• gradient checkはずれるが・・・
• モデルのサイズが約半分に
• 最近のCPUにあるAVX命令
– floatの計算を8並列, doubleの計算を4並列
• doublefloatの変更でほぼ2倍速に
• ミニバッチ学習での各データの処理は独立
– 単純にOpenMPでスレッド並列化
• もっと速くできたら嬉しい
2016/04/13 @PFI
25 / 26
どういう方向に進むか?
• LSTMのニューラルネット翻訳では
– 1,000次元を4層, といった激しいものが多い
• 系列系列の無理やりなマッピングをやってるから
GPUが必要なほど大変になっているのではないか?
– (と勝手に思っています)
• さらに文字ベースのものも増えてきた
– 良さそうな面もあるが, より大変そう
• 言語処理で積み重ねてきた技術を利用してもっとコンパク
トに良い結果を達成できると嬉しい
2016/04/13 @PFI
26 / 26