NLP プログラミング勉強会 7 – ニューラルネット

自然言語処理プログラミング勉強会 7ニューラルネット

Graham Neubig
奈良先端科学技術大学院大学 (NAIST)1NLP プログラミング勉強会 7 – ニューラルネット

予測問題

x が与えられた時y を予測する
2

NLP プログラミング勉強会 7 – ニューラルネット

今回の例
●
●

Wikipedia 記事の最初の１文が与えられた時その記事が人物についての記事かどうかを予測与えられた情報●

予測

Gonso was a Sanron sect priest (754-827)
in the late Nara and early Heian periods.

Yes!

Shichikuzan Chigogataki Fudomyoo is
a historical site located at Magura, Maizuru
City, Kyoto Prefecture.

No!

これはもちろん、２値予測

3

NLP プログラミング勉強会 7 – ニューラルネット

線形識別器
y = sign (w⋅ϕ(x))
I= sign ( ∑i=1 w i⋅ϕi ( x))
●

x: 入力

●

φ(x): 素性関数のベクトル {φ1(x), φ2(x), …, φI(x)}●w: 重みベクトル {w1, w2, …, wI}●

y: 予測値、「 yes 」なら +1 、「 no 」なら -1●sign(v) は「 v >= 0 」の場合 +1 、そうでない場合 -1

4

NLP プログラミング勉強会 7 – ニューラルネット

素性関数の例： 1-gram 素性●「事例において、ある単語が何回現れるか？」

x = A site , located in Maizuru , Kyoto
φunigram “A”(x) = 1

φunigram “site”(x) = 1

φunigram “,”(x) = 2

φunigram “located”(x) = 1 φunigram “in”(x) = 1
φunigram “Maizuru”(x) = 1 φunigram “Kyoto”(x) = 1
φunigram “the”(x) = 0 φunigram “temple”(x) = 0…
●

残りはすべて 0

便宜のため、素性 ID(φ1) の代わりに、素性の名前(φunigram “A”) を利用

5

NLP プログラミング勉強会 7 – ニューラルネット

重み付き和の計算
x = A site , located in Maizuru , Kyoto
φunigram “A”(x)φunigram “site”(x)φunigram “located”(x)

=1
=1
=1

φunigram “Maizuru”(x)φunigram “,”(x)φunigram “in”(x)φunigram “Kyoto”(x)φunigram “priest”(x)φunigram “black”(x)

=1=2
=1
=1
=0
=0wunigram “a”
wunigram “site”

*…

=0
= -3

wunigram “located” = 0
wunigram “Maizuru” = 0
wunigram “,”=0wunigram “in”
=0
wunigram “Kyoto” = 0
wunigram “priest” = 2
wunigram “black” = 0=0+-3+0 +0+0
0 ++0+0+0+…
=-3 → No!

6

NLP プログラミング勉強会 7 – ニューラルネット

パーセプトロン●

重み付き和を計算する「機械」として考える
φ“A”=1
φ“site” = 1
φ“located” = 1
φ“Maizuru”= 1
φ“,”
=2
φ“in”
=1
φ“Kyoto” = 1
φ“priest” = 0
φ“black” = 00-30000020Isign( ∑ i=1 w i⋅ϕi ( x))-1

7

NLP プログラミング勉強会 7 – ニューラルネット

numpy でパーセプトロン

8

NLP プログラミング勉強会 7 – ニューラルネット

numpy とは●●●Python で利用できる、強力な計算ライブラリ
ベクトルや行列の掛け算などが簡単

SciPy というパッケージの一部（ SciPy は機械学習アルゴリズムなども実装）

9NLP プログラミング勉強会 7 – ニューラルネット

numpy の使用例 ( ベクトル編 )10

NLP プログラミング勉強会 7 – ニューラルネット

numpy の使用例 ( 行列編 )11

NLP プログラミング勉強会７ – ニューラルネット

