ボケてAI
画像識別に使われるCNNと、文章生成等に使われるRNNを組み合わせたニューラルネットワークモデルをkerasで構築する。
- ボケてから収集した「画像-ボケ」セットを学習
- お題画像を入力すると、それに対するボケを出力してくれるはず
CNNについて
RNNについて
- 文章翻訳や対話に使われる、RNN拡張のLSTMによるseq2seqモデルを使用する
- ネットワークに文章を入力する際は、形態素解析したものをベクトル化して入力する
今回の元ネタ
画像からキャプチャ自動生成
モデル実装は上記のものをほとんどそのまま流用している
開発環境
- mac OSX 10.11.6
- python 3.5(3.6でも動くと思います)
- anaconda 4.4.0
環境構築
1. anacondaインストール
2. python仮想環境作成
# conda create -n bokete_ai python=3.5
# source activate bokete_ai
# conda info -e
# source deactivate # 終了時
3. ライブラリ関連インストール
# pip install tensorflow
# pip install keras
# pip install scrapy
# pip install Pillow
# pip install pandas
# pip install mojimoji
# pip install matplotlib
4. mecabセットアップ
-
mecabインストール
- mecab-ipadic のconfigureはutf8で行う
./configure --with-charset=utf8
- mecab-ipadic のconfigureはutf8で行う
- 新語辞書を追加
- mecabインストール後
pip install mecab-python3を実行
5. jupyter notebookセットアップ
- anacondaデフォルトで入っているが、作成したpython仮想環境で動かすため仮想環境内に別途インストールする
# conda install jupyter
# ipython kernel install --user --name=bokete_ai --display-name=bokete_ai
# jupyter kernelspec list
Available kernels:
bokete_ai /Users/username/Library/Jupyter/kernels/bokete_ai
python3 /Users/username/.pyenv/versions/anaconda3-4.4.0/share/jupyter/kernels/python3
実行
実行したソースコードはこちら
1. 学習データ収集
scrapyでボケてサイトから収集。
# cd boketeScrapy/boketeScrapy
# scrapy bokete -o legend.csv
- 高品質のボケを求めて /hot, /popular, /select, /pickup, /legendから再帰的に取得したが、400件弱とディープラーニングするには少なかった
- サイトに負荷を掛けないよう10秒間隔で実行
2. 学習
jupyter notebookを起動してvgg_seq2seq.ipynbを開く。
# cd ../
# jupyter notebook
notebookの各ステップを実行していく。
2-1. スクレイピングしたデータを加工して学習させる
- 入力となる画像をnp.arrayで読み込む
- 入力画像に対する出力となるボケ文言を、分かち書きしてからone-hotベクトル化する
2-2. モデル構築
- 上記のモデルを流用しパラメータを若干変更した
2-3. 学習実行
- mbp(core-i5/RAM8G)で4日程度かかった
-
loss=1.69, acc=0.6程度で精度が上がらないまま収束してしまった
3. ボケ実行
画像を入力して出力(ボケ)を確認する。
- 新しい画像を入力してみたが、ほとんどがまともな日本語にならない...
- 学習データ内のボケに対して、学習モデルが出力したボケは
寝言 そんな 仕事 てだった...(これでもうまくいった?方)
課題
- 学習データが全然足りない。せめて数千は必要?
- 出力文章の語彙は学習データ量に比例すると思われる
- 1000クラス分類の
ImageNetを使用しているので、未学習の物体画像(特にイラスト)は同じようなベクトルが出力され特徴量として適切でない?- VGG16も再学習させた方がよい?もしくは、もうネットワーク層を少なくしてみた方が特徴が出たりする?
- 画像内の文章に対応するタイプは
画像→文字でなく、画像内部の文字列をOCRして文字→文字のモデルを使う必要がある
参考
- Chainerでちゃんと実装されている例