@creative-account

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

AIのモデルの精度

モデルの精度を上げたい

pythonで画像を判定するプログラムを作っているんですけど、あまり良い精度が出ません。
epochsだのvalidation_stepsだのありますが、どの回数を上げる/下げればいいのでしょう

Windows Terminal内のコマンドプロンプトでの結果

Epoch 1/100
10/10 [==============================] - 2s 163ms/step - loss: 0.7666 - accuracy: 0.5100 - val_loss: 0.6794 - val_accuracy: 0.5400
Epoch 2/100
10/10 [==============================] - 1s 97ms/step - loss: 0.6429 - accuracy: 0.5900 - val_loss: 0.5977 - val_accuracy: 0.6600
Epoch 3/100
10/10 [==============================] - 1s 106ms/step - loss: 0.5978 - accuracy: 0.6289 - val_loss: 0.5948 - val_accuracy: 0.7800
中略
Epoch 70/100
10/10 [==============================] - 1s 130ms/step - loss: 0.0772 - accuracy: 0.9700 - val_loss: 0.8683 - val_accuracy: 0.8000
中略
Epoch 95/100
10/10 [==============================] - 1s 125ms/step - loss: 0.0708 - accuracy: 0.9600 - val_loss: 0.8159 - val_accuracy: 0.8200
Epoch 96/100
10/10 [==============================] - 1s 125ms/step - loss: 0.0186 - accuracy: 1.0000 - val_loss: 1.7726 - val_accuracy: 0.6800
Epoch 97/100
10/10 [==============================] - 1s 120ms/step - loss: 0.0107 - accuracy: 1.0000 - val_loss: 1.1480 - val_accuracy: 0.7800
Epoch 98/100
10/10 [==============================] - 1s 101ms/step - loss: 0.0084 - accuracy: 1.0000 - val_loss: 1.0915 - val_accuracy: 0.7800
Epoch 99/100
10/10 [==============================] - 1s 110ms/step - loss: 0.0302 - accuracy: 0.9897 - val_loss: 1.3684 - val_accuracy: 0.7200
Epoch 100/100
10/10 [==============================] - 1s 105ms/step - loss: 0.0354 - accuracy: 0.9800 - val_loss: 1.4646 - val_accuracy: 0.7200

該当するソースコード

モデルのトレーニング

from keras.models import Sequential
from keras.layers import Activation, Dense
from keras.layers import Conv2D, MaxPooling2D, Flatten
from keras.preprocessing.image import ImageDataGenerator


def main():
    model = Sequential()
    model.add(Conv2D(64, (3, 3), input_shape=(64, 64, 3)))
    model.add(Activation("relu"))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Conv2D(64, (3, 3)))
    model.add(Activation("relu"))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Flatten())
    model.add(Dense(256))
    model.add(Activation("relu"))
    model.add(Dense(2))
    model.add(Activation("softmax"))
    # model.summary()
    model.compile(
            optimizer="adam",
            loss="categorical_crossentropy",
            metrics=["accuracy"])
    train_datagen = ImageDataGenerator(rescale=1./255)
    test_datagen = ImageDataGenerator(rescale=1./255)
    train_generator = train_datagen.flow_from_directory(
            "data/train",
            target_size=(64, 64),
            batch_size=10)
    validation_generator = test_datagen.flow_from_directory(
            "data/validation",
            target_size=(64, 64),
            batch_size=10)
    model.fit_generator(
            train_generator,
            epochs=100,
            steps_per_epoch=10,
            validation_data=validation_generator,
            validation_steps=5)
    model.save("model.h5")


if __name__ == '__main__':
    main()

判定機の方も

import sys
from PIL import Image
from keras.models import load_model
import numpy as np


def main():
    name = sys.argv[1]
    # print(name)
    image = Image.open(name)
    image = image.resize((64, 64))
    image.show()
    model = load_model("model.h5")
    np_image = np.array(image)
    np_image = np_image / 255
    np_image = np_image[np.newaxis, :, :, :]
    result = model.predict(np_image)
    # print(result)
    if result[0][0] > result[0][1]:
        print("しいたけ", end=" ")
        print(result[0][0]*100, end="%")
    else:
        print("ツキヨタケ", end=" ")
        print(result[0][1]*100, end="%")


if __name__ == '__main__':
    main()

自分で試したこと

epochsを30から100に
validation_stepsを10から5に
参考にした動画は90%の精度でした
画像は学習用が847枚で途中経過用?が104枚です。

関係ないけど記号は全角の方がいいですか?

0 likes

1Answer

まずは機械学習の原理を理解されてから取り組まれてはいかがでしょうか?

学習の経過を見る限りでは,過学習が起こっているようにみえます.それの対策として不適切なハイパーパラメータチューニングを行っているので解決出来ていないという状態です.本来early stoppingすべきシーンでepoch数を増やすなど,未勉強さが伺えます.

私的には

  • 学習率(デフォルトlearning_rate=0.001)が不適であったこと.
  • 浅いネットワークでReLUを活性化関数として適用していること.ReLUより高い精度を叩き出したSwishMishを使う余地があること.
  • 重み初期化がデフォルトのglorot_uniformであること。ReLUファミリに適しているのはhe_normalかhe_uniformであること.
  • レイヤが浅くて未学習,もしくは深すぎて過学習が起こっている.(恐らく後者)
  • 入力データに対する正規化or正則化がなされていなくてロバスト性に欠けること.

など様々な原因/改善案が考えられます.
以下の記事を読んでみて色々調整してみてはいかがでしょうか

ご健闘を祈ります.

1Like

Comments

  1. ありがとうございます。
    えっと…、記事をみにいったのですが、私には難しすぎました。頑張って記事の内容を「解読」してみようと思います
  2. 80%の精度を目指したいけどハイパーパラメータチューニングが現状難しいのであれば,一応のこと70epoch目にval_accuracyが80%出ていることを利用して,

    early_stopping
    https://qiita.com/yukiB/items/f45f0f71bc9739830002#earlystopping

    を用いて学習を止めてみるのも一手かもしれません.
    ただval_lossは増大するばかりみたいですのであまり好ましくなく,あくまで応急処置です.
    頑張ってみてください.
  3. あと1つ気になったので報告までに.

    Epoch 1/100の文字の直下にある10/10の分母は,バッチサイズから計算される数字(データ数÷バッチサイズ)であることを踏まえると,
    trainデータとして用意した約850枚,およびバッチサイズ10から考えると85/85になってないといけないと思います.10/10になっているのはもしかしたら約100枚用意しているvalidationデータをtrainデータとして使ってしまっていないでしょうか.
    確認のほどお願いします.
  4. なんか参考にした動画によると、
    「steps_per_epochで1epochのうちに行うフィッティングの回数を指定します」
    とあるので、1epoch中の回数だと思います。(10回に設定してるので。5回にしたら 5 に変わりました)
  5. そうだったのですね,お手数おかけしました.
    ぜひ精度向上へ向けて頑張ってください.

Your answer might help someone💌