LoginSignup
8
6

More than 3 years have passed since last update.

TensorFlowで簡単に画像分類

Last updated at Posted at 2021-01-12

#はじめに

久しぶりにTensorFlow(Keras)を触ったら忘れていることが多かったので、簡単にメモとして残しておきます。

##学習の流れ

TensorFlow(以下TF)では、
① データセットの準備
② モデルの準備
model.compile でoptimizer, loss, metricsの指定
④ callbacksの指定
model.fitで学習開始
model.evaluate でテストの評価
⑦ 画像の予想確率だけ得るときは model.predict

のような流れです。
これは比較的簡単な書き方です。もう少し細かいところまで記述したい場合は、以前に記事を書きましたので参考にしてみてください。

TensorFlow2で機械学習をはじめたいと思ってる方へ

##① データセットの準備

ディレクトリに画像を保存しておいてそこから読み込むには、flow_from_directory()を用います。
その前にImageDataGeneratorを使用し、augmentationの中身を記述します。

.py
train_datagen = ImageDataGenerator(
            rescale=1./255,
            zoom_range=0.2,
            horizontal_flip=True,
            rotation_range=20,
            width_shift_range=0.2,
            height_shift_range=0.2,
            )

val_datagen = ImageDataGenerator(rescale=1./255)


train_generator = train_datagen.flow_from_directory(
            TRAIN_DIR,
            target_size=(img_size, img_size),
            batch_size=batch_size,
            classes=classes,
            class_mode='categorical')


val_generator = val_datagen.flow_from_directory(
            VAL_DIR,
            target_size=(img_size,img_size),
            batch_size=batch_size,
            classes=classes,
            class_mode='categorical')

*クラスラベルについては、train_generator.class_indicesのようにすると取得可能。クラスの対応表が出力できます。基本的にはアルファベット順。

以下のように使用できる augmentationは多いので各自タスクに合わせて決めてください。
詳しく知りたい人は、公式ドキュメントで確認してください。

.py
tf.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, 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, dtype=None
)

flow_from_directoryでは、ディレクトリのパスを指定して、オーギュメントされた画像がバッチサイズごとに生成されます。

.py

flow_from_directory(
    directory, target_size=(256, 256), color_mode='rgb', classes=None,
    class_mode='categorical', batch_size=32, shuffle=True, seed=None,
    save_to_dir=None, save_prefix='', save_format='png',
    follow_links=False, subset=None, interpolation='nearest'
)

class_mode : categorical, binary, sparse, input, None が選択可能。デフォは,categorical.
shuffle : Flaseならアルファベット順
save_to_dir : None or str(default:None). ディレクトリを指定することによって augmented data を保存してくれる。可視化に役に立つ。
save_prefix : str. 保存された画像のファイル名に使う。(save_to_dirが設定されている場合有効)
save_format : png or jpeg (Default:'png')
interpolation : nearest(デフォルト), bilinear, bicubic

##② モデルの準備

今回は例として、MobileNetv2を使います。tf.keras.applicationsに他の学習済みモデルもあります。

.py
IMG_SHAPE = (img_size, img_size, channels)
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                            include_top=False,
                                            weights='imagenet')

global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
prediction_layer = tf.keras.layers.Dense(n_classes, activation='softmax')
model = tf.keras.Sequential([
            base_model,
            global_average_layer,
            prediction_layer
            ])

##③ model.compile で optimizer, loss, metricsの指定

modelに対して学習の詳細を設定します。

.py
model.compile(optimizer=optimizers.SGD(lr=0.0001, momentum=0.99, decay=0, nesterov=True),
            loss='categorical_crossentropy',
            metrics=['accuracy'])
.py
compile(
    optimizer='rmsprop', loss=None, metrics=None, loss_weights=None,
    weighted_metrics=None, run_eagerly=None, steps_per_execution=None, **kwargs
)

optimizer : string or optimizer instance (default: rmsprop)
画像系のタスクだと個人的には、SGDかな?

ex) SGD, RMSprop, Adam, Adadelta,...

.py
sgd = tf.keras.optimizers.SGD(
    learning_rate=0.01, momentum=0.0, nesterov=False, name='SGD', **kwargs
)

*このsgdを model.compileのoptimizerに設定する

loss : string, object function or tf.keras.losses.Loss instance
metrics : trainingとtestで使用するmetricsのリスト
loss_weights : ロスに重み付けする

##④ callbacksの指定

CSVLogger, History, ProgbarLogger, TensorBoard, EarlyStopping, ReduceLROnPlateau など設定できます。
model.fitで学習する際に渡すことができます。詳しくは公式ドキュメントをご確認ください。

