kivantium活動日記

プログラムを使っていろいろやります

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は有料だったのでMicrosoftAPIを使います。
使い方についてはたくさんの解説記事がありますが、最近仕様が変わったらしくほとんどの記事は今では使えない方法でした。
見つかった中で唯一動いた自動要約&ニューラルネット翻訳で海外の記事を読みやすくする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 SynthesisAWSで動かしました。

  • READMEのリンクからCOCO caption data in Torch formatCOCO GAN-CLSをダウンロード
  • CONFIGのファイルの位置を書き換える
  • scripts/coco_queries.txtに画像を生成したい英文を入れる
  • ./scripts/demo_coco.shを実行して画像を生成する

うまくいくと
f:id:kivantium:20170121141048p:plain
みたいな画像が出来ます。

こうして得た日本語文と、対応する画像をれんと (@licarent) | Twitterに流しています。

うまくいった例を貼り付けておきます。



RNNが生成する日本語文はいまいちで、GANが生成する画像はさらにいまいちなのですが、今の僕の技術レベルだとこれくらいが限界でした。
もっと面白いbotを作りたいものです。

広告コーナー