制御可能な文章生成RAG - RAG学習スクリプト

はじめに

前回 まで単純なデータセットに対してRAG1の学習を行ってきたが、
RAGのモデルを学習するまでの一連の処理をまとめてgithubで公開した。

https://github.com/NeverendingNotification/rag-japanese.git

RAG学習一連の処理

RAGの学習を行うためには以下の処理を行う必要がある。

  1. BERT学習済みモデルの準備
  2. データの前処理
  3. DPR2の学習
  4. DPRモデルのtransformers3モデルへの変換
  5. 知識文章のindex化

BERT学習済みモデルの準備

今回は以下のモデルを利用させてもらった。

https://github.com/cl-tohoku/bert-japanese

前回まではtokenizerの設定が正しくできておらず、日本語のtokenizerが
機能していなかったので出力結果から濁点が消えたりしていた。

今回はDPRもBART4も全て、
transformers.tokenization_bert_japanese.BertJapaneseTokenizer
を利用することで、適切な日本語のtokenizeを行う。

# rag-japanese
python make_small_bert.py --pretrained-model cl-tohoku/bert-base-japanese-whole-word-masking --out-dir models/small_bert --num-layers 3

データの前処理

知識文章と質問・回答文章を含んだcsvファイルから、DPR学習を行うための
jsonファイルを作成する。 知識文章のcsvは通し番号と文章の列があればよいが、
質問・回答csvは質問文・回答文の列に加えて、その質問と関連する知識文章の
情報が必要である。 具体的には、各質問・回答ペアに対して、 Positive,
Negative, Hard-Negativeに対応する知識文章の番号情報が必要である。

質問・回答csv
質問 回答 Positive Negative Hard-Negative
0 北海道の人口は538万人くらいですか? 538万人くらいです。 [979] [836, 937, 11] [96, 629, 288]
1 北海道の人口は708万人くらいですか? 708万人よりも少ないです。 [979] [170, 996, 272] [979, 779, 288]
2 北海道の人口は642万人くらいですか? 642万人くらいです。 [979] [496, 318, 870] [288, 679, 96]
3 北海道の人口は530万人くらいですか? 530万人くらいです。 [979] [793, 247, 575] [929, 431, 779]
4 青森県の人口は132万人くらいですか? 132万人くらいです。 [980] [693, 69, 302] [980, 145, 49]

​ また、前回までは都道府県ごとに学習・評価を分けていたが、今回はランダムに分割している。

# rag-japanese
python preprocess_data.py --knowledge-file data/knowledge.csv --qa-file data/qa.csv --out-file data/dpr_qa.json --valid-split --out-csv

DPRの学習

DPRのモデルを学習する。
Facebookの実装を元に、日本語tokenizerなど一部修正している。

https://github.com/facebookresearch/DPR

# rag-japanese/dpr
python train_dense_encoder.py --train_file ../data/dpr_qa_train.json --dev_file ../data/dpr_qa_valid.json --encoder_model_type hf_bert --pretrained_model_cfg ../models/small_bert --batch_size 8 --output_dir ../models/dpr --num_train_epochs 6

DPRモデルの変換

学習したDPRモデルをtransformersライブラリのDPR形式に変換する。

# rag-japanese/dpr
python convert_model.py -p ../models/dpr/dpr_biencoder.5.386 -o ../models/dpr_transformers

文章情報のindex化

知識文章を学習したDPRのcontext encoderによってembeddingして、
faiss5によりindex化する。

# rag-japanese
python make_index.py  --context-model models/dpr_transformers/c_encoder --knowledge-file data/knowledge.csv --out-dir data/dpr_knowlege_index

RAG学習

ここまで作成した、DPRとindexを利用して、RAGの学習を行う。

# rag-japanese
python train_model.py  --model-type rag --question-model models/dpr_transformers/q_encoder --train-csv data/dpr_qa_train.csv --valid-csv data/dpr_qa_valid.csv --indexdata-path data/dpr_knowlege_index/knowlege --index-path data/dpr_knowlege_index/knowlege_index.faiss --out-dir  results/rag

RAG推論

学習済みRAGモデルから、テストデータに対して、RAGによる文章推論を行う。

# rag-japanese
python test_model.py  --model-type rag --pretrained-model results/rag --test-csv data/dpr_qa_valid.csv --indexdata-path data/dpr_knowlege_index/knowlege --index-path data/dpr_knowlege_index/knowlege_index.faiss --out-dir results/rag --out-file test.csv

出力csvファイル例

df = pd.read_csv(result_csv_file, index_col=0)
print(df.set_index("質問").head(3).T.to_markdown())
2010年から2015年で千葉県の人口は変わっていますか? 1940年から2005年で広島県の人口は変わっていますか? 1950年から2010年で鹿児島県の人口は変わっていますか?
回答 同じくらいです。 増えています。 同じくらいです。
返答 同じ くらい です 。 増え て い ます 。 同じ くらい です 。
関連1 2010年の千葉県の人口は621万人です。 1940年の広島県の人口は186万人です。 1950年の鹿児島県の人口は180万人です。
関連2 2015年の千葉県の人口は622万人です。 2005年の広島県の人口は287万人です。 2010年の鹿児島県の人口は170万人です。
関連3 2010年の埼玉県の人口は719万人です。 1940年の徳島県の人口は71万人です。 2015年の鹿児島県の人口は164万人です。
関連4 2010年の栃木県の人口は200万人です。 1930年の広島県の人口は169万人です。 1955年の鹿児島県の人口は204万人です。
関連5 2010年の富山県の人口は109万人です。 1935年の広島県の人口は180万人です。 2000年の鹿児島県の人口は178万人です。

