自然言語処理の歴史
本記事では自然言語処理の技術の歴史についてお話します!この記事では ChatGPT の出現手前までの自然言語処理の歴史をたどっていこうと思います!

芝 紘希
ソフトウェアエンジニア
2025-1-13
2025-1-13
芝 紘希
自然言語処理の歴史
#AI
目次
- 概要
- 「自然言語処理」とは?
- シソーラス
- シソーラスとは
- シソーラスの欠点
- 統計的手法
- 単語の分散表現
- 分布仮説
- 共起行列
- PPMI 行列
- SVD による次元削減
- word2vec
- 推論ベースの手法
- CBOW モデル
- skip-gram モデル
- king - man + woman = ?
- Bag of words
- モデルの仕組み
- tf-idf
- tf (term frequency)
- idf (inverse document frequency)
- tf-idf (term frequency–inverse document frequency)
- RNN
- 言語モデル
- RNN とは
- 言語モデルの評価
- RNN の改良
- LSTM
- LSTM の更なる改善
- Seq2Seq
- Seq2Seq の中身
- Seq2Seq の改良
- その他のアプリケーション
- まとめ
- 参考文献
概要
本記事では自然言語処理の技術の歴史についてお話します!
ChatGPT を筆頭に自然言語処理の技術は近年大きく進歩し続けています。我々の日常には自然言語処理を用いたアプリケーションで溢れています。そのため、自然言語処理という分野に興味を持った人は少なくないでしょう。
しかし、いきなり ChatGPT の技術を詳細に理解しようとするのは大変です。まずは ChatGPT が完成するまでに開発されてきた技術を順に理解することが重要です。この記事では ChatGPT の出現手前までの自然言語処理の歴史をたどっていこうと思います!
「自然言語処理」とは?
「自然言語処理」という単語は何を意味しているでしょう。それは 我々の扱う言語をコンピュータにも理解させるための技術 です。
コンピュータが扱う言語といえば「プログラミング言語」を真っ先にイメージすると思います。プログラミング言語は、それの意味が一意に解釈できるように文法や単語の意味が設計されています。
我々の扱う「自然言語」に絶対的な定義はありません。ましてや時代とともに使われ方は変わっていきます。そのため自然言語をコンピュータ上で扱うことは非常に困難です。
我々が話す言葉の意味は「単語」によって構成されます。そのため 単語の意味 をうまく捉え、コンピュータが処理できる表現に落とし込むことが自然言語処理を実現する上で重要です。単語の表現が第一の目標です。目次では「2. シソーラス」から「4. word2vec」までに該当します。
また、我々が普段使用する「文章」は単なる単語の羅列ではありません。文章には 文脈 が存在します。そのため文章に含まれる文脈を扱うことができるモデルも考える必要があります。文章を扱うことを第二の目標とします。目次では「5. Bag of words」から「9. Seq2Seq」までに該当します。
シソーラス
シソーラスとは
まず初めに考えられたのは シソーラス と呼ばれる辞書のようなもので「単語の意味」を表現する方法です。Wikipedia によるとシソーラスは以下で定義されています。
単語の上位 / 下位関係、部分 / 全体関係、同義関係、類義関係などによって単語を分類し、体系づけた類語辞典・辞書
このままでは分かりにくいので、日本語を例にそれぞれの関係を示します。
- 上位 / 下位関係:「果物 / いちご」, 「本 / 漫画」
- 部分 / 全体関係:「タイヤ / 自動車」, 「CPU / コンピュータ」
- 同義関係:「私, 僕, 俺, ...」, 「コンビニ, コンビニエンスストア」
- 類義関係:「優秀, 卓越, 秀逸, 抜群, ...」, 「巨大, 広大, 膨大, 莫大, ...」
シソーラスではこのような関係性を多くの単語間で定義します。日本語のシソーラスとして有名なものとして 日本語 WordNet があります。興味があればリンク先のページを閲覧してみてください。
シソーラスの欠点
お気づきかもしれないですが、シソーラスによる「単語の意味」の表現にはいくつかの欠点があります。
- 時代の変化に対応するのが困難
- 時代とともに新たな単語は生まれます。例えば「ふなっしー」という単語は 2000 年には存在していませんでした。人は単語と単語を組み合わせるなどして新たな単語を生み出していきます。また、時代によって意味が異なる単語もあります。有名なものは「確信犯」という単語で、単語の誤用が世間に広がったがために意味が変化した例の一つです。
- 多くの人手を必要とする
- 広辞苑にある単語数は約 25 万語です。それらの関係を全て定義するための人的コストは計り知れません。
- 単語の細かなニュアンスが表現できない
- 我々が話す言葉にはニュアンスが含まれます。「お疲れ」という言葉には「相手の苦労を労う」意味もあれば、「煽り」の意味が込められる場合があります。そのようなニュアンスをシソーラスで定義するのはとても困難です。
統計的手法
シソーラスを用いて「単語の意味」を表現するには限界がありそうです。そこで コーパス と呼ばれる「人によって書かれた文章」から自動的に、そして効率よく「単語の意味」を表現する手法があります。その一つが 統計的手法 です
単語の分散表現
「統計的手法」の説明をする前に、コンピュータで「単語の意味」を処理できる表現方法について考えます。
例えば「色」をコンピュータで処理する場合「RGB」と呼ばれる 3 次元のベクトルを用います。「水色」の場合 (R, G, B) = (24, 235, 249)です。
RGB のように「単語の意味」をベクトルで表現したものを 単語の分散表現 と呼びます。第一の目標を達成するために「単語の分散表現」を獲得する方法を考えていきます。
分布仮説
「色」の場合は 光の 3 原色(赤、緑、青という 3 つの色をさまざまな割合でまぜれば、様々な色をつくることができる)という仮説をもとに RGB というベクトル表現を得ることができます。では「色」ではなく「単語」の場合、分散表現はどのような仮説のもとで獲得していくのでしょうか。
その仮説の一つに 分散仮説 と呼ばれるアイデアがあります。これは「単語の意味は、周囲の単語によって形成される」という仮説です。つまり「単語自体には意味はなく、その単語の文脈によってその単語の意味が形成される」と仮定します。「統計的手法」以外にも、多くの自然言語処理はこの仮説に基づいて研究されています。
単語の区切りがわかりやすい英語を例に説明します。「I drink beer.」や「We drink wine.」という文章から、「drink」という単語の近くには「beer」や「wine」といった「飲み物」を表す単語が現れやすいことが分かります。また、「I have bread.」や「I eat bread.」という文章から、「have」と「eat」が近い意味の単語だということも分かります。
これから分布仮説を基に「単語の分散表現」を求める具体的な方法について説明します。そこで必要となるのは 共起行列、PPMI 行列、SVD による次元削減の 3 つの要素です。
今後、ある単語の「コンテキスト」というときは「ある単語の周囲に存在する単語」を指します。ウィンドウサイズが m の場合は、その単語の左右 m 単語を指します。ウィンドウサイズを 2 としたとき、「Everything you can imagine is real.」という文章における単語「imagine」のコンテキストは「you, can, is, real」の 4 つです。
共起行列
まず共起行列について説明します。扱う単語の種類を N 種類とした場合、共起行列 $C$ は $N \times N$ の対称行列となり、各行各列にそれぞれ単語を割り当てます。行列の各要素は、第 i 行に該当する単語を $w_i$、第 j 列に該当する単語を $w_j$ とすると
$$ 要素 C[i][j] =「単語 w_i のコンテキストに単語 w_j が含まれた回数」$$
と定義します。つまり共起行列とは、考えているすべての単語に対して、共起する単語をテーブルにまとめたものです。この行列の各行は該当する単語 $w_i$ とその周辺の単語との関係が表されています。つまり共起行列の各行は「単語の分散表現」となっています。これで「単語の意味」をベクトルで表すことができました!
PPMI 行列
共起行列のみを用いた「単語の分散表現」には欠点があります。それは単語の出現頻度を考えていない点です。例えば「the」という単語は多くの名詞の頭につきます。なので「car」という単語の分散表現において、「drive」という単語ではなく「the」という単語の方が重要度が大きくなる可能性があります。
これを解決するために 相互情報量 PMI を考えます。これは確率変数 $x$, $y$に対して以下で定義されます。
$$ PMI(x, y) = log_2 \frac{P(x, y)}{P(x)P(y)} $$
$P(x)$ は $x$ が起こる確率、$P(x, y)$ は $x, y$ が同時に起こる確率を表します。ここで単語x,yの出現する回数をC(x), C(y)とし、単語x, yの共起する回数をC(x, y)として表すと次のように書き換えられます。
$$ PMI(x, y) = log_2 \frac{C(x, y) \cdot N}{C(x)C(y)} $$
ただしこの値を用いると問題が生じる可能性があります。それは、2つの単語が共起する回数 $C(x, y)$ が 0 のものが存在する場合、PMI が無限大になってしまう点です。そこで新たに 正の相互情報量 PPMI を以下の式で定義します。
$$ PPMI(x, y) = max(0, PMI(x, y)) $$
これで単語間の関係を 0 以上の実数で表すことができました!
SVD による次元削減
PPMI でもまだ問題が残っています。扱う単語数 N が大きくなるにつれ「単語の分散表現」の次元も大きくなってしまいます。また PPMI の多くの要素が 0 であり無駄が多いです。そこで PPMI 行列に対して 特異値分解 SVD を施すことで、重要な情報を残しつつ 次元削減 を行います。
SVD とは任意の行列 X を 3 つの行列積へと分解する作業です。数式で書くと、次のように表されます。
$$ X = USV^{T} $$
ここで $U$ と $V$ は直行行列、$S$ は対角行列です。詳しいことは省きますが、行列 U の一部を単語ベクトルとして扱うことができます。このように PPMI 行列を特異値分解することで次元を削減することができます!
統計的手法についてまとめようと思います。まず始めは共起行列で単語ベクトルを表現しようとしました。しかしそれでは単語の出現回数を考慮できていませんでした。欠点を補うために PPMI を考えました。理論上はこれで十分ですが、扱う単語数が大きくなると計算するのが困難になってしまいます。そこで SVD による次元削減を行うことでコンピュータ上でも扱えるようにしました。
word2vec
前の章では 統計的手法 によって 単語の分散表現 を得ました。具体的な方法としては 共起行列 や PPMI といったコーパス全体の統計データを利用し、それに SVD を施すことで分散表現を獲得しました。
しかし SVD にも問題があります。SVD は $N \times N$ の行列に対して $O(N^3)$ の計算コストがかかります。扱う語彙数が増えると計算コストは実行不可能なほどに膨れ上がります。また、新たな単語を語彙に追加して分散表現を更新する場合、ゼロから再計算を行う必要があります。別の手法を考える必要がありそうです。
上記の欠点を克服した手法が 推論ベースの手法 であり、その代表的なモデルとして word2vec と呼ばれるものがあります。
推論ベースの手法
「推論ベースの手法」では「ある単語 w のコンテキストが与えられたときに w がどのような単語であるかを推測する」というタスクを解決するモデルを学習する過程で「単語の分散表現」を獲得します。モデルにニューラルネットワークを使用し、学習後のパラメータの一部が「単語の分散表現」となります。
ニューラルネットワークを使用するため、ミニバッチで学習できます。つまり語彙数が多い場合でも複数マシン/複数 GPU の利用による並列計算で全体の学習を高速化できます。また、語彙を追加する場合でも既存のパラメータをモデルの初期値とすることでパラメータの再学習を行うことができます。
次に word2vec のモデルの一つである CBOW モデル について見ていきましょう!
CBOW モデル
CBOW モデルは、コンテキストからターゲット(コンテキストに囲われた単語)を推測することを目的としたニューラルネットワークです。そのため入力はコンテキストを使用します。出力は各単語のターゲットとしての「スコア」を表しています。「スコア」とは具体的に、与えられたコンテキストのもとでその単語がターゲットである確率を表しています。
図 4-1 がウィンドウサイズ 1 の場合の CBOW モデルのネットワーク構造です。入力層が 2 つあり、中間層を経て出力層へと辿り着きます。ここで、入力層から中間層への変換はパラメータを共有する全結合層(重みは $W_{in}$ )によって行われます。そして、中間層から出力層への変換は別の全結合層(重みは $W_{out}$ )によって行われます。
入力は単語 ID の該当する箇所のみが 1 でそれ以外が 0 の one-hot ベクトル です。また、重み $W_{in}$ は $7\times3$ の形状の行列です。そのため入力と重みの行列積では、重みの中で入力の単語に該当する部分が抜き出されます。図 4-2 がそのイメージです。抜き出されたベクトルがその単語の分散表現となります。
skip-gram モデル
次に skip-gram モデル について説明します。このモデルはターゲットからコンテキストを推測することを目的としたニューラルネットワークです。基本的には CBOW モデル の入力と出力が反転したものです。
図 4-3 がウィンドウサイズ 1 の場合の skip-gram モデル のネットワーク構造です。入力層は一つだけであり、入力はターゲットとなります。また、出力層はコンテキストの数だけ存在し、出力は各単語のコンテキストとしての「スコア」を表しています。
一般には skip-gram モデル から得られた単語の分散表現の方が優れているとされています。それは CBOW モデル で取り組むタスクよりも skip-gram モデル で取り組むタスクの解決の方が困難だからと言えます。「I ? tea.」から「 ? が drink」であるという推測をするよりも、「? drink ?.」から「 ? が I と drink」であるという推測をする方が困難です。ただ、skip-gram モデル を用いた方が損失を求める回数が多いため学習速度は遅くなってしまいます。
king - man + woman = ?
学習を行なって得られた「単語の分散表現」の精度はどのようにして評価されるのでしょうか?
評価方法の一つは「類似単語」が適切かどうかをみます。単語ベクトル同士の「コサイン類似度」を求めると、その値がベクトル同士の類似度となります。単語の分散表現はベクトルで表されているため 2 つのベクトルがどれだけ同じ方向を向いているかを定量的に評価することができます。
他には、「類推問題」を解くことにより評価することができます。有名なものでは「king - man + woman = queen」があります。word2vec モデルは「man」に対する「king」は「woman」でいう何でしょう?といった類推問題を解くことができます。これ以外にも「take」でいう「took」は「go」でいう「went」であるという、動詞の原型と過去形の関係についても対応できます。もちろん全ての問題を解くことができるというわけではなく、間違った回答をする可能性もあります。
word2vec モデルはどのようなアプリケーションに適用できるのでしょうか。単語の分散表現を獲得することが重要である理由は、それが別の分野にも適用できるためです。例えば文章を入力としてその文章の感情を読み解く「感情分析」というタスクに適用できます。入力としての自然言語に対する分散表現を求め、「感情分析」特有のモデルにそれを入力することでタスクを解決することができます。
単語の分散表現の利点は、単語を固定長のベクトルに変換できることにもあります。one-hot ベクトルではなく分散表現として単語を扱うことができる点が重要です。
無事「単語の分散表現を獲得する」という第一の目標は達成することができました!
次は文書を扱う手法について考えていきましょう。
Bag of words
文書を扱うモデルの中で最もシンプルなものを紹介します。それは Bag of words と呼ばれるモデルです。このモデルを用いると文書をベクトルで表現することができます。
モデルの仕組み
このモデルでは文書内における単語の順序や文脈は考慮せずに、文書から特徴量を抽出します。
ある文書 $d$ とそれに含まれる単語数と同じ大きさのベクトル $V$ を考えます。そのベクトルにおける i 番目の要素に単語 $w_i$ を対応させます。文書 $d$ において単語 $w_i$ が出現する回数を $V[i]$ に格納します。
とてもシンプルな形で文書をベクトル化することができました。しかし、あまりにも単純なので欠点もあります。次章では Bag of words を改良した tf-idf モデルを紹介します・
tf-idf
次に Bag of words と比較してより実用的な tf-idf モデルについて紹介します。この手法はデータベースや文書(document)における検索システムに使用されています。
具体的に tf-idf とは統計量を指します。wikipedia によると以下で定義されています。
tf-idf は、コーパスや収集された文書群において、ある単語がいかに重要なのかを反映させることを意図した統計量(数値)である
つまり tf-idf とは文書とそれに含まれる単語の関係を、統計的手法を用いて表す手法です。
tf (term frequency)
tf-idf の頭部分である tf は term frequency の略です。「term」には「単語」という意味があり、「frequency」には「頻度」という意味があります。つまり「term frequency」を愚直に翻訳すると「単語頻度」です。文書 $d$ における単語 $t$ の重要度は、文書 $d$ 中のある単語 $t$ の出現頻度に比例すると考えます。
tf を数式で表してみましょう。ただし tf の定義はいくつかあるので、その中でも標準的なものを紹介します。$f_{t, d}$ を「文書 $d$ に含まれる単語 $t$ の出現頻度」としたとき、数式は以下のようになります。
$$\text{tf}(t, d) = \frac{f_{t, d}}{ \sum_{t' \in d} f_{t', d}}$$
tf は文書 $d \in D$ の中での 単語 $t \in T$ の相対度数を表しています。しかし共起行列の場合と同様に、単語の各文書における出現頻度である 単語の特異性 が考慮されていません。
idf (inverse document frequency)
単語の中には ストップワード と呼ばれる「自然言語処理において重要でない単語」が存在します。例えば「the」や「a」はストップワードに含まれます。tf-idf では、多くの文書で普遍的に使用される単語の場合、値を小さくする必要があります。
「単語の特異性」を考慮するために idf 導入します。idf は普遍的に使用されている、つまり特異性のない単語に対してペナルティを与える統計量です。
tf と同様に idf の数式での定義はいくつかあるので標準的なものを紹介します。扱う文書の集合を $D$ とし、その総数を $|D|$ とします。また、単語 $t$ が出現する文書の数を $|\{d \in D | t \in d \}|$ と書くことにします。このとき idf は以下の数式で書けます。
$$\text{idf}(t, D) = \text{log} ~ \frac{|D|}{~1 + |\{d \in D | t \in d \}|}~ $$
単語 $t$ の文書頻度は $\frac{~|\{d \in D | t \in d \}|~}{|D|}$で表されます。つまり idf を「単語の文書頻度の逆数を対数スケールしたもの」として定義します。分母に 1 を加えているのはゼロ除算を防ぐためです。
「単語の特異性」が大きいほど、idf も大きくなります。逆に「単語の特異性」が小さい単語に対する idf は小さな値になります。
tf-idf (term frequency–inverse document frequency)
tf 及び idf はそれぞれ「単語 $t$ の文書 $d$ での出現頻度」と「単語の特異性」を表しています。これの積が tf-idf の値となります。
$$\text{tf-idf}(t, d) = \text{tf}(t, d) \cdot \text{idf}(t, D)$$
ある文書内において出現頻度が高く、特異性の大きい単語ほど大きな値となります。
tf-idf を用いたアプリケーションには以下のようなものがあります。
- 情報検索 や 検索エンジン
- web の検索エンジンではユーザがクエリを入力し、そのクエリと関連度が大きいサイトを取得してきます。入力されたクエリを $t$ とし、サイトの集合を $D$ とします。ますは全ての $d \in D$ に対して tf-idf($t, d$) を計算します。この値をランキングにした時、上位にあるサイトはユーザが求めているサイトに近いものとなりそうです。
- テキストマイニング
- テキストマイニングとは、膨大なテキストの中から重要な情報を見つけるという作業です。このテキストに対して tf-idf を施すことによって、テキスト内の重要な単語をピックアップすることができます。
- 文書クラスタリング
- 文書クラスタリングとは、複数の文書に対して類似している文書群に分類する作業です。いくつかの単語に対して tf-idf を求め、それを一つにまとめてベクトル化します。
これで tf-idf を用いて単語と文書の関係を表現できることができました。また、これを用いたアプリケーションは数多く存在します。しかし文書内にある単語の順序を無視しているため「文脈」を捉えることはできていません。それを可能にするモデルを次章では考えていきます。
RNN
この章では文章の「文脈」を扱うことができる RNN モデルについて紹介します。RNN を使用すると、複数の単語を入力し、その単語から始まる文章を生成することができたりします。
RNN の紹介の前に「確率」の観点からこれまでのモデルについておさらいしたいと思います。$w_1, w_2, ..., w_T$ という単語の列で表されるコーパスを考えます。そして、t 番目の単語を「ターゲット」として、その前後にある t-1 番目および t+1 番目の単語を「コンテキスト」として扱います。
ここで CBOW モデルが行うことは、コンテキストである$w_{t-1}, w_{t+1}$からターゲットである$w_t$を推測することです。つまり CBOW モデルは事後確率
$$P(w_t|w_{t-1}, w_{t+1})$$
をモデル化したものです。そして損失関数
$$L = -logP(w_t|w_{t-1}, w_{t+1})$$
が最小となるように学習を行うと、その副産物として「単語の分散表現」が得られました。ただし、CBOW モデルでは$w_{t-1}, w_{t+1}$の順序は考慮できません。つまりコンテキストの順序が無視されてしまいます。
これからの説明のためにコンテキストを「ターゲットの前後 2 文字」から「ターゲットの左側 2 文字」に定義し直します。つまり CBOW モデルが扱う事後確率を
$$P(w_t|w_{t-2}, w_{t-1})$$
とします。
言語モデル
CBOW モデルや skip-gram モデルを使用して単語の分散表現を獲得することはできました。しかし我々が現実世界で扱っているのは「単語」だけではありません。その単語の列である「文章」を主に使用しています。文章は単なる単語の羅列ではなく 文脈 が存在します。この「文脈」をコンピュータが理解するにはどのようなモデルを使用する必要があるのでしょうか。
ここで新しいモデルである 言語モデル について考えます。このモデルは単語の並びに対して確率を与えます。つまり単語の並びが与えられたときに、それがどれだけ自然な単語の並びであるのかということを確率で評価するモデルを考えます。
$w_1, w_2, ..., w_m$ という順序で単語が出現する確率は、$P(w_1, ..., w_m)$で表されます。この確率は複数の事象が同時に起こる確率であるため同時確率と呼ばれます。また 確率の乗法定理 と呼ばれる以下の式で表される定理が存在します。
$$P(A, B) = P(A|B)P(B)$$
同時確率は「確率の乗法定理」を用いると以下のように変形することができます。
$$P(w_1, ..., w_m) = \prod_{t=1}^{m} P(w_t|w_1, ..., w_{t-1})$$
数式の簡略化のため、$P(w_1|w_0) = P(w_1)$としました。
これから単語の並びを考慮した言語モデルである RNN について紹介していきます!
RNN とは
RNN は「Recurrent Neural Network」の略です。日本語では「再帰ニューラルネットワーク」と呼ばれています。「再帰」という単語が表す通り、モデルへの入力にモデルの出力が使用されます。
図 5-1 は RNN のネットワーク構造です。内部の RNN と書かれたレイヤーでは以下のような計算が行われます。
$$h_t = tanh(h_{t-1} W_h + x_t W_x + b)$$
ここで前のレイヤーの出力$h_{t-1}$が次のレイヤーの入力として使用されるため「再帰」という名前がつきます。
RNN レイヤーからの出力$h_t$は隠れ状態と呼ばれ、それ以前の単語列の情報が格納されます。
図 5-2 は RNN を用いた「言語モデル」である RNNLM のネットワーク構造の全体です。単語 $w_0$ の次にくる単語の尤もらしさを確率分布 $y_0$ として出力します。
言語モデルの評価
単語列に対して確率を与える「言語モデル」の評価はどのようにして行われるのでしょうか。言語モデルの予測性能の良さを評価する指標として パープレキシティ がよく用いられます。パープレキシティは「確率の逆数」の値が使用されます。
「I have a pen.」という文章を例に入力が 1 つの場合を考えます。ある言語モデルに「I」という単語を入力し、次の単語が「have」である確率が 0.5 と出力された場合、パープレキシティは $\frac{1}{0.5} = 2$ と計算されます。この場合「言語モデルは次の単語の候補を 2 個程度に絞ることができた」と考えることができます。そのためパープレキシティは「分岐数」と解釈することができます。正解となる単語の確率が大きく予測されれば良いモデルであると言えます。そのためパープレキシティが小さな値になることを期待します。
入力が複数ある言語モデルではパープレキシティはどのように計算されるのでしょうか。言語モデルの出力は確率であり、損失関数には softmax が使用されます。そのためモデル全体の損失は以下の式で表されます。
$$L = -\frac{1}{N} \sum_n \sum_k t_{nk} logy_{nk}$$
時系列データは N 個あると仮定します。$t_n, y_n$ はそれぞれ、n 個目のデータの one-hot ベクトルの正解ラベルと出力である確率分布です。この損失に指数を取った値 $e^L$ が一般に言語モデルに対するパープレキシティとなります。
RNN の改良
前章で紹介した RNN は非常にシンプルなものです。構造がシンプルなので簡単に実装することができるのですが大きな欠点を抱えています。
その欠点とは時系列データの長期の依存関係をうまく学習できない点です。これは時間方向における演算の回数が多く、勾配爆発もしくは勾配消失が起きてしまうからです。
勾配爆発の回避策としては 勾配クリッピング と呼ばれる手法があります。この手法ではパラメータのノルムが大きくなった場合に、パラメータのスケールを小さくします。
勾配消失を避けるためには少し複雑なモデルを考える必要があります。そのモデルが ゲート付き RNN です。
LSTM
勾配消失を回避するために、ゲートと呼ばれる機能を RNN に取り入れます。ゲートが実装された RNN の一つに LSTM があります。
図 6-1 は LSTM のネットワーク構造の全体です。$c_t$ は RNN には無かった要素であり、記憶セルと呼ばれます。このセルは LSTM レイヤー内のみでデータをやり取りし、上方向のレイヤーに出力されることはありません。この記憶セルの値を用いて隠れ状態$h_t$が計算されます。
内部での関数 f, g, i, o は次のように定義されます。
$$f = \sigma (x_t W_x^{(f)} + h_{t-1} W_h^{(f)} + b^{(f)}) $$
$$g = tanh (x*t W_x^{(g)} + h*{t-1} W*h^{(g)} + b^{(g)}) $$
$$i = \sigma (x_t W_x^{(i)} + h*{t-1} W*h^{(i)} + b^{(i)}) $$
$$o = \sigma (x_t W_x^{(o)} + h*{t-1} W*h^{(o)} + b^{(o)}) $$
$\sigma$ はシグモイド関数、×はアダマール積を表しています。
以下の式で記憶セル$c_t$と隠れ状態$h_t$を求めます。
$$c_t = f \odot c*{t-1} + g \odot i $$
$$h_t = o \odot tanh(c_t)$$
記憶セルの順伝播で使用されている演算は加算及びアダマール積のみです。これのおかげで勾配消失は起こりにくくなっています。
LSTM の更なる改善
ゲートの実装以外にも改善できるポイントがあります。以下の 3 つを説明しようと思います。
- レイヤの多層化
- RNN 以外のニューラルネットワークでも層を深くすることでモデルの精度を向上させることができました。言語モデルでも図 6-2 のように LSTM レイヤーを縦方向に積み上げることで精度を向上させることができます。どれだけ層を深くするかは問題の複雑さや学習データの量に応じて適切に決定する必要があります。
- 過学習の抑制
- 層を深くすればするほどモデルの表現力は豊かになります。しかしそれと同時に過学習が起きやすくなる点には注意が必要です。過学習を抑えるにはモデルの複雑さを減らす 正則化 を行う必要があります。
- 正則化の一つとして Dropout があります。これは学習時にレイヤー内のニューロンのいくつかをランダムに無視して学習を行うものです。Dropout を挿入する場所には 2 つ候補があります。一つ目は横方向(時間方向)であり、二つ目は縦方向(レイヤーの深さ方向)です。横方向の場合 変分 dropout を使用します。
- 重み共有
- 他に改良する手法として 重み共有 があります。文字通り複数の層の重みを共有します。図 6-2 のモデルでは Embedding レイヤと Affine レイヤの重みを共有します。パラメータを減らすことができるだけでなく精度も向上させることができます。
以上に加えハイパーパラメータのチューニングを厳密に行うことで更にモデルの精度を向上させることができます。
Seq2Seq
これまでは RNN や LSTM の実装について説明してきました。この章ではそれらの言語モデルを利用したアプリケーションについて説明したいと思います。
自然言語処理に関係するアプリケーションはたくさんあります。例として以下のようなものがあります。
- 日本語から英語への 機械翻訳
- 自動で文章を要約する 自動要約
- 画像からその説明文を生成する 画像キャプショニング
このようなアプリケーションを実現するモデルとして Seq2Seq があります。このモデルは「ある時系列データを別の時系列データへと変換する」ことができます。時系列データには「文章データ」や「音声データ」、そして「動画データ」が含まれます。上記のアプリケーションにおける「時系列データの変換」は次のようなものです。
- 機械翻訳:日本語の文章から英語の文章
- 自動要約:長い文章から簡潔な文章
- 画像キャプショニング:画像からそれを説明する文章
Seq2Seq モデルは様々なアプリケーションに適用可能です。では Seq2Seq モデルの実装について具体的に見ていきましょう。
Seq2Seq の中身
Seq2Seq モデルでは 2 つの RNN(LSTM)を利用します。そしてそれぞれの RNN を Encoder, Decoder と呼びます。そのため Seq2Seq は Encoder-Decoder モデル とも呼ばれます。
「Encode」、「Decode」はそれぞれ日本語に直すと「符号化」「復号化」です。Seq2Seq では 1 つ目の RNN である Encoder で入力された時系列データをコンパクトな表現に変換し、2 つ目の RNN である Decoder でその表現を目的の時系列データに変換します。
図 7-1, 7-2 はそれぞれ Encoder, Decoder のレイヤ構造です。日本語の文章「私はペンを持っている」を英語の文章「I have a pen」に変換するタスクを想定しています。\<eos> は 区切り文字 であり、文章の開始や終了を表現する特殊文字です。
まずは Encoder について説明します。入力は変換前の時系列データです。出力は最後の隠れ状態ベクトル$h_{T-1}$のみで、この値こそが「コンパクトに表現された時系列データ(入力)」です。そして Decoder への入力となります。重要なのは時系列データ(入力)が固定長のベクトル(隠れ状態)に変換されている点です。
次に Decoder について説明します。Decoder は Encoder によって変換された固定長のベクトルから目的の時系列ベクトルを生成することです。図 7-2 を見ると分かる通り、Decoder は前章で説明した LSTM モデルとほとんど同じ構成です。異なる点は先頭の LSTM レイヤが隠れ状態 $h_{T-1}$ を受け取っていることです。このたった一つの違いで機械翻訳を実現しています。
順伝播では Encoder から Decoder へ、逆伝播では Decoder から Encoder へとデータが流れます。2 つの RNN をくっつけるだけで「言語モデル」から「時系列変換モデル」を構築することができました!
Seq2Seq の改良
Seq2Seq による学習を改善する方法がいくつかあります。
一つ目は 入力データの反転 です。「私 は ペン を 持って いる」と入力していたものを「いる 持って を ペン は 私」と変換するだけでモデルは改善されます。入力データの反転による効果は問題に応じて異なりますが、多くの場合向上するらしいです。
二つ目は Peeky と呼ばれるものです。Peeky とは日本語で「のぞき見」を意味します。一体何をのぞき見するのでしょうか。現在 Encoder から出力された固定長ベクトル $h_{T-1}$ が与えられるのは先頭の LSTM レイヤだけです。この Encoder から与えられる唯一の情報を、全ての LSTM レイヤ及び Affine レイヤが見ることができるように修正します。図 7-3 は修正した Peeky_Decoder のネットワーク構造です。
LSTM レイヤや Affine レイヤに入力されるデータに固定長ベクトルが追加されました。実際はこれまでの入力と固定長ベクトルを結合(concatenate)させます。そのため、それぞれのレイヤで使用する重みのサイズは大きくなります。
その他のアプリケーション
画像キャプショニングについて少し説明したいと思います。
画像キャプショニングでは「画像データから文章データ」という変換を行います。ゆえに上記のようなモデルではうまくいきません。どうするのでしょうか。
解決策は Encoder を RNN から CNN に変更することです。Encoder の役割は入力された時系列データから特徴を取り出し、固定長ベクトルに変換することでした。CNN は画像から特徴マップを抽出します。つまり画像の場合は CNN が Encoder としての役割を担うことができます!特徴マップを平滑化し、Affine レイヤに通すことで LSTM を用いた Decoder の入力として扱うことができます。
まとめ
第一の目標は 単語の分散表現 の獲得でした。シソーラス や 統計的手法 を用いて獲得しようとしましたが、人的コストなどにより困難なことが分かりました。そこで word2vec を用いた 推論ベースの手法 について紹介しました。ニューラルネットワークを用いた手法であり、「ミニバッチ学習」や「並列計算」そして「パラメータの再学習の容易さ」といった利点がありました。
第二の目標は 文章を扱うこと でした。まずは「文脈」を考慮せずに 文書 を扱う Bag of words や tf-idf を考えました。文脈は考慮できていませんが、利用されているアプリケーションはたくさんあります。文脈を考慮するには RNN やそれを改善した LSTM といった 言語モデル を用いることで実現できました。「時系列データから時系列データの変換」というタスクには「Encoder-Decoder モデル」である Seq2Seq を利用することができました。
しかし RNN には問題点がないかのように思われますがそんなことはありません。次回の記事では RNN の問題を解決する Attention と呼ばれるアイデアについて紹介します。また、ChatGPT のベースにもなっている Transformer と呼ばれるモデルについても解説しようと思います。
この記事を最後まで読んでいただきありがとうございます。次の記事でまた会いましょう!
参考文献
Author

芝 紘希
ソフトウェアエンジニア
現在は神戸大学工学部情報知能工学科に在籍し勉強中です。ただただひたむきに筋肥大。