本サイトにはプロモーションが含まれています

人工知能の技術

【Keras/NumPy】データ拡張(Data Augmentation)における画像操作

こんにちは。投資エンジニアの三年坊主(@SannenBouzu)です。

今回は、機械学習のモデル精度向上に役立つ技術:データ拡張(Data Augmentation)における画像操作について紹介します。

大学の研究・自分の趣味・業務で、合わせて5年以上Pythonを使ってきました。

画像処理に関しては専門外なのですが(間違いがあれば是非コメント等で指摘いただけると幸いです)、最近興味が湧いてきたので、自身の知識定着も兼ねて整理したいと思います。

KerasのImageDataGeneratorでのパラメータ指定方法に加えて、一部NumPyでの実装例も紹介しているので、ぜひご覧ください。

 

この記事はこんな方におすすめ!

  • 機械学習のモデル精度向上に役立つ?データ拡張(Data Augmentation)って何?概要とモチベーションを知りたい方
  • データ拡張で実際に使われる画像操作を、サンプル画像で確認したい方
  • preprocess_input関数による前処理の効果を、サンプル画像で確認したい方

データ拡張(Data Augmentation)の概要とモチベーション

機械学習、特に深層学習(Deep Learning)の複雑なモデルを構築する際には、解決したい課題に適した大量のトレーニングデータが必要ですが、データ収集は必ずしも簡単ではありません

一方で、学習データが少ないと、過学習(Overfitting)が起きてしまい汎化性能(未知のデータに対する性能)が出ないという問題があると言われます。

データ拡張(Data Augmentation)は、元のトレーニングデータに変換処理を加える、いわばデータの「水増し」によってトータルのデータ量を増やし、データのバリエーションを増やすことでモデルの精度向上を目指すテクニックです。

今回は、画像処理分野におけるCNN(Convolutional Neural Network)への入力データを想定して、データ拡張(Data Augmentation)における画像操作について具体的に確認します。

 

サンプル画像データの準備

サンプル画像データを準備します。

ライブラリをインストール。

 

深層学習(Deep Learning)系ライブラリのバージョンを確認します。

  • tf : 1.14.0
  • (tf.keras : 2.2.4-tf)
  • keras : 2.2.5
  • keras_applications : 1.0.8
  • keras_preprocessing : 1.1.0

 

 

Kerasの訓練済みモデル定義や画像の前処理についてはそれぞれkeras_applicationskeras_preprocessingというライブラリに具体的に記述されていて、kerasライブラリがそれらをインポートしている状況のようです。

 

 

 

以下、中央寄せしたこの画像に対してデータ拡張を行っていきます。

 

データ拡張(Data Augmentation)における画像操作

近年、機械学習のモデル精度向上に有効なデータ拡張方法が次々と提案されています。

ここではその全てに触れることは避け、いくつかの基本的な例を紹介するに留めます。

 

Horizontal Flip, Vertical Flip(画像の左右反転・上下反転)

 

 

NumPyでの実装は、例えばこのようになります。(Kerasのコードを参考にしています)

 

  • スライス(::-1)を使って、配列の値を逆順にしています
  • x = x[::-1, …] の … はPythonの組み込み定数Ellipsis。途中の次元を省略して指定できます

 

 

Random Rotation(画像の回転)

 

 

Random Shift(画像の平行移動)

 

 

Random Shear(画像のシアー変換)

 

 

Random Zoom(画像の拡大・縮小)

 

 

Random Channel Shift(画像のチャネルシフト)

 

 

Random Brightness(画像の明るさ調整)

 

 

その他の画像操作

 

  • Random Crop(画像のトリミング)
  • Scale Augmentation(画像のリサイズ+トリミング)
  • Cutout(画像のマスク)
  • Random Erasing

 

機械学習モデルにとって意味のある画像操作をすることが大切だと思います。

  • 被写体の向きや光の加減が少し違ったり、一部分が見えなかったりすることはたしかに十分起こりうる
  • 被写体があらぬ方向に引き伸ばされるようなシチュエーションはありうるのか・・・?

トレーニングデータをいくら大量に集めても絶対に実際に出現しないような画像を水増ししても、おそらく実際のモデルの性能向上にはあまり役立たないでしょう。

 

preprocess_input関数とImageDataGeneratorの関係を読み解く【コードリーディング】

preprocess_input関数とは、Kerasの訓練済みモデルごとに個別に定義されている画像前処理用の関数のことです。

上のリンクからサンプルコードを確認すると、Keras model に画像を与える前にこのpreprocess_inputを適用しているのが分かります。

この preprocess_input は実質的には _preprocess_numpy_input という関数を呼んでいて、それぞれの訓練済みモデルが元々どのように訓練されたかに応じて、画素値が[-1,1]の範囲に収まるように正規化をしたり、’RGB’->’BGR’の変換をしたりなどの前処理をしているようです。

 

ImageDataGeneratorクラスでこの処理を行わせるためには、引数preprocessing_function に preprocess_input を指定できます。

少しだけコードリーディングをすると、

という関係になっているようです。

 

最後に、いくつかの訓練済みモデルを例に、preprocess_inputによる前処理の効果を確認してみます。

元々Caffeで訓練されているResNet50の場合、

 

より最近になって提案された、軽量・高精度のMobileNetでは、

このように、モデルごとに適切な前処理を行うための関数 preprocess_input が定義されているので、keras.applications以下の空間からモデルに合ったものをインポートして使いましょう。

今後の課題

 

  • 白い部分を補完する
    • 縦横比が崩れるのが嫌で(PIL.Image.resizeではなく)PIL.Image.thumbnailを使いましたが、データによっては気にせずresizeで縦横比を壊してしまってもいいかもしれません
  • NumPy(SciPy)での実装を確認する
    • 今回はHorizontal Flip, Vertical FlipのNumPy実装を確認しましたが、他の画像操作についても実装を検討して追加できればと思います

 

関連記事:こちらも読まれています

【2019年版】Pythonインストール・Mac編【長く安全に使える環境構築】

Pythonを快適に使いこなすMac環境【現役エンジニアおすすめはPro 13インチ】

【pandas】重複したDataFrameの行を確認・削除【逆引きデータ分析】

 

 

▼経験の棚卸しで納得のキャリアを▼
▼自宅で簡単・お得にふるさと納税▼
【期間限定】無料登録でプレゼント

COMMENT

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください