言語生成の強化学習をやっていく(手法紹介 REINFORCE編)

この記事は強化学習苦手の会 Advent Calendar 2020の3日目の記事です。

免責事項:載せている式は論文からの引用ではなく、自分の理解で書いたものが含まれますので、サーベイ論文の紹介と言っても論文の内容をそのまま写しているわけではありません。気になるところがあれば原論文をご確認することを勧めます。

2020.12.04 追記

REINFORCEの式が間違ってたので修正しました。
(誤)$\nabla_{\theta} \mathcal{L}_{\theta}= - \frac{1}{T} \sum_{t=1}^{T} { \nabla_{\theta} \log \pi_{\theta}\left(\hat{y}_{t+1} \mid \hat{y}_{t}, s_{t+1}, c_{t}\right) \left( r(\hat{Y}) - r_b \right)}$
(正)$\nabla_{\theta} \mathcal{L}_{\theta}= - \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T} { \nabla_{\theta} \log \pi_{\theta}\left(\hat{y}_{t+1} \mid \hat{y}_{t}, s_{t+1}, c_{t}\right) \left( r(\hat{Y}) - r_b \right)}$

はじめに

こんにちは、品川です。
私は、強化学習苦手の会のもくもく会ニューラルネットによる言語生成の強化学習を試してみようとしています。
理由は、私自身が興味あるというのと、image-captioningなどの研究領域で、強化学習を使ってfine-tuningするのが標準的になってきたので、中身を深く理解しておく必要があると考えたためです。

最近の強化学習自体には色々な教科書や良さげな資料が出てきていますが、言語生成においては意外とチュートリアル的な資料をあまり目にしていませんでした(てっきり出てくると思っていたのですが)ただ、一つサーベイ論文を見つけて読んでみたら結構良かったので、今回はその論文で学んだことを紹介しようと思います。

サーベイ論文の概要

今回紹介するサーベイ論文のタイトルは"Deep Reinforcement Learning for Sequence-to-Sequence Models"です。 arxiv.org

2019年の4月にArXivで公開された論文です。言語生成に用いるモデルとしてはLSTMのようなRNNベースの系列生成モデルを想定していますが、現在徐々に勢力を広げつつあるTransformerベースのモデルでも自己回帰なモデルは基本的な考え方が同じはずなので応用可能と思います。

このサーベイ論文の面白い所は、説明が方策勾配法→Actor Critic→Q-learningになっている点です。多くの書籍や資料ではQ-learning→方策勾配法→Actor Criticというのが多い印象でしたので、方策勾配法から入る説明は初めて見ましたが、こちらの説明の方が個人的にはすっと入ってくる気がしています。

また、サーベイ論文として、image-captioningだけでなく様々な分野の言語生成タスク、評価指標が網羅されています。著者はTensorflowで各種のアルゴリズムの再現実装も行っているようで、訓練時間についても比較言及している点が面白かったです。(Actor-Criticが良さそうという結論でした;後述します)

一つ注意点は、Double Deep Q-LeanringとDDQNの説明が紛らわしいという点でしょうか。式(30)は2つあるQの前後がおそらく逆であるべきと思われますので、この点だけ注意が必要かと思います。(後述します)

言語生成モデルのおさらい

まず、ニューラルネットによる言語生成について簡単におさらいしたいと思います。

言語生成モデルは、$w_i$を文のi番目のトークン(生成時に扱う単位、単語・文字・サブワードなど)とすると、$p(w_1, w_2, w_3, \ldots, w_N, C) = p(C)\Pi_{t=1}^{N}{p(w_t | w_{t-1}, w_{t-2}, \ldots, w_1, C)}$のモデルを学習することを目指します。ここで$C$は生成条件で、例えばimage-captioningなら画像、機械翻訳なら原言語文が該当します。

本記事では、サーベイ論文の内容に沿って、ニューラル言語モデルとしてRNNを想定することにします。 RNNを使う場合、トークンを予測する確率分布$p(w_t | w_{t-1}, w_{t-2}, \ldots, w_1, C)$は、隠れ層$h_t$を用いて以下のように表現されます。

$p(w_t | w_{t-1}, w_{t-2}, \ldots, w_1, C) = p_{\theta}\left(y_{t} \mid \hat{y}_{t-1}, h_{t}, c_{t-1}\right)$

