GPT-2でスピッツの次なるタイトルを創造して、妄想する

## 好きなもの × 気になる技術 = ワクワク

### はじめに
唐突ですが、4人組バンドの**スピッツ**が好きです:relaxed:
1987年に結成し、今年でデビュー30周年になります。
ここはプログラマのための技術情報共有サービス、**Qiita**なので、彼らの魅力には触れません。
気になった方は今すぐYouTubeをcheckしましょう。

一方、2020年に発表された文章生成のモデルの**GPT-3**の論文["Language Models are Few-Shot Learners"](https://arxiv.org/abs/2005.14165)
を眺めていると最近の文章生成は何やら楽しそうです（主観）。
GPT-3はOpen AIが提案した1750億個という膨大なパラメータを用いて構築された言語モデルです。
東大の松尾先生は[こちらの記事](https://ledge.ai/matsuo-new-years-impression2021/)でGPT-3を**2020年の大きなトピックの1つ**として取り上げています。

このモデルはFew-Shot leaning、タスクの記述と2,3のサンプルを示すことで、そのタスクに対応する（ファインチューニングはしない）学習方法で、高い性能を示しました。
![few-shot.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684711/4e430a6b-2ac8-f244-9245-d8eab28548d5.png)
またもや松尾先生が紹介されていますが、[別の記事](https://ledge.ai/chugai-digital-day/)で技術者のマヌエル・アラオスさんの[ブログ](https://maraoz.com/2020/07/18/openai-gpt3/)の文章が実はGPT-3によって生成された文章だったことがブログの後半で紹介され、その文章の自然さは衝撃的だったようです（英語がよくわからないので、どれくらい自然な文章かちょっとよくわからない）。


### 本当はGPT-3を試したかったけど、GPT-2にトライ

文章生成のモデルの動向を見ているうちに
**スピッツの次なる曲/アルバムタイトルが生成できるのでは!?**
というアイディアが頭をもたげてきます。

OpenAIの[サイト](https://openai.com/blog/openai-api/)で「JOIN THE WAITLIST」で登録すれば、
GPT-3のAPIが試せるようなのですが、
登録に少し抵抗がある＆どなたかのブログで「WAITLISTを登録したが、回答が返ってこない」と見かけ、まずはGPT-3の前のバージョンのGPT-2を試すことにしました。

![waitlist.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684711/738d5647-e158-c945-8f1c-9218c95b79e8.png)

GPT-3とGPT-2の構築方法は基本的に同じで、パラメータ数が異なると言われています。
（違っていたらすみません。いつかはGPT-3を試したい）

### データ準備
以下の情報をwikipediaから手で拾い上げ、「あ～この曲最近聴いてない」と思いながら1行1曲をコピペしながら学習データ(261件,songs.txt)を作成しました。

![songs.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684711/a69e5381-4d1a-7933-27d1-7c38ecbce96e.png)

学習で用いたのは以下のタイトルです。

* シングル曲
* アルバム/ミニアルバムのタイトル
* アルバム/ミニアルバムの曲

シングル曲だけで学習しようとしならおそらくデータ数が少なく上手く学習できなかったので、情報を増やすことにしました。
**「シングル曲のカップリングは？」**と気づいた方、ご安心ください。
**アルバム『花鳥風月(1999)』、『色々衣(2004)』、『おるたな(2012)』**でカバーしました！（収録されてないカップリングがもしかしてある？）。
このアルバムを含めると厳密にはカバー曲（『おるたな』に収録されているユーミンのカバー「14番目の月」など）も
含まれますが、そこは「スピッツ寄りの曲（？）」として学習に含めました。
学習データを一つでも増やしたかった、というのも理由の一つです。

### 早速試す

開発環境は**Google Colab**で、GPUを利用した状態で動作を試しました。
Qiitaの[【GPT2】AIにラノベのタイトルを作らせてみる](https://qiita.com/atsonic/items/802ce98c127b4960dd93)を全面的に参考し、日本語版の[GPT2-Japanese](https://github.com/tanreinama/gpt2-japanese)を使用しました。

#### データを加工

学習をさせるためには、上記で作成した学習データを一部加工する必要があります。
末尾を表すトークンである「
」をつけます。
文末の改行("\n")を文末トークン("
")に変換して加工しdataset.txtを作成しました。

```
f = open('dataset/songs.txt', 'r')

datalist = f.readlines()
song_list = []
for i in datalist:
  song_list.append(i.replace("\n","
"))

with open("dataset.txt", 'wt') as f:
  for ele in song_list:
    f.write(ele+'\n')
```
datasetフォルダを新規作成(mkdir)し、このdataset.txtをコピーしておきます。

### git clone & インストール

```
!git clone https://github.com/tanreinama/gpt2-japanese

#gpt2-japaneseのフォルダに移動
%cd gpt2-japanese
!pip uninstall tensorflow -y
!pip install -r requirements.txt
```
### モデルをゲット

モデルデータをコピーして解凍します。
（こちらの[記事](https://qiita.com/atsonic/items/802ce98c127b4960dd93)によると、
  smallじゃないとcolab上で動作しないようなので、**small**を使用しました）

```
!wget https://www.nama.ne.jp/models/gpt2ja-small.tar.bz2
!tar xvfj gpt2ja-small.tar.bz2
```

### データセットをエンコード
```
#エンコーダーをクローン
!git clone https://github.com/tanreinama/Japanese-BPEEncoder.git

#ディレクトリ移動
%cd Japanese-BPEEncoder/

#エンコード（src_dirにはデータセットのディレクトリを指定、dst_fileはエンコード後のファイル名を指定します）
!python encode_bpe.py --src_dir dataset --dst_file finetune
```
この処理でエンコード完了するとfinetune.npzが生成されます。
このデータを用いてファインチューニングを行っていきます。

こちらの[記事](https://qiita.com/atsonic/items/802ce98c127b4960dd93)では、ファイル構成やgoogle driveにfinetune.npzにコピーしておくことでエンコード処理を飛ばせる旨を丁寧に説明されているので、ここでは少し省略します。

### ファインチューニング
gpt2-japaneseの中のrun_finetune.pyを用いてファインチューニングを実行します。

```
#fine tuning実行（base_modelは元になるモデル、datasetはエンコードファイル、run_nameは生成後のモデルデータ名）
!python run_finetune.py --base_model gpt2ja-small --dataset finetune.npz --run_name gpr2ja-finetune_run1 --batch_size 1
```

学習をしていくと、ロスが表示されます。
![fineturning.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684711/a8ecff31-f48b-cdba-d185-9337dd278da8.png)

どこで学習を終えれば良いかわかりませんが、しばらくロスが0になった段階で学習を中断しました。

### いざ生成
gpt2-generate.pyを用いて、先程作成したモデルデータ(gpr2ja-finetune_run1)を用いて、
100種類の生成を試みました。出力結果を"title.txt"に保存しました。

```
!python gpt2-generate.py --model checkpoint/gpr2ja-finetune_run1 --num_generate 100 --output_file "title.txt"
```

### 結果考察

100種類の生成結果を確認すると、学習データに含まれているタイトルもちょくちょく出力されていました。
学習データに含まれていなかった生成結果を以下に列挙しながら、勝手に考察をしていきます。

|  生成結果|  勝手に考察  |
| ---- | ---- |
| 'ないと思う。あわて' |  'あわて'とは・・？ |
| 'イジり。イジり・る' | シングル『さわって・変わって(2001)』を想起するようなしないような |
|'ローテク・ラヴ' | アルバム『三日月ロック(2002)』の収録曲『ローテク・ロマンティカ』の変化形っぽい|
|'旅に出る' | シングル『魔女旅に出る(1991)』の一部、あるいはシングル『僕はきっと旅に出る(2013)』の一部　|
|'死神泥棒' |デビューアルバム『スピッツ(1991)』の収録曲『死神の岬へ』とアルバム『インディゴ地平線(1996)』の収録曲『花泥棒』の組み合わせ |
|'砂漠の惑星' | アルバム『さざなみCD(2007)』の収録曲『砂漠の花』とシングルもしくはアルバム名『惑星のかけら(1992)』の組み合わせ |
|'砂漠の青い車' | アルバム『さざなみCD(2007)』の収録曲『砂漠の花』とシングル『青い車(1994)』の組み合わせ |
|'笑う'| アルバム『インディゴ地平線(1996)』の収録曲『夕陽が笑う、君も笑う』の一部 |
|'虫が怖い'| ・・・どうした急に？ |
|'虫けらの暮つを'| 「暮つ」ってどこかの方言？「虫けら」という単語はタイトルにないぞ |
|'頬に咲いた黄色い花'|シングル『冷たい頬(1998)』とアルバム『名前をつけてやる(1991)』の収録曲『胸に咲いた黄色い花』の組み合わせ |
|'魔女旅'|  シングル『魔女旅に出る(1991)』の略語？ |

とこのような結果でした。
結果を見ながらスピッツは**虫**関連の曲が多いことに気づきました。

* 鈴**虫**を飼う(1991)
* 宇宙**虫**(2000)
* 夢追い**虫**(2001)
* 花と**虫**(2019)

虫関連の曲を作り続けた結果、いつか**虫が怖い**というタイトルの曲がリリースされるやも・・

その他、スピッツには**旅**がつくタイトルも多いことに気づきました。

* 魔女**旅**に出る(1991)
* **旅**人(1996)
* **旅**の途中(2002)
* 僕はきっと**旅**に出る(2013)


**魔女旅**のようなタイトルはなさそうですが、**旅**がつくタイトルがリリースされるやも・・

### まとめ

GPT-2を用いて、スピッツのタイトルを生成する試みをしてみました。
ちなみにこのブログを書くにあたり、学習を複数実施し、その度に全然違う答えが返ってきました。
ですので、今回の推論及び考察はあくまで**趣味の範囲**として暖かい目で見て頂ければ幸いです。

### 参考にした記事
ありがとうございました！

* [【GPT2】AIにラノベのタイトルを作らせてみる](https://qiita.com/atsonic/items/802ce98c127b4960dd93)
* Ledge.aiの記事:[松尾豊さん、2020年の大きなトピックの1つは「GPT-3」](https://ledge.ai/matsuo-new-years-impression2021/)
* Ledge.aiの記事:[AI研究の松尾豊さん、時代を切り開くのは新しい武器を持った挑戦者](https://ledge.ai/chugai-digital-day/)
* GPT-3の[論文](https://arxiv.org/abs/2005.14165)