参考文献

制御可能な文章生成RAG - RAG学習

はじめに

前回 RAG1を学習する前段階としてDPR2の学習を行った。
今回は学習済みのDPRを利用してRAGの学習を行った。

RAGの構成要素

RAGは入力文に対して、関連する知識文章を検索してから、
それに対応する出力文を返すseq2seqモデルである。

RAGは以下の3つの構成要素からなる。

  1. Question Encoder
    • 入力文から特徴量を抽出する
  2. Retriever
    • 1で抽出した特徴量に対して関連する知識文(passage)を検索
    • 知識文から特徴量を抽出する (DPRのcontext encoderを利用)
  3. Generator
    • Retriverから得た特徴量を元に出力文を生成する

1, 2の部分をDPRが担い、3の部分はBART3やT54などのseq2seqモデルが担う。
transformers5ライブラリのRAG実装では、検索効率を向上するため、
Retriever部分は知識文をindex化して利用している。

知識文のindex化

知識文章群の数が増えると検索に必要な時間が膨大となる。
これを緩和するためRAGではfaiss6というライブラリを利用して、
検索の高速化を図っている。

  1. DPRのcontext encoderで知識文章群の各文章の特徴量を抽出
  2. 特徴量群をfaissライブラリを使ってindex化
  3. retrrieverはindexを利用して高速な検索を行う。

参考 : 学習済みDPRを用いた知識文章のindex化

RAGの学習

前々回 作成したデータに対してRAGの学習を行った。
DPRは前回学習したモデルを利用し、generatorはBARTを用いた。

評価文に対する出力結果

質問 正解回答 RAG返答
1925年から1935年で静岡県の人口は変わっていますか? 同じくらいです。 増 えています 。
京都府の人口は634万人くらいですか? 634万人よりも少ないです。 644 万 人 よりも 少 ないてす 。
2005年から2010年で徳島県の人口は変わっていますか? 同じくらいです。 同 しくらいてす 。

濁点が消えている、数字が微妙に間違っている点は気になるが、それらしい返答はできている。

次に質問文に対する関連文章を見てみる。

静岡県の人口は345万人くらいですか? 京都府の人口は280万人くらいですか? 島根県の人口は73万人くらいですか?
正解回答 345万人くらいです。 280万人くらいです。 73万人くらいです。
RAG返答 345 万 人 よりも 少 ないてす 。 202 万 人 よりも 少 ないてす 。 203 万 人 くらいてす 。
関連1 1955年の大阪府の人口は461万人です。 1955年の大阪府の人口は461万人です。 1955年の大阪府の人口は461万人です。
関連2 1965年の大阪府の人口は665万人です。 1965年の大阪府の人口は665万人です。 1965年の大阪府の人口は665万人です。
関連3 1975年の大阪府の人口は827万人です。 1975年の大阪府の人口は827万人です。 1975年の大阪府の人口は827万人です。
関連4 1955年の栃木県の人口は154万人です。 1955年の栃木県の人口は154万人です。 1955年の栃木県の人口は154万人です。
関連5 1960年の大阪府の人口は550万人です。 1960年の大阪府の人口は550万人です。 1960年の大阪府の人口は550万人です。

関連1~5はretrieverから得られた、入力文章に関連すると思われる知識文章上位5件である。

上表の3つの質問に対して関連する文章は変わっていない。
すなわちretrieverが入力文章に対して、意味的に関連する文章を返せていないことになる。
このためgeneratorはretrieverからの入力を無視して、 元の入力文章情報だけから
返答を行っていることとなり、RAGの意味がない(ほぼBARTと挙動が変わらない。)

前回DPR学習時点では評価データに対して正しい情報検索ができていた。
すなわち、学習時にquestion encoderもfine-tuningしてしまったために、
question encoder側が過学習してしまっていると思われる。

そこでquestion encoderの重みを固定して、generatorのみを学習することとする。

generatorのみの学習

評価データ回答例
静岡県の人口は345万人くらいですか? 京都府の人口は280万人くらいですか? 島根県の人口は73万人くらいですか?
回答 345万人くらいです。 280万人くらいです。 73万人くらいです。
返答 1055 万 人 よりも 少 ないてす 。 21280 万 人 くらいてす 。 273 万 人 よりも 少 ないてす 。
関連1 2015年の静岡県の人口は370万人です。 2015年の京都府の人口は261万人です。 2015年の島根県の人口は69万人です。
関連2 2010年の静岡県の人口は376万人です。 2015年の東京都の人口は1351万人です。 2015年の鹿児島県の人口は164万人です。
関連3 2005年の静岡県の人口は379万人です。 2010年の京都府の人口は263万人です。 2005年の島根県の人口は74万人です。
関連4 2015年の福岡県の人口は510万人です。 2005年の京都府の人口は264万人です。 2015年の徳島県の人口は75万人です。
関連5 2015年の佐賀県の人口は83万人です。 2000年の京都府の人口は264万人です。 2015年の広島県の人口は284万人です。

