Keras CNN を改造してImageDataGenerator(画像水増し機能)を理解する

今回は、Keras のサンプルプログラム cifar10_cnn.pyを改造して、ImageDataGenerator(画像水増し機能)の使い方を理解します。

こんにちは cedro です。

Webで Keras について検索すると、サンプルプログラムは公式版の他にも、色々な方々が作ったものが沢山見つかりますし、個別の機能を紹介するブログは山ほどあります。

そういう環境の中であれば、Keras の習得はWebの情報を元にサンプルプログラムを改造して動かしてみることが一番効果的ではないかと考え、最近サンプルプログラムを色々改造しています。

今回改造するのは、cifar10_cnn.py という、10クラス(飛行機〜トラックまで)の画像データセット Cifar10CNN(畳み込みニューラルネットワーク)で分類するサンプルプログラムです。

実は、このプログラムの中には、ImageDataGenerator(画像水増し機能)が組み込まれていて、画像データが少ない場合のディープラーニングにどれだけ使えるのか試してみたいと思っています。

ということで、今回は、Keras のサンプルプログラム cifar10_cnn.py を改造して、ImageDataGenerator(画像水増し機能)の使い方を理解します。

 

オリジナルデータセットを用意する

データセットが cifar10 のままでは面白くないので、有名人の顔画像を集めた CelebA データセット属性ファイルを利用して、オリジナルのデータセットを作成します。(詳細は、8/18のブログ「CelebAデータセットから好みのデータセットを抽出する」を参照下さい。)

 

celeba_data に CelebAの画像データを格納します。抽出したデータセットを格納するために select フォルダーを作り、その下に「0」〜「3」のフォルダーを作ります。list_attr_celeba.txt属性ファイルselect.pyプログラムです。

 

select.py の中身です。「笑う男」、「笑わない男」、「笑う女」、「笑わない女」の4種類からなる「性別×笑い」データセットを作成します。

 

作成したデータセットです。オリジナルは178×218ピクセルですが、今回改造するサンプルプログラムの中で、センターから160×160ピクセルクロップしてからリサイズするので、ここでは、160×160ピクセルクロップした状態で表示しています。

なお、各フォルダーの枚数は、7,500枚に揃えました。従って、全体で 7,500枚×4種類=30,000枚です。

 

プログラムを改造します

新たに必要なライブラリーインポートします。

 

毎度おなじみの、オリジナルデータセットの読み込み部分です。画像データは、オリジナル178×218を読み込み、センターから160×160でクロップして、32×32にリサイズしています。30,000枚のデータを学習用24,000枚評価用6,000枚に使います。

 

プログラムの最後に、ロス・精度の時系列グラフConfusion Matrix を表示する部分を追加します(詳細は、8/30ブログ「Keras MLPを改造して定番パターンを勉強する」を参照)。

これに伴い、改造前プログラムの72行目の model.fithistory = model.fit に、114行目の model.fit_generatorhistory = model.fit_generator に変更します。こうすることで、history ディレクトリにロス・精度等のデータが記録され、後でこれを利用してグラフを作ることが出来ます。

 

改造したプログラムを、celeba_cnn.py で保存し、同じフォルダーに先ほど作ったデータセットのselect フォルダーを格納します。では、動かしてみます。

精度の推移グラフです。精度 86.66%(100 epoch)でした。

Confusion Matrix です。32×32ピクセルと小さいためか、男性・女性の識別に間違いは少ないですが、笑っているかどうかの識別は間違いが結構多く、むずかしいようですね。

 

ImageDataGenerator(画像水増し機能)の効果を確認する

改造前プログラム19行目の data_augmentation = True False に変更すると、ImageDataGenerator を使わない設定になるので、ここを切り替えれば効果が確認できます。

ImageDataGenerator が真価を発揮するのはデータ量が少ない時ですので、データを学習と評価に分割する、x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=111) の中を test_size =0.97 に変更し、学習用データ24,000個から900個に減らします。

そして、データ数が極端に減るので、改造前プログラム18行目のepochs100→400に変更して学習回数を調整します。また、ImageDataGenerator には、色々な設定項目がありますが、ひとまずはサンプルプログラムの設定をそのまま使います。

data_augmentation = False で動かした結果です。100epoch76.30%と急速に精度が改善しますが、それ以降はほとんど精度向上は見られず、400epoch77.44%でした。まあ、同じ画像を繰り返して学習するだけなので、直ぐ頭打ちになるということでしょうか。

data_augmentation = True で動かした結果です。 False と比べて精度改善スピードはゆっくり目で 100 eopch でまだ70.53%でしたが、その後も着実に精度が改善し 400 epoch79.41%となり、2ポイント改善されました。人工的とはいえ、常に変化する画像を学習するので、学習効果が長く続くということでしょうか。

 

ImageDataGenerator の働きを画像で見てみる

ImageDataGenerator が画像にどんな加工を加えているのか、サンプル画像で見てみます。

サンプル画像は、CelebAデータセットの先頭にある、この 000001.png を使います。

ImageDataGenerator の働きをチェックするためのプログラムです。000001.png を読み込んで、ImageDataGenerator で設定した内容で加工をしたものを6枚並べて表示し、gentest.png で保存します。(ブログ「Keras の ImageDataGenerator を使って学習画像を増やす」を参考にさせて頂きました。感謝です。)

 

rotation_range(回転)です。この設定は15で、±15度の範囲でランダムに画像を回転させます。CelebAの顔画像は、傾いた顔はほとんどないので、効果はなさそうです。サンプルプログラムは使っていません。

 

width_shift(横方向のシフト)です。この設定は0.1で、±10%の範囲でランダムに画像を横方向にシフトします。これはアリですね。サンプルプログラムは、これと同じ0.1で設定しています。

 

height_shift(縦方向のシフト)です。この設定は0.1で、±10%の範囲でランダムに画像を縦方向にシフトします。これもアリですね。サンプルプログラムは、これと同じ0.1で設定しています。

 

horizontal_flip(左右反転)です。この設定は True で、ランダムに左右を反転します。これは常套手段ですね。サンプルプログラムでも使っています。

 

vertical_flip(上下反転)です。この設定は True で、ランダムに上下を反転します。さすがに、顔画像にこれはないでしょう。サンプルプログラムでも使っていません。

 

zoom_range(ズーム)です。この設定は、0.1で、±10%の範囲で、ランダムに画像をズームします。0.05くらいならありかも。サンプルプログラムは使っていません。

 

shear_range(シアー変換)です。この設定は、10です。斜め方向に引き延ばすような変換をかけます。顔が歪んじゃうのはあまり良くない気がします。サンプルプログラムでは使っていません。

zoom_range を追加したり、width_shiftheight_shift を調整したりして、学習・評価プログラムを再度動かしてみましたが、精度向上は見られず、逆に悪化する場合もありました。CelebAの顔画像は、サンプルプログラムの設定が適切な様です。

では、また。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

ABOUTこの記事をかいた人

2017年8月に、SONY Neural Network Console に一目惚れして、ディープラーニングを始めました。初心者の試行錯誤をブログにしています。