2000点程度の画像データを使ってランク付けのモデルを作ろうとしています。
画像データは1~5段階で評価されており、順序尺度です。
https://stackoverflow.com/questions/38375401/neural-network-ordinal-classification-for-age
https://www.kaggle.com/c/diabetic-retinopathy-detection/discussion/13115
を参考に、スコアをそれぞれ{1: [0,0,0,0], 2: [1,0,0,0], 3: [1,1,0,0], 4: [1,1,1,0], 5: [1,1,1,1]}
としてエンコーディングしました。
画像は(224, 224)にリサイズしました。preprocess_input
を行うと特徴が消えたので採用しませんでした。
転移学習を行うためKerasの持つ学習済みモデルでをいくつか検証し、Resnetを用いると良さそうだったので以下の様に画像を学習済みモデルで特徴量変換してモデルを作成しました。
マルチラベル分類を参考にsigmoidで出力、binary_crossentropy損失を使っています。
python
1model = resnet.ResNet152(weights='imagenet', include_top=False, pooling="avg") 2data_feature = model.predict(image_data) 3# 2xxx/2xxx [==============================] - 88s XXms/sample 4 5train_x, test_x, train_y, test_y = train_test_split(data_feature, encorded_score) 6 7model=Sequential() 8model.add(Input(2048)) 9model.add(Dense(256, activation="relu")) 10model.add(Dropout(0.5)) 11model.add(Dense(4, activation="sigmoid")) 12model.compile(optimizer="adam", 13 loss="binary_crossentropy", 14 metrics=[total_acc]) 15 16history = model.fit(train_x, train_y, epochs=100, batch_size=16,validation_split=0.1) 17# Epoch 1/100 18# 1800/1800 [==============================] - 0s 273us/sample - loss: 0.1397 - total_acc: 0.7600 - val_loss: 0.2168 - val_total_acc: 0.6567 19# 中略、バリデーションの精度は変わらない 20# Epoch 100/100 21# 1800/1800 [==============================] - 0s 238us/sample - loss: 0.0646 - total_acc: 0.9039 - val_loss: 0.2837 - val_total_acc: 0.6667
この特徴抽出モデルと全結合のモデルをつなげると同じ精度がでず、不思議に思っています。
畳み込み層を凍結させて同じ形の全結合層とつなぎました。
python
1conv_model = resnet.ResNet152(weights='imagenet', include_top=False, pooling="avg",input_shape=(224,224,3)) 2conv_model.trainable = False 3 4top_model = Sequential() 5top_model.add(Input(2048)) 6top_model.add(Dense(256, activation="relu")) 7top_model.add(Dropout(0.5)) 8top_model.add(Dense(4, activation="sigmoid")) 9 10model = Sequential([conv_model,top_model]) 11 12model.compile(optimizer="adam", 13 loss="binary_crossentropy", 14 metrics=[total_acc]) 15 16train_x, test_x, train_y, test_y = train_test_split(image_data, encorded_score) 17history = model.fit(train_x, train_y, epochs=20, batch_size=16,validation_split=0.1) 18 19# Epoch 1/20 20# 2160/2160 [==============================] - 99s 46ms/sample - loss: 0.4650 - total_acc: 0.3463 - val_loss: 0.4620 - val_total_acc: 0.2780 21# 中略、バリデーションの精度は変わらない 22# Epoch 20/20 23# 2160/2160 [==============================] - 98s 46ms/sample - loss: 0.2599 - total_acc: 0.5963 - val_loss: 0.5168 - val_total_acc: 0.3320
私の理解ではこの2つはやっていることはほぼ同じという理解なのですが、学習を行う上でどのような違いがあるのでしょうか?
バリデーションの精度が上がらないのはなぜでしょうか?コードの間違いでしょうか?転移学習に対する理解が違うのでしょうか?
2番目のモデルで上手くいけば画像の水増しやファインチューニングを試そうと思っています。
この2つのモデルの違い、精度を上げる方法、コードの不適切な点等、ご教授いただきたいです。
tensorflow version2.1.0のtf.kerasを使っています。
宜しくお願いします。
追記
仕方ないので特徴ベクトルで学習させた全結合層と畳み込み層(imagenet学習済みResnet)を結合させてFine tuningを行ってみましたが、
不思議な結果になりました。
python
1model.evaluate(test_image, test_encord) 2# [0.2531382454914993, 0.6142322] 3model.fit(train_image, train_encord, epochs=3, batch_size=16,validation_split=0.1) 4# 2160/2160 [==============================] - 93s 43ms/sample - loss: 1.5922 - total_acc: 0.2333 - val_loss: 0.2954 - val_total_acc: 0.5643 5model.evaluate(test_image, test_encord) 6# [0.2892280397343725, 0.54681647] 7model.evaluate(train_image, train_encord) 8# [0.2311001866869706, 0.6222407]
悪い方向に学習するだけでなく、進捗で表示される結果とevaluateの結果が異なる等、何が起きているのか良く分かりません。
バグのような気もしてきたので環境を変えてみようかと思いますが、質問は数日で打ち切らせていただき、Tensorflowのコミュニティで聞いてみることにします。ありがとうございました。
あなたの回答
tips
プレビュー