この場合関連文章は概ね正しいが、 返答文章中の数字が
入力文章からかけ離れているものが多い。 (73 → 273など部分的に一致はしている)
おそらくgeneratorが入力文章と知識文章の両方を見るようになったことで、
入力文章の数字部分の再現性能が低下しているものと思われる。

このケースについて他の質問についての結果も見ていく。

Q2 都道府県面積
静岡県の面積は8310km2くらいですか? 京都府の面積は4837km2くらいですか? 島根県の面積は6563km2くらいですか?
回答 8310km2くらいです。 4837km2くらいです。 6563km2くらいです。
返答 8501km2よりも 小 さいてす 。 8837km2よりも 小 さいてす 。 6933km2よりも 小 さいてす 。
関連1 静岡県の面積は7700km2である。 京都府の面積は4600km2である。 島根県の面積は6700km2である。
関連2 福岡県の面積は4900km2である。 東京都の面積は2100km2である。 広島県の面積は8400km2である。
関連3 長野県の面積は13500km2である。 大阪府の面積は1900km2である。 徳島県の面積は4100km2である。
関連4 長崎県の面積は4100km2である。 2015年の京都府の人口は261万人です。 福島県の面積は13700km2である。
関連5 滋賀県の面積は4000km2である。 1995年の京都府の人口は262万人です。 長崎県の面積は4100km2である。

面積に関する質問は人口に関する質問と同様に数字部分の再現がうまくできていない。

Q3 面積比較
島根県と長野県ではどちらが大きいですか? 徳島県岩手県ではどちらが大きいですか? 長崎県大阪府ではどちらが大きいですか?
回答 長野県のほうが大きいです。 岩手県のほうが大きいです。 長崎県のほうが大きいです。
返答 長 野 県 のほうか 大 きいてす 。 岩 手 県 のほうか 大 きいてす 。 長 野 県 のほうか 大 きいてす 。
関連1 島根県の面積は6700km2である。 徳島県の面積は4100km2である。 大阪府の面積は1900km2である。
関連2 長野県の面積は13500km2である。 広島県の面積は8400km2である。 長崎県の面積は4100km2である。
関連3 長崎県の面積は4100km2である。 島根県の面積は6700km2である。 京都府の面積は4600km2である。
関連4 秋田県の面積は11600km2である。 岩手県の面積は15200km2である。 宮崎県の面積は7700km2である。
関連5 徳島県の面積は4100km2である。 福島県の面積は13700km2である。 2015年の長崎県の人口は137万人です。

面積の比較では関連文章も概ね正しく、出力結果も一見正しいが、
generatorは学習に使った都道府県しか再現できないようである。
(右の返答で"長崎"ではなく"長野"と回答している)。

今回学習・評価で都道府県を分けているため、
評価に利用した5県(静岡、京都、島根、徳島、長崎)を含む出力文章は生成できないようである。

Q4 人口比較
1955年から1990年で静岡県の人口は変わっていますか? 1955年から1980年で京都府の人口は変わっていますか? 1950年から1980年で島根県の人口は変わっていますか?
回答 増えています。 増えています。 同じくらいです。
返答 増 えています 。 同 しくらいてす 。 増 えています 。
関連1 1955年の静岡県の人口は265万人です。 1955年の京都府の人口は193万人です。 1950年の島根県の人口は91万人です。
関連2 1995年の静岡県の人口は373万人です。 1955年の東京都の人口は803万人です。 1950年の広島県の人口は208万人です。
関連3 1985年の静岡県の人口は357万人です。 1980年の京都府の人口は252万人です。 1950年の徳島県の人口は87万人です。
関連4 1990年の静岡県の人口は367万人です。 1970年の京都府の人口は225万人です。 1950年の鹿児島県の人口は180万人です。
関連5 1955年の岡山県の人口は168万人です。 1960年の京都府の人口は199万人です。 1980年の島根県の人口は78万人です。

年代間の人口比較では、関連文章の精度がやや低く、出力文章も間違っているものが多い。
やはり細かい数字を考慮して出力文を生成することは難しいものと思われる。

考察

今回都道府県の統計量から作成した文章データセットを使ってRAGを学習したが、
あまりいいモデルができなかった。 RAGの挙動を考えるとそもそもデータセット自体に
いくつか問題がある可能性がある。 (難易度が高すぎる)

  1. 数字の出力
  2. 学習-評価の分割

このデータセットでは回答文に数字を含むデータがたくさんあるが、数字が4桁くらいの幅を
もっており、 データの数(学習データ3000程度)的に数字生成をうまく学習すること
は難しいと思われる。 また、数字情報が入力文章と知識文章に分散していることも
難易度を上げている。