パーセプトロンの予測
predict_one(w, phi)score = 0
for each name, value in phi
if name exists in w
score += value * w[name]return (1 if score >= 0 else -1)# score = w*φ(x)numpy
predict_one(w, phi)score = np.dot( w, phi )return (1 if score[0] >= 0 else -1)
12

NLP プログラミング勉強会７ – ニューラルネット

素性の ID 化●

numpy は密行列を利用→ 素性を整数 ID に変えたい！

ids = defaultdict(lambda: len(ids)) # ID に変換するトリック！
CREATE_FEATURES(x):create list phi
split x into words
for word in words
phi[ids[“UNI:”+word]] += 1
return phi

13

NLP プログラミング勉強会７ – ニューラルネット

素性の初期化●●素性の数だけのベクトルを初期化
ゼロで初期化w = np.zeros(len(ids))●[-0.5,0.5] でランダムに初期化

w = np.random.rand(len(ids)) – 0.5

14NLP プログラミング勉強会７ – ニューラルネット

パーセプトロン学習の疑似コード# 素性の数を数えて、重みを初期化する
create map ids
for each labeled pair x, y in the data
create_features(x)w = np.zeros(len(ids))# 学習を行う
for I iterations
for each labeled pair x, y in the dataphi = create_features(x)y' = predict_one(w, phi)
if y' != yupdate_weights(w, phi, y)
print w to weight_file
print ids to id_file

15

NLP プログラミング勉強会７ – ニューラルネット

パーセプトロン予測の疑似コード
read ids from id_file
read w from weights_file
for each example x in the dataphi = create_features(x)y' = predict_one(w, phi)

16

NLP プログラミング勉強会７ – ニューラルネット

ニューラルネット

17

NLP プログラミング勉強会 7 – ニューラルネット

問題：線形分類のみ●

線形分離不可能な問題に対して高い精度は実現不可

XOO

X

18

NLP プログラミング勉強会 7 – ニューラルネット

ニューラルネット●

複数のパーセプトロンをつなげる
φ“A”=1
φ“site” = 1
φ“located” = 1
φ“Maizuru”= 1
φ“,”
=2
φ“in”
=1
φ“Kyoto” = 1
φ“priest” = 0
φ“black” = 0●-1

モチベーション：線形でない関数も表現可能！

19

NLP プログラミング勉強会 7 – ニューラルネット●

2 つの分類器を作成

φ0(x1) = {-1, 1} φ0(x2) = {1, 1}

X

φ0[1]

O

例:
φ0[0]

X

φ0(x3) = {-1, -1} φ0(x4) = {1, -1}

1

φ0[1]

11-1

φ0[0]

Ow0,0

step

φ1[0]

step

φ1[1]

b0,0
w0,1

φ0[0] -1
φ0[1] -1
1-1
b0,120NLP プログラミング勉強会 7 – ニューラルネット

例:●

分類器は新しい素性空間へマッピング
φ1(x3) = {-1, 1}

φ0(x1) = {-1, 1} φ0(x2) = {1, 1}

X

φ2

O

O

φ1[1]

φ1

O

φ1[0]

X

X

φ0(x3) = {-1, -1} φ0(x4) = {1, -1}

φ1(x1) = {-1, -1}φ1(x4) = {-1, -1}

11-1

φ1[0]

-1-1-1

φ1[1]O
φ1(x2) = {1, -1}

21

NLP プログラミング勉強会 7 – ニューラルネット

例:●

新しい空間で、事例が分類可能に！

φ0(x1) = {-1, 1} φ0(x2) = {1, 1}
φ0[1]

X

O
φ0[0]

O

X

1
1
1

φ2[0] = yφ0(x3) = {-1, -1} φ0(x4) = {1, -1}1
1-1-1-1-1

φ1[0]
φ1[1]

φ1(x3) = {-1, 1} O
φ1(x1) = {-1, -1}
X
φ1(x4) = {-1, -1}

φ1[1]
φ1[0]
O φ1(x2) = {1, -1}22

NLP プログラミング勉強会 7 – ニューラルネット

例:●

最終的なニューラルネット
φ0[0]

1φ0[1]

11-1

φ0[0]

-1

