cedro-blog

Keras で変分オートエンコーダ(VAE)を漢字データセットでやってみる

今回は、変分オートエンコーダで漢字を2次元マップにマッピングしてみます。

こんにちは cedro です。

変分オートエンコーダが面白くてたまりません。画像を連続的に変化させながら2次元マップに分布させるのを見る度に、関心してしまいます。

変分オートエンコーダは、第1回はMNIST第2回はオリジナルデータセット(モノクロ28×28の顔画像)、第3回はセレブの顔画像とやって来ました。

数字顔画像顔画像とやって来ましたので、今回は文字にトライしてみたいなと思って、色々データセットを探したところ、ちょうど良さそうな漢字のデータセットを見つけました。

ということで、今回は、変分オートエンコーダ漢字2次元マップマッピングしてみます。

 

NDL Lab 漢字データセット とは

 

今回、使うデータセットは、NDL Lab文字画像データセット(漢字300文字版)です。

このデータセットは、国立国会図書館デジタルコレクションのインターネット公開資料から、頻出漢字300文字の画像を切り出したもので、合計146,157画像あります。

 

データ形式は、グレイスケール48×48のPNGです。各文字の収録画像数は、100画像から1,000画像まで文字によってバラツキがあります。

今回、どれ位の種類の漢字を2次元マップマッピングさせようかと考えたのですが、10種類くらいじゃあ MNIST みたいで面白くない。なので、思い切って30種類の漢字をマッピングさせることにしました。

 

使用する漢字は、データ数を多い順に並べ、画数が4未満のものを省いて(あまり簡単だと面白くないので)、上位30個を選びました。データ数は、合計28,838個です。

 

moji フォルダーを作成し、その下に0〜29まで30種類のフォルダーを作成して、画像データをそのまま格納すればOKです。前処理は、一切不要です。

 

プログラムを改造します

今回は、畳み込み変分エンコーダーのサンプルプログラム(variational_autoencoder_deconv.pyを改造して使います。

 

新たに必要なパッケージを追加でインポートします。train_test_split は1つのデータセットを学習用と評価用に任意に分割してくれるパッケージ、Imageglob は今回のデータセットの読み込みに使うパッケージです。

 

学習完了後、2次元マップドット画像マッピングする部分です。

28行目plt.close() で、ドット2次元マップをセーブした後に、matplotlibクリアしています。理由は良く分かりませんが、ここでクリアしておかないと、この後2次元マップに多量に生成する画像シミのようなものが付いてしまうので。

29行目と63行目plt.show() を無効にしているのは、一端表示させると、表示中止ボタンを押すまでプログラム動作が中断して使い勝手が悪いので。

46−47行目は、2次元マップに生成する画像を1枚づつ保存する部分で、0@0fig.png 〜 29@29fig.png まで 900枚(30×30=900)を保存する設定にしています。

 

データセット読み込み部分です。まず、MNIST 用の部分は無効にします(削除でもOK)。

今回は、画像データが30種類もあるので、前回や前々回の読み込み方だと、やたらプログラムの行数が増えスマートでないので、別の方法を試してみます。

まず、folder = [“0”, “1”, “2”, ・・・”29″] でフォルダー名を設定します。そして、 files = glob.glob(dir + “/*.png”) で、フォルダー内の画像名を全て取得します。その後、for i, file in enumerate(files): で画像を1つづつ、読み込んで行きます。

読み込んだ後は、必要な処理をし、train_test_split学習データ評価データ8:2に分割しています。これ便利で良いですよね。

 

ネットワーク構築部分です。先回同様、2箇所ある  for  i  in range (2) →  for  i  in range (3) に変更することで、エンコーダデコーダ畳み込みレイヤー2段から3段にパワーアップさせ、これに伴い filters16 → 32 に変更しています。

 

エンコーダの構成図はこんな形(プログラムが出力する vae_cnn_encoder.pngです)。畳み込みの部分は、モノクロ48×48の入力を24×24フィルター64枚で受けてから、6×6フィルター256枚まで次元圧縮(1/4)しています。

 

デコーダの構成図はこんな形(プログラムが出力する vae_cnn_decorder.pngです)。畳み込み部分は、エンコーダの逆です。

 

プログラムを動かしてみます

プログラムを格納したディレクトリで、上記コマンドを入力すれば、プログラムが動きます。学習時間は macbookAir1epoch 当たり7〜8分程度、設定は50epochなので約6時間といったところです。


2次元マップドットマッピングした結果です。Color bar を使ってデータを色分けしていますが、30種類もあると、色の変化が微妙で識別は難しいですね(笑)。

2次元マップ画像マッピングした結果です。さすがに30種類の漢字は伊達じゃないですね。変分オートエンコーダも結構大変なようで、ところどころ不連続なところがあります。

2次元マップ画像が比較的上手く分布している、赤枠線の部分に該当する画像を、保存した画像の中から拾って、GIF動画にしてみます。

まるで生き物のように漢字が連続的に変形して行きます。いわゆる漢字のモーフィングも、結構面白いものですね。

では、また。