学習・評価データの分割についても都道府県ごとに学習・評価データを分けたのは難易度が
高すぎたと思う。tokenzierの関係上 "京都府"という文字列は "京", "都", "府"という
3トークンに分割されるため、 generatorが都道府県名を出力する場合はこれらの
パターンを覚える必要がある。 学習せずに知識文章だけからこういったパターンを
出力することは難しいと思われるため、 学習・評価データの分割を都道府県で行うのは
難易度が高すぎる気がする。

もう少し単純なデータセットのほうがRAGの挙動が分かりやすいと思う。

まとめ

今回はRAGについて一通り学習を行い、簡単に結果を見てみた。
現時点ではすごいと言えるような結果は出ておらず、
もう少し単純なデータセットでRAGの性能を確かめたいと思った。

参考文献

制御可能な文章生成RAG - DPR

はじめに

前回まではRAGについて調査し、 学習に必要なデータを準備した。
今回はRAG学習に必要なDPRの学習を行う。

DPR

Dense Passage Retrieval1 (DPR)はある質問に回答するために必要な知識文(passage)を
文章群から推定するためのモデルである。
質問文を入力として、知識群の各文章に対してその文に対する関連度を出力する。

ネットワークは質問文を入力するBERTと知識文を入力するBERTの2つのBERTからなり、
それらの出力のドット積を文章間の関連度として、最適化を行っている。

DPRの学習

DPRはtransformers2にも実装されているが学習機能がないため、
実装はFacebookが公開している元論文の実装を用いた。
https://github.com/facebookresearch/DPR

学習対象は前回作成した都道府県質問文章とした。
47都道府県のうち5県をランダムに選び、その県が関係する質問・回答文は評価データとした。
(静岡県, 京都府, 島根県, 徳島県, 長崎県を評価データとした。)

日本語事前学習モデルとして以下のモデルを利用した。
https://github.com/cl-tohoku/bert-japanese

学習結果

Q1に対する関連度

質問文 静岡県の人口は380万人くらいですか? 京都府の人口は1165万人くらいですか? 島根県の人口は624万人くらいですか?
関連度 1位 2015年の静岡県の人口は370万人です。 2015年の京都府の人口は261万人です。 2015年の島根県の人口は69万人です。
関連度 2位 2010年の静岡県の人口は376万人です。 2015年の東京都の人口は1351万人です。 2015年の鹿児島県の人口は164万人です。
関連度 3位 2005年の静岡県の人口は379万人です。 2005年の京都府の人口は264万人です。 2005年の島根県の人口は74万人です。
関連度 4位 2000年の静岡県の人口は376万人です。 2010年の京都府の人口は263万人です。 2015年の徳島県の人口は75万人です。
関連度 5位 2015年の福岡県の人口は510万人です。 2015年の埼玉県の人口は726万人です。 2015年の福島県の人口は191万人です。

前回のQ1は各都道府県の2015年時点での人口がどのくらいかという質問であった。
上表Q1の質問文に対して関連度1位の文章は2015年度時点でのその都道府県の人口であるため、
Q1に関しては質問文と知識文の関連が正しく学習できていると思われる。

Q2に対する関連度

質問文 静岡県の面積は10746km2くらいですか? 京都府の面積は38518km2くらいですか? 島根県の面積は55263km2くらいですか?
関連度 1位 静岡県の面積は7700km2である。 京都府の面積は4600km2である。 島根県の面積は6700km2である。
関連度 2位 福岡県の面積は4900km2である。 東京都の面積は2100km2である。 広島県の面積は8400km2である。
関連度 3位 長野県の面積は13500km2である。 大阪府の面積は1900km2である。 徳島県の面積は4100km2である。
関連度 4位 2015年の静岡県の人口は370万人です。 2015年の京都府の人口は261万人です。 福島県の面積は13700km2である。
関連度 5位 長崎県の面積は4100km2である。 大分県の面積は6300km2である。 長崎県の面積は4100km2である。

Q2は都道府県の面積に関する質問であり、関連度1位はその都道府県の面積、
それ以下は適当な都道府県の面積となっている。  

Q3に対する関連度

質問文 茨城県京都府ではどちらが大きいですか? 千葉県と島根県ではどちらが大きいですか? 東京都と静岡県ではどちらが大きいですか?
関連度 1位 茨城県の面積は6000km2である。 千葉県の面積は5100km2である。 東京都の面積は2100km2である。
関連度 2位 京都府の面積は4600km2である。 島根県の面積は6700km2である。 京都府の面積は4600km2である。
関連度 3位 宮城県の面積は7200km2である。 三重県の面積は5700km2である。 静岡県の面積は7700km2である。
関連度 4位 2015年の茨城県の人口は291万人です。 栃木県の面積は6400km2である。 大阪府の面積は1900km2である。
関連度 5位 東京都の面積は2100km2である。 熊本県の面積は7400km2である。 愛媛県の面積は5600km2である。

Q3は2つの都道府県を比べてどちらが大きいかを尋ねる質問である。
関連する2つの都道府県の面積に対する知識が最上位にくるのが理想である。
上表左、中央はそのとおりとなっているが、一番右の東京都と静岡県の比較だけは
静岡県の面積を表す知識文章の関連度が3位となっており、 理想からはずれた結果となっている。
(BERTのtokenizer的に東京都と京都府が関連しやすいため?)