φ0[1]-1

1-1tanh φ1[0]11tanhφ2[0]tanh φ [1]11 123

NLP プログラミング勉強会 7 – ニューラルネット

2 層ニューラルネットの例 ( ベクトル編）
入力

φ0 = np.array( [1, -1] )φ0[0] 1
φ0[1] 11tanh φ1[0]1-1

φ0[0] -1
φ [1] -1 tanh φ [1]
01 -1

1

1

1 1tanh

φ2[0]一層目の計算w0,0 = np.array( [1, 1] )b0,0 = np.array( [-1] )w0,1 = np.array( [-1, -1] )b0,1 = np.array( [-1] )φ1 = np.zeros( 2 )φ1[0] = np.tanh( φ0w0,0 + b0,0 )[0]φ1[1] = np.tanh( φ0w0,1 + b0,1 )[0]２層目の計算w1,0 = np.array( [1, 1] )b1,0 = np.array( [-1] )φ2 = np.zeros( 1 )24
φ2[0] = np.tanh( φ1w1,0 + b1,0 )[0]

NLP プログラミング勉強会７ – ニューラルネット

2 層ニューラルネットの例 ( 行列編）
入力

φ0 = np.array( [1, -1] )φ0[0] 1
φ0[1] 11w0 = np.array( [[1, 1], [-1,-1]] )b0 = np.array( [-1, -1] )φ1 = np.tanh( np.dot(w0, φ0) + b0 )tanh φ1[0]２層目の計算1-1

φ0[0] -1
φ0[1] -1 tanh φ1[1]1 -1

一層目の計算

1tanh

φ2[0]

w1 = np.array( [[1, 1]] )b1 = np.array( [-1] )φ2 = np.tanh( np.dot(w1, φ1) + b1 )1 125

NLP プログラミング勉強会 7 – ニューラルネット

ニューラルネットの伝搬コード
forward_nn(network, φ0)
φ= [ φ0 ] # 各層の値
for each layer i in 0 .. len(network)-1:w, b = network[i]# 前の層の値に基づいて値を計算
φ[i] = np.tanh( np.dot( w, φ[i-1] ) + b )return φ # 各層の結果を返す

26

NLP プログラミング勉強会 7 – ニューラルネット

tanh を用いたパーセプトロン学習●

エラー関数：二乗誤差
err = (y' – y)2 /2
正解●

システム出力エラーの勾配 :
err' = δ = y' - y●

各重みを更新 :w ← w + λ⋅δ⋅ϕ( x )●λ は学習率27

NLP プログラミング勉強会 7 – ニューラルネット

問題：正解は分からない！
●

NN では出力層のみで正解が与えられる
φ“A”=1
φ“site” = 1
φ“located” = 1
φ“Maizuru”= 1
φ“,”
=2
φ“in”
=1
φ“Kyoto” = 1
φ“priest” = 0
φ“black” = 00y' = ?
y=1y' = ?
1 y=1

2

3y' = 1y = -1y' = ?
y=128

NLP プログラミング勉強会 7 – ニューラルネット

解決策：逆伝搬法●

出力層からエラーを後ろへ伝搬
w=0.1

δ = -0.9w=1

δ = 0.2

w=-0.3

δ = 0.4

jtanh の勾配も考慮
y●∑i δ i w j ,i-4-3-2-1

0

1

2

34

2d tanh (ϕ (x)∗w)=1−tanh (ϕ (x )∗w) =1− y●

合わせて：

δ j=(1− y ) ∑i δi w j ,i2j2j29

NLP プログラミング勉強会 7 – ニューラルネット

逆伝搬の例（行列編）
出力層のエラーδ2 = np.array( [y'-y] )φ0[0] 1φ0[1] 1
1tanh φ1[0]1φ0[1] -1 tanh φ1[1]
1 -1

11 1

δ'2 = δ2 * (1-φ22)
δ1 = np.dot(δ'2, w1)
０層目の計算δ'1 = δ1 * (1-φ12)
δ0 = np.dot(δ'1, w0)-1

φ0[0] -1

１層目の計算tanhφ2[0]30NLP プログラミング勉強会 7 – ニューラルネット

逆伝搬のコード
backward_nn(net, φ, y')J = len(net)create array δ = [ 0, 0, …, np.array([y' – φ[J][0]]) ] # length J+1
create array δ' = [ 0, 0, …, 0 ]for i in J-1 .. 0:δ'[i+1] = δ[i+1] * (1 – φ[i+1]2)
w, b = net[i]δ[i] = np.dot(δ'[i+1], w)
return δ'

31

NLP プログラミング勉強会 7 – ニューラルネット

重み更新
●
●

最後に、重みを更新

重み w の勾配、次の δ' と、前の φ の外積で求める-derr/dwi = np.outer( δ'i+1, φi )●学習率をかけ、重みを更新
wi += λ * -derr/dwi●

バイアス項は単純に δ' と同等-derr/dbi = δ'i+1
bi += λ * -derr/dbi
32

NLP プログラミング勉強会７ – ニューラルネット

重み更新のコード
update_weights(net, φ, δ', λ)for i in 0 .. len(net)-1:w, b = net[i]w += λ * np.outer( δ'[i+1], φ[i] )b += λ * δ'[i+1]33

NLP プログラミング勉強会７ – ニューラルネット

学習の全体像# 素性を作り、ネットワークをランダムな値で初期化
create map ids, array feat_lab
for each labeled pair x, y in the data
add (create_features(x), y ) to feat_lab
initialize net randomly# 学習を行う
for I iterations
for each labeled pair φ0, y in the feat_lab
φ= forward_nn(net, φ0)
δ'= backward_nn(net, φ, y)update_weights(net, φ, δ', λ)print net to weight_file
print ids to id_file34

NLP プログラミング勉強会 7 – ニューラルネットニューラルネット学習のこつ35

NLP プログラミング勉強会 7 – ニューラルネット

学習の安定化●●

ニューラルネットはパラメータが多い→学習が不安定
重みの初期値：●●

ランダム、 -0.1~0.1 の間の一様分布など

学習率：0.1 から始めることが多い● エラーが前イタレーションに比較して増加した場合は学習率を下げる ( *= 0.9 や *= 0.5)●●

隠れ層の大きさ：●

だいたい色々試して一番精度の良いものを選択
36

NLP プログラミング勉強会 7 – ニューラルネットテスト●●

手軽：エラーの値をプリントし、イタレーションごとにだいたい減ることを確認
本気：有限差分法で勾配を確認

アイデア：

重み更新の際、重み wi の勾配を計算： derr/dwi
つまり、この重みを少しだけ（ ω だけ）揺らせば
wi = xwi = x + ωが成り立つはず！の場合 なら の場合
err = yerr = y + ω * derr/dwi有限差分法で、 wi を揺らしてみて、上記が（ 1e-6 など、一定の誤差内）成り立たなければ、勾配計算のバグがあると判断37
詳細： http://cs231n.github.io/neural-networks-3/

NLP プログラミング勉強会 7 – ニューラルネット

演習課題

38

NLP プログラミング勉強会 7 – ニューラルネット●

実装

演習課題 (1)train-nn: NN を学習するプログラム● test-nn: NN を用いて予測するプログラム
●

●

テスト

入力 : test/03-train-input.txt● 学習 1 回、隠れ層 1 つ , 隠れ層のノード 2 つ● 更新を手で確認●

39

NLP プログラミング勉強会 7 – ニューラルネット

演習課題 (2)●

学習 data/titles-en-train.labeled●

予測 data/titles-en-test.word

●

評価
●

●

script/grade-prediction.py data-en/titles-en-test.labeled your_answer

比較

単純なパーセプトロン、 SVM 、ロジスティック回帰● ノード数、初期学習率、ランダムな値の初期レンジ● チャレンジ●

複数の隠れ層を使ったネットの実装● エラー増加の場合、学習率を減らす手法を実装●40

NLP プログラミング勉強会 7 – ニューラルネット

Thank You!

41