ここで、生成済みの系列情報$w_{t-1}, w_{t-2}, \ldots, w_1$と生成条件$C$は文脈ベクトル$c_{t-1}$とRNNの隠れ層$h_t$によって表現されます。 文脈ベクトル$c_{t-1}$は、主に生成条件のencoderからの特徴量(attention vectorなどの情報も含む)だと考えて良いです。
$\hat{y}_{t-1}$は、前の時刻に生成したトークンが対応しています。$\theta$はモデルの学習可能なパラメータです。

言語生成における強化学習 (前提知識)

言語生成における強化学習では、この生成済みの系列から次のトークンを予測する確率分布$p_{\theta}$が方策$\pi_{\theta}(a|s)$にあたります。つまり、言語生成における強化学習のaction $a$は「語彙の中から次に生成するトークンを選ぶ操作」、状態 $s$は「隠れ層や文脈情報、前の時刻のトークンによる入力ベクトル」ということになります。

エピソード

1エピソードは、文頭から文末のトークンを生成するまでが該当します。
文を生成しきって1エピソードが終了した時点で教師データである参照文との近さをBLEUやCIDERなどの文の近さの評価尺度で評価するため、通常遅延報酬のみで即時報酬が無いのが特徴のようです。また、強化学習における割引率を小さくすると短い文が生成しやすくなると考えられることから、割引率は1.0か、同程度に高いものが選ばれていると想像します。(私見では、image-captioningとかだと割引率についての言及はないことが多い印象です)

報酬

強化学習の報酬には、言語生成の評価に用いられるBLEUやCIDErなどを使うことができます。これらは生成文と参照文の間の近さを測る評価指標です。 強化学習を言語生成に用いる最大のモチベーションは、これらの微分不可能な評価指標を報酬として直接最適化できる点にあります。

学習における立ち位置

言語生成における強化学習の役割はファインチューニングであるという認識で間違っていないと思います。
多くの手法では、最初にクロスエントロピーでTeacher forcingで学習してからある程度言語モデルを学習させた後に強化学習を適用するケースが多いようです[要出典]。
私見としては、actionの数が多くて探索空間が広いため、効率よく学習するためには、ある程度言語モデルを作りこんでおくことで選択肢を減らす必要があるのだと思います。

言語生成の強化学習 壱ノ型 「REINFORCE(方策勾配法による最適化)」

さて、さきほど方策がニューラルネットになっているという話をしました。ならば、勾配降下法で最適化せねば不作法というもの・・・ということで、この方策を直接最適化する方法である方策勾配法から紹介します。

実際、言語生成系で強化学習を使っている論文で最も頻繁に目にするのは、おそらくREINFORCE(またはモンテカルロ方策勾配法)だと思われます。 REINFORCEは、方策勾配法の最も単純な手法と言われています[MLP強化学習(青本), P.186]。 おそらく、手軽に追加できるという点が利点なのかなと思います。最近は「reward is hogehoge~」とだけ書いてる論文もたまに見ますが、これはだいたいREINFOECEを使っているとみて良いでしょう(たぶん)

ちなみに、REINFORCEは略称で、正式には

REward Increment = Nonnegative Factor times Offset Reinforcement times Characteristic Eligibility(報酬増大=非負係数×オフセット強化×特性エリジビリティ)

とのことです[MLP強化学習(青本), P.186]。

まず目的関数を書いてみます。強化学習の目的は累積報酬を最大化することでした。つまり、目的関数は以下のように書くことができます。

$\mathcal{L}_{\theta}=-\mathbb{E}_{\hat{y}_{1}, \cdots, \hat{y}_{T} \sim \pi_{\theta}\left(\hat{y}_{1}, \cdots, \hat{y}_{T}\right)}\left[r\left(\hat{y}_{1}, \cdots, \hat{y}_{T}\right)\right]$

ここで、$r$は文頭から文末まで一文を生成しきった1エピソードに対しての(遅延)報酬となっています。$\hat{Y} = (y_{1}, \cdots, y_{\hat{T}})$を生成文、$Y_i = (y_{i, 1}, \cdots, y_{i, T_i})$ (ただし、$i=1,2,\ldots$)を参照文とすると、適当な評価指標(例えばCIDEr)を用いて、以下のような意味合いとなります。

$\mathcal{L}_{\theta}=-\mathbb{E}_{ \hat{Y} \sim \pi_{\theta}} \left[r (\hat{Y}) \right]$

$r(\hat{Y})=CIDEr \left(\hat{Y}, (Y_1, Y_2, \ldots) \right)$

目的関数を書いたらそのままbackpropagationしたくなるのが人情ですが、$\mathcal{L}_{\theta}$はCIDErを使っているので微分できません。