Q4に対する関連度

質問文 1935年から1990年で京都府の人口は変わっていますか? 1920年から1965年で島根県の人口は変わっていますか? 2005年から2010年で徳島県の人口は変わっていますか?
関連度 1位 1935年の京都府の人口は170万人です。 1920年島根県の人口は71万人です。 2010年の徳島県の人口は78万人です。
関連度 2位 1935年の東京都の人口は636万人です。 1920年広島県の人口は154万人です。 2005年の徳島県の人口は80万人です。
関連度 3位 1995年の京都府の人口は262万人です。 1920年の鹿児島県の人口は141万人です。 2015年の徳島県の人口は75万人です。
関連度 4位 1940年の京都府の人口は172万人です。 1920年徳島県の人口は67万人です。 2000年の徳島県の人口は82万人です。
関連度 5位 1930年の京都府の人口は155万人です。 1920年福島県の人口は136万人です。 2010年の福島県の人口は202万人です。

Q4はある都道府県の2つの年の人口の増減を答える質問であり、
その都道府県の対応する年の人口が関連する文章である。
結果は関連度1位の文章に関しては正しく予想できているが、
関連度2位の予測は少し間違っている。

Q3と同様に複数の知識が関連する文章に対する関連度の予測はやや難易度が高いと思われる。

まとめ

今回は都道府県統計情報文章に対するDPRの学習と評価を行った。
単純な文章に関しては関連度の予測が正しくできていたが、 関連する文章が増えると
難易度が上昇することが分かった。

今後はこのモデルを利用してRAGの学習を行いたい。

参考文献

制御可能な文章生成RAG - 学習用データ作成

はじめに

前回調査したRAGを学習するための単純なデータセットを作成した。

RAGのためのデータセット

RAGは入力文章に対して、知識を用いて出力文章を生成するモデルである。
RAGは内部的にはDPRBARTという2つのモデルからなり、DPRは知識の
retrieve(検索)を行い、 BARTはseq2seqにより文章の生成を行う。

元のRAG論文では TriviaQA1, Natural Questions2の2つのデータセットでDPRを
事前学習してから、 DPRのquery encoder部分とBARTを同時に最適化している。

今回RAGの挙動を理解するための単純なデータセットを作成する。

都道府県統計データ

知識文章

政府が公開している情報

人口統計
面積

から、都道府県ごとの面積、年代ごとの人口をtableデータ化して、
そこから知識文章を作成する。

知識文章例
都道府県 種類 面積 知識 年代 人口
45 鹿児島県 面積 9100 鹿児島県の面積は9100km2である。 nan nan
46 沖縄県 面積 2200 沖縄県の面積は2200km2である。 nan nan
48 北海道 人口 nan 1920年の北海道の人口は235万人です。 1920 235
49 青森県 人口 nan 1920年青森県の人口は75万人です。 1920 75
50 岩手県 人口 nan 1920年岩手県の人口は84万人です。 1920 84

都道府県の面積と五年ごとの人口から計986個の知識文章を作成した。

質問・回答文章

知識文章を元に質問・回答文章ペアを作成する。

文章ペアは以下のアルゴリズムで生成する。

  • Q1: Aの人口はX万人くらいですか? (2015年基準)。
    • X万人くらいです。 (-20% ~ +20%)
    • X万人よりも少ないです。(< -20%)
    • X万人よりも多いです。(> +20%)
  • Q2 : Aの面積はX km2よりも大きいですか?
    • X km2くらいです。 (-20% ~ +20%)
    • X km2よりも大きいです。 ( > +20%)
    • X km2よりも小さいです。 (< -20%)
  • Q3 : AとBではどちらが大きいですか?
    • 同じくらいです。 (-20% ~ +20%)
    • Aのほうが大きいです。
    • Bのほうが大きいです。
  • Q4 : X年からY年でAの人口は変わっていますか?(Y > X)
    • 同じくらいです。 (-20% ~ +20%)
    • 増えています。 ( > +20%)
    • 減っています。 (< -20%)

このようなアルゴリズムで3428個の質問・回答文を生成した。

質問・回答文章例
種類 質問 回答
3187 Q4 1920年から1970年で熊本県の人口は変わっていますか? 増えています。
702 Q3 佐賀県と石川県ではどちらが大きいですか? 石川県のほうが大きいです。
310 Q2 鳥取県の面積は18609km2くらいですか? 18609km2よりも小さいです。
467 Q3 千葉県と三重県ではどちらが大きいですか? 同じくらいです。
45 Q1 千葉県の人口は494万人くらいですか? 494万人よりも多いです。
1337 Q4 1935年から1985年で埼玉県の人口は変わっていますか? 増えています。
2705 Q4 1925年から1985年で山口県の人口は変わっていますか? 増えています。
1599 Q4 1955年から1980年で新潟県の人口は変わっていますか? 同じくらいです。
391 Q3 青森県富山県ではどちらが大きいですか? 青森県のほうが大きいです。
1696 Q4 1925年から1955年で石川県の人口は変わっていますか? 増えています。

DPR用のデータ

transformers3にはDPRの学習例はなかったが、 FacebookのDPRの実装4には
学習方法が記載されていた。

