Help us understand the problem. What is going on with this article?

2クラス分類から多クラス分類への変更

More than 1 year has passed since last update.

前回、自分のデータセットで品と不良品の判別をやってみました。
前回は『PythonとKerasによるディープラーニング』のサンプルに忠実に2クラス分類でやりましたが、今回は出力に「良品」と「不良品」の2つを独立して設定し、どうなるのか試してみました。
実装上の違いは

  • モデルの最終層のカテゴリ数が1 → 2
  • モデルの最終層の活性化関数がsigmoid → softmax
  • 損失関数がbinary_crossentropy → categorical_crossentropy
  • ImageDataGeneratorのオプションclass_modeがbinary → categorical

です。

使用するデータセットは前回と同じで、モデル構成やハイパーパラメータも極力同じにしました。

モデル定義

モデル定義の部分は下記のように変更しました。

# モデルの定義
model = models.Sequential()
model.add(layers.Conv2D(16, (3, 3), activation='relu', input_shape=(120, 40, 1)))
model.add(layers.Conv2D(16, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(32, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(256, activation='relu'))
#model.add(layers.Dense(1, activation='sigmoid'))        # ひとまず犬猫と同じ2クラス分類で
model.add(layers.Dense(2, activation='softmax'))         # 今回は多クラス分類で

# モデルのコンパイル
#model.compile(loss='binary_crossentropy',
model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])

model.summary()で確認すると次のようになります。

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 118, 38, 16)       160       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 116, 36, 16)       2320      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 58, 18, 16)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 56, 16, 32)        4640      
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 28, 8, 32)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 7168)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               3670528   
_________________________________________________________________
dense_2 (Dense)              (None, 256)               131328    
_________________________________________________________________
dense_3 (Dense)              (None, 2)                 514       
=================================================================
Total params: 3,809,490
Trainable params: 3,809,490
Non-trainable params: 0
_________________________________________________________________

前回と比較すると、最終層のパラメータが増えていることが確認できます。

ImageDataGeneratorの準備

多クラス分類では正解ラベルの与え方も変わるので変更が必要です。

# すべての画像を1/255でスケーリング
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

# ImageDataGeneratorを使ってディレクトリから画像を読み込む(リスト5-7)
train_generator = train_datagen.flow_from_directory(
    train_dir,                      # ターゲットディレクトリ
    target_size=(120, 40),          # すべての画像サイズを120*40に変更
    color_mode='grayscale',
    batch_size=20,                  # バッチサイズ
#   class_mode='binary')            # binary_crossentropyを使用するため2値のラベルが必要
    class_mode='categorical')       # categoricalに変更
validation_generator = test_datagen.flow_from_directory(
    validation_dir,
    target_size=(120, 40),
    color_mode='grayscale',
    batch_size=20,
    class_mode='categorical')

モデルの学習

前回からの変更点は以上です。
これで学習を実行したところ、次のような結果となりました。
前回同様、今回も高い精度が出て、うまくいったようです。

 88/100 [=========================>....] - ETA: 0s - loss: 0.0222 - acc: 0.9966
 90/100 [==========================>...] - ETA: 0s - loss: 0.0219 - acc: 0.9967
 92/100 [==========================>...] - ETA: 0s - loss: 0.0235 - acc: 0.9962
 94/100 [===========================>..] - ETA: 0s - loss: 0.0266 - acc: 0.9952
 96/100 [===========================>..] - ETA: 0s - loss: 0.0262 - acc: 0.9953
 98/100 [============================>.] - ETA: 0s - loss: 0.0259 - acc: 0.9954
100/100 [==============================] - 4s 43ms/step - loss: 0.0271 - acc: 0.9950 - val_loss: 0.0270 - val_acc: 0.9970

Figure_1.png
Figure_2.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした