今回の記事はKerasの画像前処理のパラメータチューニングを解説します。
データ拡張は、訓練データの画像に対して移動、回転、拡大・縮小など人工的な操作を加えることでデータ数を追加するテクニック。学習データを追加すると、モデルの汎化性能が改善できます。
機械学習、ディープラーニングの世界では大量のデータが必要となるので、オリジナルデータが少ない場合、ImageDataGeneratorを使用することで簡単に画像を増やす事ができます。
KerasライブラリのImageDataGeneratorクラスのパラメータを変更します。
keras.preprocessing.image.ImageDataGenerator(featurewise_center=False, samplewise_center=False, featurewise_std_normalization=False, samplewise_std_normalization=False, zca_whitening=False, zca_epsilon=1e-06, rotation_range=0.0, width_shift_range=0.0, height_shift_range=0.0, brightness_range=None, shear_range=0.0, zoom_range=0.0, channel_shift_range=0.0, fill_mode='nearest', cval=0.0, horizontal_flip=False, vertical_flip=False, rescale=None, preprocessing_function=None, data_format=None, validation_split=0.0)
featurewise_center: 真理値。データセット全体で,入力の平均を0にします。
samplewise_center: 真理値。各サンプルの平均を0にします。
featurewise_std_normalization: 真理値。入力をデータセットの標準偏差で正規化します。
samplewise_std_normalization: 真理値。各入力をその標準偏差で正規化します。
zca_epsilon: ZCA白色化のイプシロン。デフォルトは1e-6。
zca_whitening: 真理値。ZCA白色化を適用します。
rotation_range: 整数。画像をランダムに回転する回転範囲。
width_shift_range: 浮動小数点数(横幅に対する割合)。ランダムに水平シフトする範囲。
height_shift_range: 浮動小数点数(縦幅に対する割合)。ランダムに垂直シフトする範囲。
shear_range: 浮動小数点数。シアー強度(反時計回りのシアー角度)。
zoom_range: 浮動小数点数または[lower,upper]。ランダムにズームする範囲。浮動小数点数が与えられた場合,[lower, upper] = [1-zoom_range, 1+zoom_range]です。
channel_shift_range: 浮動小数点数。ランダムにチャンネルをシフトする範囲。
fill_mode: {"constant", "nearest", "reflect", "wrap"}のいずれか。デフォルトは 'nearest'です。指定されたモードに応じて,入力画像の境界周りを埋めます。
constant: kkkkkkkk|abcd|kkkkkkkk (cval=k)
nearest: aaaaaaaa|abcd|dddddddd
reflect: abcddcba|abcd|dcbaabcd
wrap: abcdabcd|abcd|abcdabcd
cval: 浮動小数点数または整数。fill_mode = "constant"のときに境界周辺で利用される値。
horizontal_flip: 真理値。水平方向に入力をランダムに反転します。
vertical_flip: 真理値。垂直方向に入力をランダムに反転します。
rescale: 画素値のリスケーリング係数。デフォルトはNone。Noneか0ならば,適用しない。それ以外であれば,(他の変換を行う前に) 与えられた値をデータに積算する。
preprocessing_function: 各入力に適用される関数です。この関数は他の変更が行われる前に実行されます。この関数は3次元のNumpyテンソルを引数にとり,同じshapeのテンソルを出力するように定義する必要があります。
data_format: {"channels_first", "channels_last"}のどちらか。"channels_last"の場合,入力のshapeは(samples, height, width, channels)となり,"channels_first"の場合は(samples, channels, height, width)となります。デフォルトはKerasの設定ファイル~/。keras/keras。jsonのimage_data_formatの値です。一度も値を変更していなければ,"channels_last"になります。
validation_split: 浮動小数点数。検証のために予約しておく画像の割合(厳密には0から1の間)です。
では猫の画像を準備します。
import matplotlib.pyplot as plt
from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator
# 画像ファイルをPIL形式でオープン
img = image.load_img('./data/cat01.png')
# PIL形式をnumpyのndarray形式に変換
x = image.img_to_array(img)
# (height, width, 3) -> (1, height, width, 3)
x = x.reshape((1,) + x.shape)
datagen = ImageDataGenerator(
rotation_range=0,
width_shift_range=0,
height_shift_range=0,
shear_range=0,
zoom_range=0,
horizontal_flip=False,
vertical_flip=False)
def show_imgs(imgs, row, col):
"""Show PILimages as row*col
# Arguments
imgs: 1-D array, include PILimages
row: Int, row for plt.subplot
col: Int, column for plt.subplot
"""
if len(imgs) != (row * col):
raise ValueError("Invalid imgs len:{} col:{} row:{}".format(len(imgs), row, col))
for i, img in enumerate(imgs):
plot_num = i+1
plt.subplot(row, col, plot_num)
plt.tick_params(labelbottom="off") # x軸の削除
plt.tick_params(labelleft="off") # y軸の削除
plt.imshow(img)
plt.show()
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
# このあと画像を表示するためにndarrayをPIL形式に変換して保存する
imgs.append(image.array_to_img(d[0], scale=True))
# datagen.flowは無限ループするため必要な枚数取得できたらループを抜ける
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
rotation_range: 整数.画像をランダムに回転する回転範囲.
「-90〜90」の中でランダムに1つ数字を選んで回転処理するようになっている。
rotation_range=45に変換します。
datagen = ImageDataGenerator(
rotation_range=45,
width_shift_range=0,
height_shift_range=0,
shear_range=0,
zoom_range=0,
horizontal_flip=False,
vertical_flip=False)
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
imgs.append(image.array_to_img(d[0], scale=True))
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
width_shift_range: 浮動小数点数(横幅に対する割合)。
ランダムに水平シフトする範囲.
width_shift_range=0.25に変換します。
datagen = ImageDataGenerator(width_shift_range=0.25)
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
imgs.append(image.array_to_img(d[0], scale=True))
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
height_shift_range: 浮動小数点数(縦幅に対する割合)。
ランダムに垂直シフトする範囲
height_shift_range=0.25に変換します。
datagen = ImageDataGenerator(height_shift_range=0.25)
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
imgs.append(image.array_to_img(d[0], scale=True))
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
datagen = ImageDataGenerator(shear_range=50)
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
imgs.append(image.array_to_img(d[0], scale=True))
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
zoom_range: 浮動小数点数または[lower,upper]。
ランダムにズームする範囲.浮動小数点数が与えられた場合,
[lower, upper] = [1-zoom_range, 1+zoom_range]です。
zoom_range=0.5に変換します。
datagen = ImageDataGenerator(zoom_range=0.5)
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
imgs.append(image.array_to_img(d[0], scale=True))
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
datagen = ImageDataGenerator(channel_shift_range=100)
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
imgs.append(image.array_to_img(d[0], scale=True))
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
datagen = ImageDataGenerator(horizontal_flip=0.4)
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
imgs.append(image.array_to_img(d[0], scale=True))
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
datagen = ImageDataGenerator(vertical_flip=0.4)
max_img_num = 4
imgs = []
for d in datagen.flow(x, batch_size=1):
imgs.append(image.array_to_img(d[0], scale=True))
if (len(imgs) % max_img_num) == 0:
break
show_imgs(imgs, row=2, col=2)
ImageDataGenerator https://keras.io/ja/preprocessing/image/