自然言語処理勉強結果「ニューラルネットワーク」

自然言語処理学習結果

前回まで、自然言語処理における
単語の意味理解について解説していた。

今回もその手法の一つ…ではない。

というのも、それを解説するために、
また機械学習に戻らなければいけない。

今回は、機械学習における
ニューラルネットワークというものを解説しよう。

なお、本記事での目的としてはこれを使えることとする。

…実は、一部理解が追い付いていない部分がある。

なので、あくまで使えるように、ということだ。

今後もこのあたりを深掘りして勉強していくので、
分かったら追記、あるいは別記事で補足するとしよう。

なお、本講座は以下の本を参考に進めている。

もしよかったら、中身を覗いてみて欲しい。

https://amzn.to/3gMSl4P
スポンサーリンク

ニューラルネットワーク

ニューラルネットワークとは

ニューラルネットワークとは、
人の脳で行われている情報処理をモデル化したもの

教師あり学習の一つだ。

ちょっと、人の脳のお話をしよう。

人の脳は、1000億個くらいのニューロンという
ものが存在し、これが情報処理を行っている。

このニューロンは、他のニューロンから
信号を受け取り、その内容によって
他のニューロンにまた信号を送る

簡単に言ってしまうと、
これを機械で再現しよう、というのが
ニューラルネットワークである。

階層型ニューラルネットワーク

階層型ニューラルネットワークは単純なもので、
以下3層からなる。

  • 入力層
  • 中間層(隠れ層)
  • 出力層

それぞれの層で、ユニットと呼ばれるものが存在する。

このニューラルネットワークへ入力するものは、
ベクトルだ。

また、出力もベクトルとなる。

ただし、その次元数(ベクトルの要素数)は
異なっていても問題がない

入力層のユニット数を\(n\)、
中間層のユニット数を\(l\)、
出力層のユニット数を\(m\)とした場合の
概要図を以下に示そう。

階層型ニューラルネットワークの概要図

処理の流れとしては、
まずn個の要素を持つベクトルが入力される。

すると、中間層の\(u_i\)でその入力を受け取り、
バイアス項と呼ばれるパラメータを含めた計算式で、
ここでの出力\(o_i\)を決定する。

そして、出力層で\(u’_i\)としてここでの入力を受け取り、
再度計算して最終的な出力\(o’_i\)を決定する。

なお、図には入れてないが、
各ユニットを結ぶ辺にも重みが付けられている

実際の学習時には、
この辺の重みを調整していくことになる。

この中で使う、シグモイド関数と呼ばれる
関数を先にご紹介しよう。

シグモイド関数

これは、以下の式で示される関数だ。

$$f(x) = \frac{1}{1 + e^{-x}}$$

これは、入力を0より大きく、
1未満の範囲に写像してくれる関数だ。

どうやって使うかは、
実際の計算の中で提示しよう。

ニューラルネットワークの計算

まずは、単純にこの計算方法を見ていこう。

先に示した通り、
入力はベクトル\(x = (x_1, x_2, …, x_n)\)だ。

最初は、中間層への入力\(u_j\)を見てみよう。

ここに入力される値は、
以下の計算式で求められる。

$$u_j = \sum_{i = 1}^n w_{ji}x_i + b_j$$

ここで、\(w_{ji}\)が辺の重みだ。

入力層の\(x_i\)から、中間層の入力\(u_j\)に繋がっている
辺の重みを、\(w_{ji}\)で表している。

さらに、\(b_j\)というやつが、バイアス項だ。

次に、中間層の出力\(o_j\)を見る…が、
ここで出てくるのがシグモイド関数だ。

単純に、入力\(u_j\)をシグモイド関数へ入れた
結果を\(o_j\)とする。

$$o_j = f(u_j) = \frac{1}{1 + e^{-u_j}}$$

ここまで大丈夫だろうか。

大丈夫なら、出力層への入力\(u’_k\)を見ていこう。

とはいえ、ここでやっていることは
中間層へのものと全く同じだ。

入力がベクトル\(x\)からベクトル\(o\)に変わって、
また辺の重みも変わる。