学習データは以下のjson形式で記述する必要がある。

[
  {
    "question": "....",
    "answers": ["...", "...", "..."],
    "positive_ctxs": [{
        "title": "...",
        "text": "...."
    }],
    "negative_ctxs": ["..."],
    "hard_negative_ctxs": ["..."]
  },
  ...
]

'question', 'answers'は今回作成した質問・応答文で良い。
その他の要素はこの質問・回答ペアに関連する情報であり今回は
知識文章から選ぶこととする。

  • positive_ctxs は質問・回答文生成に利用した知識
  • negative_ctxsは質問・回答文に関係ない都道府県の知識
  • hard_negative_ctxs は関連する都道府県の利用していない知識
{'question': '1975年から2010年で沖縄県の人口は変わっていますか?',
 'answers': ['増えています。'],
 'positive_ctxs': [{'title': '', 'text': '1975年の沖縄県の人口は104万人です。'},
  {'title': '', 'text': '2010年の沖縄県の人口は139万人です。'}],
 'negative_ctxs': [{'title': '', 'text': '1995年の佐賀県の人口は88万人です。'},
  {'title': '', 'text': '1995年の和歌山県の人口は108万人です。'},
  {'title': '', 'text': '1940年の山形県の人口は111万人です。'}],
 'hard_negative_ctxs': [{'title': '', 'text': '1955年の沖縄県の人口は80万人です。'},
  {'title': '', 'text': '1980年の沖縄県の人口は110万人です。'},
  {'title': '', 'text': '1970年の沖縄県の人口は94万人です。'}]}

まとめ

今回はRAG学習のためのテストデータセットの作成を行った。
次回はDPRの学習を行いたい。

参考文献

制御可能な文章生成RAG - 技術概要

はじめに

蓄えられた知識を元に文章生成を行うTransformerモデル
Retrieval-augmented generation (RAG)の技術について調査した。

Deep Learning による文章生成

T5, GPT-3などのDeep Learningを用いたモデル1は一見すると
人間に近い性能の文章を生成できる。
しかしながら、それらのモデルはいくつか問題を抱えている。

  • 知識と文法を一つのモデルで学習
    • 間違った知識で自然な文章が生成される可能性あり (Fake news)
  • 追加学習が難しい
    • 新たな知識が増えた場合のモデル更新が難しい
  • 出力結果の説明が難しい

これに対してRAGはモデルの外にある知識を利用して文章を生成する。
具体的には、外部知識として文章群を用意し、文章を生成するときはその中から
関連する文章を選び、それらを元に文章を出力する。

RAG

RAGはT5と同様に文章を入力として文章を出力するモデルである。
(出力文章をクラスとすれば分類問題にも使える)

RAGは内部的にはDPR (Retriever)とBART (Generator)の2つのモデルを利用している。
transformers2ライブラリに実装済み。
https://huggingface.co/transformers/model_doc/rag.html

概念図

f:id:nakamrnk:20201019093305j:plain

DPRは文章間の関連度を求めるためのネットワークであり、 これにより
知識文章群から入力文章に関連する文章とその特徴量を抜き出す。
BARTは元の入力とDPRが出力した特徴量から文章を生成する。

これにより、出力された文章に対して知識文章群のどの文章が関連するかが
明確となるため、判定の根拠が示しやすい。 また、知識群に不適切なものや古い知識が
含まれていた場合にそれらを取り除くことで、間違った出力が抑制されることが期待される。

RAGの利用

RAGは前述した通り、良い性質を備えたモデルであるが、 入出力文章データを
用意するだけで学習ができるBARTやT5よりもモデル作成に必要なものが多い。

知識文章の用意

RAGの論文では知識文章としてWikipediaの文章を100単語ごとに区切ったものを使用している。
膨大な質の低いデータが良いのか、数は少ないが質の高いデータが良いのかは検証の余地がある。

DPRの学習

DPRは知識群から特徴量を抽出するEpと入力文章から特徴量を抽出する
Eqの2つのエンコーダからなるモデルである。 RAG論文ではRAGの学習中はDPRの
Epは固定してEq部分のみをfine-tuningしているので、RAGを学習するためには
DPRの事前学習モデルが必要となる。

まとめ

RAGの論文を読み、技術概要をまとめた。
学習は大変そうだが、うまく使えば制御のしやすい文章生成モデルとなり、
面白いことができそうだと思った。
とりあえず単純なデータセットを作って学習し、挙動を理解したい。

参考文献

XAIについての検証 - 手法比較

はじめに

前回までいくつかのXAI手法の検証を行ってきた。
今回はそれらの手法を比較するコードを実装し、githubに公開した。
https://github.com/NeverendingNotification/pytorch-xai-analyze

このコードを用いていくつかの状況で各XAIアルゴリズムの挙動を検証した。

比較したアルゴリズム

  • Anchors1
  • SHAP2
  • Grad-CAM3

初期値依存性

Deep Learningの学習結果はネットワーク重み初期値にある程度依存する。
XAIアルゴリズムの初期値依存性を見るために、 乱数SEED以外のパラメータを
固定して数回学習し、 XAIの可視化結果を比較した。