そこでREINFORCEでは、方策勾配定理に基づいて、学習パラメータ$\theta$に対し、以下のように方策勾配を求めることができます。

$\nabla_{\theta} \mathcal{L}_{\theta}=-\underset{\hat{Y} \sim \pi_{\theta}}{\mathbb{E}}\left[\nabla_{\theta} \log \pi_{\theta}(\hat{Y}) \left( r(\hat{Y}) - r_b \right) \right]$

一ステップごとにみれば、こう書けます。

$\nabla_{\theta} \mathcal{L}_{\theta}= - \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T} { \nabla_{\theta} \log \pi_{\theta}\left(\hat{y}_{t+1} \mid \hat{y}_{t}, s_{t+1}, c_{t}\right) \left( (\sum_{t'=t+1}^{T}{r_{t'}}) - r_b \right)}$

ここで、$\sum_{t'=t+1}^{T}{r_{t'}}$は時刻$t$からエピソード終了時までのリターン実績と呼ばれるものです。時刻$t$以前に受けた報酬を切り捨てた報酬の総和だと解釈できます。
ただし、言語生成の強化学習では即時報酬はなく、遅延報酬のみを考慮するため、結局以下のように書けます。

$\nabla_{\theta} \mathcal{L}_{\theta}=- \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T} { \nabla_{\theta} \log \pi_{\theta}\left(\hat{y}_{t+1} \mid \hat{y}_{t}, s_{t+1}, c_{t}\right) \left( r(\hat{Y}) - r_b \right)}$

$r_b$というのは強化学習で「ベースライン」と呼ばれているものです。$r_b$自体はパラメータ$\theta$を含まないので、任意の値に対して方策勾配は理論上不偏となりますが、$r_b$を報酬の平均値として設定することで、方策勾配の分散を下げることができ、学習をしやすくさせることができます。

1エピソードで最適化するのか?ステップごとに最適化するのか?

学習の方法として、1エピソード終わったものをbackpropagationするのか、1ステップごとに最適化するのか、どちらなのかが気になりました。しかし、よく考えてみると、1ステップごとに新しいトークンをサンプリングした時に勾配のチェインは切れるので、基本は1ステップごとに最適化するものだと考えて良いかと思います。エピソード終了時にならないと報酬が計算できないので、各時刻の$\pi_{\theta}$の出力確率分布と生成した$y_{t+1} \sim \pi_{\theta}$の値を保持しておく必要があります。

解釈?

$\nabla_{\theta} \mathcal{L}_{\theta}= - \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T} { \nabla_{\theta} \log \pi_{\theta}\left(\hat{y}_{t+1} \mid \hat{y}_{t}, s_{t+1}, c_{t}\right) \left( r(\hat{Y}) - r_b \right)}$

教師あり学習に慣れ親しんだ身として上の式をみると、REINFORCEの式は「自分で生成したサンプル(トークン)を擬似的な教師データとして、評価が高いサンプルに高い重みをつけて学習する操作」だと考えるとしっくりきます。(論文ではEq. (15),(16)に同じような話がありました)

REINFORCEの派生手法:Self-Critic (SC) models

REINFORCEの派生的な研究として"Self-critical Sequence Training for Image Captioning (CVPR2017)"というのが提案されています。

REINFORCEでのベースライン計算は(モンテカルロ)サンプリングした系列を用いているので、分散の低減の効果が十分ではありません。

そこで、Self-Criticでは、このベースライン計算に用いる系列を、サンプリングしたものでなく特定の推論アルゴリズムに従って生成した系列を用いて計算する手法になります。例えば論文ではgreedy searchを使っていました。

動機としては、「greedy searchより良い系列が生成できたら+の報酬を与えたい」というシンプルなアイデアから始まったようです。これを実現する方法として、ベースラインをgreedy searchで生成した系列をベースラインとして利用し、単純なREINFORCEよりも実験的に良い結果を示したとのことです。

Actor-Criticを関連研究として挙げており、Actor-Criticに対してCriticのモデルを必要とせずに使える点を利点として主張していました。(いうて直接Actor-Criticとは比較してるわけではないです)

さて、長くなってきたので本日はここまでにしたいと思います。
サーベイ論文は他にもActor-CriticとQ-learningの話が載っています。後日、こちらの記事も更新したいと思います。今のところ以下の記事を執筆予定です。

実験編では、実際にコードを動かしてみてどのような結果になるか見ていこうと思います。