RNNによるツイートの自動生成
授業で「Deep Learningを使って何か作る」という課題を与えられました。チーム開発なのですが、知らないうちにテーマがツイートの自動生成に決まっていたので実装をやりました。発表内容は以下のスライドを見てください。
以下、実装の詳細を説明します。
使ったコードはkivantium/rnn-twitter · GitHubに置いてあります。
github.com
char-rnn (Keras)
char-rnnはKarpathyがThe Unreasonable Effectiveness of Recurrent Neural Networksで紹介したことで有名になり、各種フレームワークに移植されているLSTMの有名なモデルです。モデルの説明はKarpathyの記事を読んでください。
Kerasを使いたかったのでkeras/lstm_text_generation.py at master · fchollet/keras · GitHubを元に実装しました。
かな漢字混じりの文章をそのまま学習させたところ意味のある文章が生成されなかったので、入力文字列を全てカタカナにする前処理を行いました。
漢字の読みを取り出す (Mecab, Python)
MeCabの辞書としてmecab-ipadic-neologdを使いました。(過去記事)
Pythonバインディングはsudo apt-get install python-mecab
で入ります。
MeCabで形態素解析を行うと読み情報が得られるので以下のようなコードで取り出します。
#!/usr/bin/env python # -*- coding: utf-8 -*- import MeCab mt = MeCab.Tagger("-Ochasen -d /usr/lib/mecab/dic/mecab-ipadic-neologd") mt.parse('') text = 'あらゆる現実をすべて自分のほうへねじ曲げたのだ。' node = mt.parseToNode(text) node = node.next data = '' while node: if node.next: data += node.feature.split(',')[-2] node = node.next print data
結果は
アラユルゲンジツヲスベテジブンノホウヘネジマゲタノダ。
となります。
辞書に読みが入っていないと*
になるので気になる人は手動で取り除いてください。
Pythonのエンコーディングは厳しいのでうまくいかなかったら頑張ります。
Yahooのかな漢字変換APIを使う (Python)
かな漢字変換を自分で実装するのはつらいのでYahooのAPIを使いました。
テキスト解析:かな漢字変換 - Yahoo!デベロッパーネットワーク
利用するにはアプリケーションIDが必要なのでご利用ガイド - Yahoo!デベロッパーネットワークに従って取得します。
カタカナからひらがなの変換はjaconvを使いました。GitHub - ikegami-yukino/jaconv: Pure-Python Japanese character interconverter for Hiragana, Katakana, Hankaku and Zenkaku
また、XMLの解析にはBeautifulSoupを使いました。Beautiful Soup Documentation — Beautiful Soup 4.4.0 documentation
どちらもpipで入ります。
#!/usr/bin/env python # -*- coding: utf-8 -*- import jaconv import requests from bs4 import BeautifulSoup text = u'アラユルゲンジツヲスベテジブンノホウヘネジマゲタノダ。' hira = jaconv.kata2hira(text) yahoo_url = "http://jlp.yahooapis.jp/JIMService/V1/conversion" appid = 'PUT YOUR ID HERE' parameter = {'appid': appid, 'sentence': hira, 'results': 1} r = requests.get(yahoo_url, params=parameter) soup = BeautifulSoup(r.text) sentence = '' for word in soup.find_all('candidatelist'): sentence += word.find('candidate').text print(sentence)
出力は
あらゆる現実をすべて自分の方へねじ曲げたのだ。
となります。
ここまでの機能で適当な文章が作れます。
データセットとしてはYJ Captions 26k Datasetの説明文を抜き出して使いました。
文章を作るだけではbotとしての面白みに欠けるので画像を生成しようと思いました。
運の良いことにMS COCOの説明文からGANで画像を生成する研究があり、コードと学習済みデータが公開されているのでそれを使おうと思いました。
GitHub - reedscot/icml2016: Generative Adversarial Text-to-Image Synthesis
しかし、この研究は英語から画像を生成しているので生成した日本語から英語にする必要があります。
Microsoftの翻訳APIを使う (Python?)
Google翻訳APIは有料だったのでMicrosoftのAPIを使います。
使い方についてはたくさんの解説記事がありますが、最近仕様が変わったらしくほとんどの記事は今では使えない方法でした。
見つかった中で唯一動いた自動要約&ニューラルネット翻訳で海外の記事を読みやすくするSlackBot - Qiitaに従いました。
Cognitive Services - Text Translationに従ってkeyを取得します。
#!/usr/bin/env python # -*- coding: utf-8 -*- import subprocess from bs4 import BeautifulSoup def popen(cmd): outputs = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = outputs.communicate() return stdout text = 'あらゆる現実をすべて自分の方へねじ曲げたのだ。' token_url = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken" translate_url = "https://api.microsofttranslator.com/v2/http.svc/Translate" KEY = 'YOUR KEY HERE' CATEGORY = "generalnn" request_token = popen('curl -X POST \"{url}\" -H \"Content-type: application/json\" -H \"Content-length: 0\" -H \"Accept: application/jwt\" -H \"Ocp-Apim-Subscription-Key:{key}\"'.format(url=token_url, key=KEY)) result = popen( "curl -X GET --header \'Accept: application/xml\' \'{url}?appid=Bearer%20{token}&text={text}&from=ja&to=en&category={category}\'".format( url=translate_url, token=request_token, text=text, category=CATEGORY)) soup = BeautifulSoup(result) print(soup.string)
出力は
All the realities were screwed towards myself.
となります。
さすがにこの方法は汚い気がしますがDone is better than perfectと唱えて次に進みます。
GANによる画像の生成 (Torch, AWS)
GitHub - reedscot/icml2016: Generative Adversarial Text-to-Image SynthesisをAWSで動かしました。
- READMEのリンクから
COCO caption data in Torch format
とCOCO GAN-CLS
をダウンロード CONFIG
のファイルの位置を書き換えるscripts/coco_queries.txt
に画像を生成したい英文を入れる./scripts/demo_coco.sh
を実行して画像を生成する
うまくいくと
みたいな画像が出来ます。
こうして得た日本語文と、対応する画像をれんと (@licarent) | Twitterに流しています。
うまくいった例を貼り付けておきます。
芝生の上に花が生けられています。 pic.twitter.com/aqBqr1sJzq
— れんと (@licarent) 2017年1月20日
スキーヤーがジャンプしています。 pic.twitter.com/yAwRL4h5ca
— れんと (@licarent) 2017年1月21日
男性が、テニスラケットを持っています。 pic.twitter.com/Si2wPBgbMR
— れんと (@licarent) 2017年1月21日
RNNが生成する日本語文はいまいちで、GANが生成する画像はさらにいまいちなのですが、今の僕の技術レベルだとこれくらいが限界でした。
もっと面白いbotを作りたいものです。