やましなぶろぐ

自作画像データを分類するベースモデルを構築

自作した画像データをそのまま学習してCNNモデルを作成します

今回のモデルの精度をベンチマークとして諸々を工夫を施すと精度がどれくらい変化するかを今後検証します。

🕒 Last mod: 2020-11-02


1. ベンチマークモデルと精度

自作した画像データに対して分類するCNNモデルを構築します。

学習データはこちらの記事で作成しています。

今回、構築するモデルは工夫を施さずに画像データをそのままモデルに流し込みます。

今回のモデルの精度をベンチマークとして諸々の工夫を施したときに精度がどの程度変化するかを今後検証していきます。

ちなみにベンチマークの精度はroc_auc_scoreで0.5。全く判別できないモデルです。

2. 各種設定

モデル構造は汎用的なものを定義します。このモデルは公開されているモデルを参考にして汎用的に使用できそうなCNNモデルを定義しています。

batch_size=64, batch_sizeを小さくしすぎると結果が安定しないので64で固定します。

epochs=10、これもチューニングなどすると面倒なので固定とします。

検証方法、ホールドアウトでroc_auc_scoreで検証します。

3. 今後の工夫予定

  1. 画像データを255で割る

  2. 画像データをMinMaxScalar

  3. 画像データをStandardScalar

  4. BatchNormalizationを追加

  5. WeightNormalizationを追加

4. コード

最後にコードです。

先程も書きましたが精度は0.5で全く判別できないモデルになってしまいました。

basecnnmodel.py
import numpy as np

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.preprocessing.image import (
    load_img,
    save_img,
    img_to_array,
    array_to_img,
)
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score

def create_model(input_shape):
    model = Sequential()
    model.add(
        Conv2D(
            16,
            kernel_size=(3, 3),
            activation='relu',
            input_shape=input_shape
        )
    )
    model.add(
        Conv2D(
            32,
            (3, 3),
            activation='relu'
        )
    )
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(64, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(2, activation='softmax'))
    model.compile(
        loss='categorical_crossentropy',
        optimizer='adam',
        metrics=['accuracy']
    )
    return model

imgarrays = np.zeros(
    (2000, 20, 20, 1),
    np.uint8,
)

y = np.zeros(
    (2000, 2),
    np.uint8
)
y[:1000, 1] = 1
y[1000:, 0] = 1

for i in range(1000):
    img = load_img(
        'normalimgs/positive/normalimg_' + str(i) + '.jpg',
        color_mode='grayscale',
    )
    imgarray = img_to_array(img).astype(np.uint8)
    imgarrays[i] = imgarray

for i in range(1000):
    img = load_img(
        'normalimgs/negative/normalimg_' + str(i) + '.jpg',
        color_mode='grayscale',
    )
    imgarray = img_to_array(img).astype(np.uint8)
    imgarrays[i+1000] = imgarray

(
    X_train,
    X_test,
    y_train,
    y_test
) = train_test_split(
    imgarrays,
    y
)

clf = create_model(X_train.shape[1:])
clf.fit(
    X_train,
    y_train,
    batch_size=64,
    epochs=10
)
p = clf.predict(X_test)
score = roc_auc_score(y_test, p)
print(score)