【ディープラーニング】DCGANでポケモンのドット絵を生成してみた【Tensorflow】

はじめに

Deep Learningのネタ系記事はn番煎じではありますが一応記録として。
DCGANはDeep Convolutional Generative Adversarial Networksの略で、画像なんかを生成するアルゴリズムです。
画像認識において効果的な畳み込み層の構造を逆にして、ベクトル列を拡張しながら画像を生成します。

f:id:fuchami:20170715162313p:plain
詳しいアルゴリズムは僕が説明するより良い記事はたくさんあるので割愛。

実行環境

学習モデル

自分で作れるほど技術力がないのでTensorflowで動かせるDCGANのデモを使用。
github.com

gitから持ってきました。

学習用データセット収集

bohemia.hatenablog.com

こちらの記事の方はPokemon Goスクリーンショットにてポケモンを生成してるのですが、これを見た僕は「ドット絵の方でもできるんじゃ」
なんて思いつき試してみました。

ひこちゃんず!│ドット絵一括ダウンロード

有志の方がドット絵データセット作られていました。感謝、、、
カラードット(金銀)以降の対面画像のものだけを抽出、
さらに左右反転などの水増し処理を行ったものをデータセットとして学習に用いました。

その結果フシギダネだけで184枚のデータセットが出来上がりました。
画像総数は80,622枚です。いい具合に集まったと思われます。

f:id:fuchami:20170715163606p:plain

学習結果

epoch 99

f:id:fuchami:20170715164110p:plain

まあ最初はこんな感じ、、

epoch 600

f:id:fuchami:20170715164144p:plain

お?それっぽいぞ

最終的にうまくできたやつ

f:id:fuchami:20170715164318p:plainf:id:fuchami:20170715164733p:plain
f:id:fuchami:20170715164458p:plainf:id:fuchami:20170715164543p:plainf:id:fuchami:20170715164311p:plain

gifにした

f:id:fuchami:20170715165935g:plain

まとめ

どことなくそれっぽいのが出来ました。
アンノーンのデータが多い(A〜Zの形のやつがいる)のでアンノーンっぽいのがちょこちょこ混じってます。

データ整形がうまくいってないような気もするのでぼちぼちまたいじりないおします。

スポンサーリンク
このサイトについて

ここには、自己紹介やサイトの紹介、あるいはクレジットの類を書くと良いでしょう。

検索

フォローする

スポンサーリンク
このサイトについて

ここには、自己紹介やサイトの紹介、あるいはクレジットの類を書くと良いでしょう。

検索

【Twitter API】西野カナっぽい歌詞を自動生成するbotをつくった【形態素解析】

形態素解析西野カナbot

f:id:fuchami:20170216063410p:plain

大学で自然言語処理に関する講義を受講しました。
最終課題としてTwitter APIを用いて自動ツイートをするbotの作成を課されたので、自動で西野カナっぽい歌詞を生成するbotを作成。

データを収集する

とりあえず、西野カナの歌詞を大量に収集しなければいけません。
Twitter APIを用いるということで、歌詞もTwitter上から集めることに。
西野カナ歌詞botなるものがいくつも存在するためその中からこちらのアカウントを使用させて頂きました。

西野カナ 歌詞bot (@kanayan_lyrics) | Twitter
西野カナ歌詞bot (@kana_lyrics) | Twitter

データ収集コード

実際にツイートから歌詞を収集していきます。1回のツイート取得数は200ツイートまでなのですが、オプションパラメータであるmax_idを指定することによってそれより前のツイートを繰り返し取得していきます。

#-*- encoding:utf-8 -*-
import requests_oauthlib
import requests
import json
import sys, os
#ツイートの取得
def get_tw(account):
session = requests_oauthlib.OAuth1Session(
"XXXXXXXXXXXXXXXXXXX", #Consumer Key
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #Consumer Secret
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #Access Token
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" #Access Token Secret    
)
url = 'https://api.twitter.com/1.1/statuses/user_timeline.json'
res = session.get(url, params = {'screen_name': account, 'count':200,'include_rts':False})
maxid = 0
i = 0
f = open("data.txt", "a")
#ツイートを取得
while True:
res_text = json.loads(res.text)
for r in res_text:
if maxid > r['id'] or maxid == 0:
maxid = r['id']
tw = r['text'].encode('utf-8')
f.write(tw)
i = i +1
if  500<= i:
break
res =  session.get(url, params = {'screen_name': account, 'count':200,'include_rts':False, 'max_id': r['id']-1})
#APIの呼び出し・ステータスコード判定
if res.status_code != 200:
#正常終了しなければエラー表示
print ("Twitter API Error: %d" % res.status_code)
sys.exit(1)
f.close()
return 0
#main関数
def main():
#ツイートを取得する
get_tw("kanayan_lyrics")
get_tw("kana_lyrics")
print("ツイートを収集しました")
return 0
if __name__ == "__main__":
sys.exit(main())

収集結果

こんな感じで収集できました。だいぶ重複しているとは思いますが、文字数にして104020文字、5304行西野カナの歌詞を取得することができました。
なかなかカオスです。

f:id:fuchami:20170216055850p:plain

歌詞を生成する

分かち書き

歌詞の生成の前に、日本語を分かち書きする必要があります。
英語は単語ごとにスペースが区切られてますが日本語はそんなことがないため単語ごと(正確には形態素ごと)に分ける必要があります。
MeCabっていう形態素解析エンジンがあるのでこれを使用。

歌詞生成 マルコフ連鎖 (N-gramモデル)

さて、いよいよ歌詞を生成します。
今回はマルコフ連鎖を用いて歌詞を生成していきます。
マルコフ連鎖に関してはニコニコ大百科が非常に分かりやすいので一読することをおすすめします。
マルコフ連鎖とは (マルコフレンサとは) [単語記事] – ニコニコ大百科

今回は連鎖数3で作成。あまり増やしすぎるとオリジナルの歌詞そのままを生成してしまう(ような気がした)ので。

歌詞生成コード

#-*- encoding:utf-8 -*-
from requests_oauthlib import OAuth1Session
import requests
import json
import sys, os, re
import MeCab
import random
#Mecabによってわかちがきを行う
def wakati(text):
#余計な文字列を除去
text=re.sub(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-…]+', "", text)
text=re.sub('RT', "", text)
text=re.sub('#kana_nishino', "", text)
text=re.sub('/', "", text  )
text=re.sub('#西野カナ', "", text)
t = MeCab.Tagger("-Owakati")
m = t.parse(text)
result = m.rstrip(" \n").split(" ")
return result
#連鎖数3のマルコフ連鎖にて文章生成
def create_tw(wordlist):
markov = {}
w1 = ""
w2 = ""
w3 = ""
endword = ["。", "!", "?"]
for word in wordlist:
if w1 and w2 and w3:
if(w1, w2, w3) not in markov:
markov[(w1, w2, w3)] = []
markov[(w1, w2, w3)].append(word)
w1, w2, w3 = w2, w3, word
count = 0
sentence = ""
w1, w2, w3 = random.choice(markov.keys())
while count < len(wordlist):
tmp = random.choice(markov[w1, w2, w3])
#句読点などの区切りがついたら文章作成を終了
if tmp in endword:
break
sentence += tmp
w1, w2, w3 = w2, w3, tmp
count += 1
if count > 20:
break
return sentence
#main関数
def main():
CK = 'XXXXXXXXXXXXXXXXXXXXXXXXX'
CS = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
AT = 'XXXXXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
AS = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
filename = "data.txt"
src = open(filename, "r").read()
# ツイート投稿用のURL
url = "https://api.twitter.com/1.1/statuses/update.json"
#わかち書き
wordlist = wakati(src)
#文の作成
tw = create_tw(wordlist)
# ツイート本文
params = {"status": tw}
# OAuth認証で POST method で投稿
twitter = OAuth1Session(CK, CS, AT, AS)
req = twitter.post(url, params = params)
# レスポンスを確認
if req.status_code == 200:
print ("posted tweet:" + tw)
else:
print ("Error: %d" % req.status_code)
return 0
if __name__ == "__main__":
sys.exit(main())

生成結果

上手く出来たものをいくつか紹介。
なかなか西野カナの雰囲気のが出てると思います。

失敗例

英単語が何故か単語ごとにスペースがなく見づらくなってしまいました。
いろいろやってみものの結局挫折。
pytnoで日本語と英語を扱うのはなかなかキツいっす。

スポンサーリンク
このサイトについて

ここには、自己紹介やサイトの紹介、あるいはクレジットの類を書くと良いでしょう。

検索

フォローする

スポンサーリンク
このサイトについて

ここには、自己紹介やサイトの紹介、あるいはクレジットの類を書くと良いでしょう。

検索