中間層の\(j\)番目と出力層の\(k\)番目を
結ぶ重みを、\(w’_{kj}\)とする。

これで、出力層の\(k\)番目の入力\(u’_k\)、
出力\(o’_k\)
を求めると、

$$u’_k = \sum_{j=1}^l w’_{kj} o_j + b’_k$$

$$o’_k = f(u’_k) = \frac{1}{1 + e^{-u’_k}}$$

となる。

…さて、ちょっとこのままだと計算がしづらい。

というのも、二種類のパラメータ…
バイアス項辺の重みを学習しなければ
いけないからだ。

そこで、以下のように考える。

新たに0番目の入力\(x_0\)を追加し、
そこには常に1が入ってくるとする。

また、そこから\(j\)番目の中間層に向かう
辺の重みを\(w_{j0}\)
と置こう。

そして、この\(w_{j0}\)が\(b_j\)と等しいと置くと、
なんと式から\(b_j\)を消すことができる

どういうことかというと、式変形でお見せしよう。

$$
\begin{eqnarray}
u_j & = & \sum_{i = 1}^n w_{ji}x_i + b_j \\
& = &\sum_{i = 1}^n w_{ji}x_i +w_{j0}x_0 \\
& = &\sum_{i = 0}^n w_{ji}x_i
\end{eqnarray}
$$

こうなるわけだ。

中間層から出力層に向けても同じことができるので、
ここから先はバイアス項はなしで考えよう。

誤差逆伝搬学習

ここからが、学習の内容だ。

階層型ニューラルネットワークの学習は、
入力データを一つずつ入力層から入れて、
出力層のデータと正解データを比較し、
誤差を小さくなるように辺の重みを変化させる、
ということを繰り返す。

この辺の重みの調整は、
まず出力に直接影響を与える
中間層、出力層の間の辺の重みを調整し、
次に間接的に影響を与える
入力層と中間層の間の辺の重みを調整する。

この手法のことを、誤差逆伝搬法と呼ぶ。

…実はこのあたりがまだ理解不足だ。

調べたところ、
この誤差逆伝搬法あくまで一般的な手法の一つで、
それを今回学習に利用している、らしい。

詳細が知りたい方は、
調べれば出てくるのでそちらを参照してほしい。

ここでは、結果の数式だけお見せしよう。

前提として、
入力したベクトル\(x = (x_1, x_2, …, x_n)\)に対する
正解データが\(y = (y_1, y_2, …, y_m)\)とする。

このとき、\(j\)番目の中間層と\(k\)番目の出力層を繋ぐ
辺の重み\(w’_{kj}\)は、以下の式で更新される。

$$w’_{kj} – \eta \delta’_ko_j$$

ただし、\(\delta’_k\)は、

$$\delta’_k = (o’_k – y_k)(1 – o’_k)o’_k$$

で表される。

また、\(\eta\)は学習率と呼ばれる値で、
重みを1回にどの程度変化させるかの度合いを表す。

次に、\(i\)番目の入力層と\(j\)番目の中間層を繋ぐ
辺の重み\(w_{ji}\)は、以下の式で更新される。

$$w_{ji} – \eta \delta_j x_i$$

ただし、\(\delta_j\)は、

$$\delta_j = (\sum_{k=1}^mw’_{kj}\delta’_k)(1-o_j)o_j$$

で表される。

…ここで一度力尽きてしまったので、
詳細な解説は理解できてから行おう。

とりあえず、なんとなくの流れを
理解してもらえれば大丈夫だ。

おわりに

今回はニューラルネットワークについて説明した。

ちょっと理解が及ばず、
中途半端な形になってしまい、申し訳ない。

ただ、ここで詰まっていてもいけないので、
いったん先に進もう。

次回は、これを使った単語の意味理解を簡単に説明する。

…というのも、結局このあたりもツールで行えたり、
行った後のデータも公開されていたりするのだ。

本当は根本を理解した方がいいのだが、
使えるならいったんはそれで進めよう、という考え方だ。

今回の補足は…理解できたらするとしよう。

コメント

タイトルとURLをコピーしました