学習曲線 (評価データ)

f:id:nakamrnk:20201017064850j:plain

精度 (評価データ)

class-F run1 run2 run3
T-shirt/top 0.872945 0.867698 0.870871
Trouser 0.987443 0.985915 0.98542
Pullover 0.897 0.891337 0.897654
Dress 0.921944 0.92323 0.924303
Coat 0.869186 0.880193 0.88101
Sandal 0.978894 0.979879 0.980529
Shirt 0.766631 0.765803 0.771222
Sneaker 0.962451 0.961727 0.959334
Bag 0.986028 0.988 0.985522
Ankle boot 0.972348 0.970707 0.965377
mean-F 0.921487 0.921449 0.922124
acc 0.9221 0.9218 0.9225

評価データに対する性能的には初期SEEDごとのブレはほぼ存在しない。

XAI結果比較 (Ankle bootクラス)

f:id:nakamrnk:20201017064713j:plain

4行ずつ一組で(元画像、Anchors, SHAP, Grad-CAM)。
上から順にrun1, run2, run3。

  • Anchorの挙動はrunごとにややぶれているが、靴底の窪んでいる部分と正面部分に反応しているものが多い。
  • SHAPは共通してつま先付近(+かかとも?)に強く反応している。
  • Grad-CAMは共通して靴の正面部分に反応している。

モデル初期値によってXAIアルゴリズムの挙動が大きく変わることはないようだ。

ネットワークのパラメータ数依存

ネットワークの複雑さによってXAIの挙動が変化するか検証した。
変更したパラメータは

  • チャンネル数 (model.feature.c0)
    • (16, 32, 64, 128)
  • 層数 (model.feature.num_layres)
    • (2, 3 ,4)

はデフォルト値。

チャンネル数比較

学習曲線 (評価データ)

f:id:nakamrnk:20201017070633j:plain

精度 (評価データ)
class-F channel_16 channel_32 channel_64 channel_128
T-shirt/top 0.856566 0.872945 0.878073 0.885328
Trouser 0.981891 0.987443 0.988978 0.989442
Pullover 0.873657 0.897 0.898709 0.905698
Dress 0.910366 0.921944 0.924988 0.937406
Coat 0.861098 0.869186 0.886608 0.906126
Sandal 0.974975 0.978894 0.981379 0.987976
Shirt 0.746842 0.766631 0.793354 0.799401
Sneaker 0.957594 0.962451 0.969966 0.96895
Bag 0.982491 0.986028 0.98854 0.989033
Ankle boot 0.965169 0.972348 0.974333 0.972152
mean-F 0.911065 0.921487 0.928493 0.934151
acc 0.9111 0.9221 0.9289 0.9341

チャンネル数は増加するほど性能が向上している。

XAI結果比較 (Ankle bootクラス)

f:id:nakamrnk:20201017072520j:plain

上から順にチャンネル数(16, 32, 64, 128)。
全体の傾向としてはどのアルゴリズムも多くは変わっていない。

層数比較

学習曲線 (評価データ)

f:id:nakamrnk:20201017073148j:plain

精度 (評価データ)
class-F layers_2 layers_3 layers_4
T-shirt/top 0.821782 0.872945 0.889555
Trouser 0.972039 0.987443 0.990964
Pullover 0.82341 0.897 0.907023
Dress 0.856865 0.921944 0.945744
Coat 0.778786 0.869186 0.909
Sandal 0.940759 0.978894 0.986987
Shirt 0.66242 0.766631 0.807771
Sneaker 0.92137 0.962451 0.971852
Bag 0.960716 0.986028 0.987026
Ankle boot 0.942799 0.972348 0.973764
mean-F 0.868095 0.921487 0.936969
acc 0.8687 0.9221 0.9372

層数が増加するほど性能が向上している。

XAI結果比較 (Ankle bootクラス)

f:id:nakamrnk:20201017073457j:plain

上から順に層数 2, 3, 4。

Anchorsの挙動

層数を増やすほど反応箇所が減少している。
Anchorsの反応箇所はその部分を残すと予測結果があまり変わらない
superpixels領域を示しているため、層数が増加し、視野の広い特徴を
獲得するほどに、ローカルなsuperpixelsに対しての依存度が下がっている
ためと思われる。 解釈性という観点ではあまりよくないため、
superpixelsのとり方を考えるなど対策が必要。

SHAPの挙動

層数2の場合、つま先やかかと付近に強く反応している。
層数が増えると特定箇所への反応は弱くなり、正面付近の輪郭
全体に分布するようになる。 Anchorsと同様画像の特定部位への
依存性が落ちているためと思われる。

Grad-CAMの挙動

Grad-CAMは全てのパラメータで2層目の特徴マップを可視化している。

2層モデルの場合可視化している層は最終層であり、 靴の履き口、
正面、つま先など凹んでいる局所構造に反応している。
3層モデルの場合は靴正面のライン上に反応している。

4層モデルの場合はGrad-CAMが消滅しているものがある。
これはGrad-CAMが特徴量マップの重み付け和をとったあとに
ReLUを通すため、得られたマップ全体が負値ならば0となってしまうためである。
(最終層(4層目)を可視化する場合はこのような挙動はしないはず)
潰れていないマップを見るためには最終層を可視化するほうが良いが、
解像度がさらに落ちるため、局所性は失われる。