例をいくつか挙げておきます。

.py
tf.keras.callbacks.EarlyStopping(
    monitor='val_loss', min_delta=0, patience=0, verbose=0,
    mode='auto', baseline=None, restore_best_weights=False
)
.py
tf.keras.callbacks.ModelCheckpoint(
    filepath, monitor='val_loss', verbose=0, save_best_only=False,
    save_weights_only=False, mode='auto', save_freq='epoch',
    options=None, **kwargs
)

filepath : string or PathLike, モデルを保存するパス。指定できる変数は、epoch, loss, acc, val_loss, val_accです。
ex) filepath = '{val_loss:.2f}-{val_acc:.2f}.hdf5'
monitor : 何を基準にモデルを保存するか。accuracy, val_accuracy, loss, val_loss
*もし metrics name が分からなかったら、 history = model.fit()history.historyを確認。
mode : {auto, min, max}
save_best_only : もし、filepathが{epoch}のようなフォーマットを含んでいなかったら、filepathはオーバーライドされる
save_weights_only : modelの重みのみ保存
save_freq : epoch, or integer.

.py
tf.keras.callbacks.LearningRateScheduler(
    schedule, verbose=0
)
.py
tf.keras.callbacks.ReduceLROnPlateau(
    monitor='val_loss', factor=0.1, patience=10, verbose=0,
    mode='auto', min_delta=0.0001, cooldown=0, min_lr=0, **kwargs
)
.py
tf.keras.callbacks.RemoteMonitor(
    root='http://localhost:9000', path='/publish/epoch/end/',
    field='data', headers=None, send_as_json=False
)
.py
tf.keras.callbacks.CSVLogger(
    filename, separator=',', append=False
)

##⑤ model.fitで学習開始

.py
history = model.fit(
        train_generator,
        steps_per_epoch=steps_per_epoch,
        validation_data=val_generator,
        validation_steps=validation_steps,
        epochs=CONFIG.epochs,
        shuffle=True,
        callbacks=[cp_callback])
.py
fit(
    x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None,
    validation_split=0.0, validation_data=None, shuffle=True, class_weight=None,
    sample_weight=None, initial_epoch=0, steps_per_epoch=None,
    validation_steps=None, validation_batch_size=None, validation_freq=1,
    max_queue_size=10, workers=1, use_multiprocessing=False
)

validation_split : [0~1]. training dataの一部をa validation data とする。x, yの後ろのデータが用いられる(シャッフルする前)。
validation_data : validation data. validation_splitがある場合はオーバーライドされる
class_weight : データが少ないクラスのlossに重きを置く方法。辞書型で渡す。例) {0:0.66, 1:1.33}
steps_per_epoch : Integer or None. training data // batch_size で求められる。
validation_steps : Integer or None. validation data // batch_size で求められる。

##⑥ model.evaluate でテストの評価

.py

test_loss, test_acc = model.evaluate(test_generator, steps=test_steps)
.py
evaluate(
    x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None,
    callbacks=None, max_queue_size=10, workers=1, use_multiprocessing=False,
    return_dict=False
)

x : 入力データ。 Numpy array, tensor, tf.data.dataset, (inputs, targets) or (inputs, targets, sample_weights)
y : ターゲットデータ。
batch_size : Integer or None.
verbose : 0 or 1. Verbosity mode. 0 = silent, 1 = progress bar.
sample_weight :
steps : Integer or None
callbacks : list of keras.callbacks.Callback instances
max_queue_size : Integer.
workers : Integer.
use_multiprocessing : boolean
return_dict : もしTrueなら、metric results をdictで返す

##⑦ 画像の予想確率だけ得るときは model.predict

.py
predict(
    x, batch_size=None, verbose=0, steps=None, callbacks=None, max_queue_size=10,
    workers=1, use_multiprocessing=False
)

##+α

####<<モデルを保存した際に作成されるファイルについて>>

checkpoint : 1ファイルのみ作成。どのファイルが最新か確認可能。学習の際に必要なのでテストの際はなくても大丈夫。保存したデータから再度学習を始める場合に必要。

XXXXX.data-0000-of-00001 : 変数名をテンソル値としてマッピングした独自のフォーマット。

XXXXX.index : このファイルはバイナリファイル。複数のステップでデータを保存した際に同名の「.data-0000-of-00001」ファイルが、どのステップのどのデータであるか一意に定まる。

#終わりに
細かい設定まで今回目を通すことができて良い機会になりました。

#参考文献

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6