まとめ

各XAIアルゴリズムの挙動を比較した。
チャンネル数を増やした場合はあまり挙動が変わらないのに、
層数を変えると挙動が大きく変わるのはおもしろいと思った。
ネットワークのアーキテクチャや問題を変えた場合の挙動も理解したい。

参考文献

XAIについての検証 - Grad-CAM

はじめに

前回前々回に引き続きfashion-mnistデータについてXAIの検証を行う。
今回はGrad-CAMについて検証した。

Grad-CAM

Grad-CAMはXAIアルゴリズムのひとつであり、
特定のクラス予測に対する特徴量マップの勾配から計算した重みで
特徴量マップの重み付け和を求めることで、そのクラス予測が
画像のどの部分を元に行われているかを可視化する手法である。

Grad-CAMはXAIだけでなく他の分野でもAttention mapとして利用されている。

  • 人物識別1
  • 異常検知2
  • 弱教師ありSegmentation3

検証

実装はpytorch-gradcamを利用した。

可視化層選択

Grad-CAMにおいてはNeural Netのどの層を可視化するかという自由度
が存在する(Global Average Pooling前の畳み込み層がよく利用される印象)。

今回検証するモデルは畳み込み層3層から構成されており、
活性化関数の前後も含めると6箇所特徴量マップの候補が存在する。
(BN前後を考慮すると9だが、今回はBN後の特徴量マップのみを考える)。

以下はSandal クラス画像における各特徴量マップに対するGrad-CAMである。

f:id:nakamrnk:20201014095432j:plain

一番上の画像は元画像であり、その下に1層目のActivationの前後、
2層目のActivationの前後、 3層目のActivationの前後に対するGrad-CAMを表示している。

1層から順に特徴量マップの解像度が下がり、抽象化されているためGrad-CAMも
ぼやけていく。 1層は入力画像との差異が小さく、3層は解像度が低すぎるため、
今回は2層のactivation前の特徴量マップを解析に利用する。

Bagクラス

f:id:nakamrnk:20201014100353j:plain

最上段は元画像、それ以下は予測クラス上位1, 2, 3位のクラスに対するGrad-CAMである。
Bag予測に対するGrad-CAMの傾向を観察すると、持ち手部分やバッグ上端のたいらな部分に
強く反応している。 AnchorsやSHAPよりノイズも少なく理解しやすいと感じる。

Trouser クラス

f:id:nakamrnk:20201014100820j:plain

Trouserクラスにおいては、股下部分や裾部分に反応しており、 正しい特徴を捉えられている。

靴クラス

Sandalクラス

f:id:nakamrnk:20201014101406j:plain

Sneakerクラス

f:id:nakamrnk:20201014101418j:plain

Ankle bootクラス

f:id:nakamrnk:20201014101432j:plain

  • Sandalクラスは紐や隙間に反応している
    • SHAPと似た傾向
  • Sneakerクラスは靴の正面部分に反応しているものが多い
    • SHAPと同様はっきりしないものも多い
  • Ankle bootは靴正面ラインに反応している

前回のSHAPはAnkle bootクラスのつま先付近に反応していたが、
今回のGrad-CAMはどちらかというと正面ラインに反応しているように見える。
画像解像度を下げて広いコンテクストを扱えるGrad-CAMとピクセル単位の
勾配をみているSHAPでは解釈が異なるようだ。
複数のXAI手法を比較し、違いを見ることでモデルの予測傾向をつかめるかもしれない。

トップスクラス

トップスクラスは2層のActivation後の特徴量マップを採用した。
(Activation前のGrad-CAMが見づらかった)

T-shirt/top

f:id:nakamrnk:20201014104817j:plain

Pullover

f:id:nakamrnk:20201014104841j:plain

Dress

f:id:nakamrnk:20201014104852j:plain

Coat

f:id:nakamrnk:20201014104903j:plain

Shirt

f:id:nakamrnk:20201014104922j:plain

  • T-shirt/topクラスは全体的にぼやけているが、首や胸、袖下などに反応しているものもある
  • Pulloverクラスもぼやけているが、左袖の端に反応しているものが多い
  • Dressクラスは左右のボディラインに反応
  • Coatクラスは首元と下端に反応
    • Coatは袖が胴よりも下まで伸びているものが多いのでそれを特徴と捉えている?
  • Shirtクラスは正面部分に反応

Dress, Coatクラスはある程度人間にも理解できる反応箇所だが、
性能の低いShirtクラスは分かりづらい結果となっている。
他のXAI手法でも人間の感覚に合わなかったため、 モデル自体が
あまり良い特徴を捉えられていない可能性がある。   

まとめ

今回はGrad-CAMについて検証を行った。
見栄え自体はAnchorsやSHAPよりも良いと感じたが、
最終層を特徴量マップとすると解像度が低いため、局所的な特徴を議論したい
場合は入力に近い層を特徴量マップとして採用したり、
他の手法とも比較する必要があると感じた。

参考文献