質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.07%

転移学習した後のモデルで、特定の画像を予測するには?(TensorFlow)②

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 439

51sep

score 14

転移学習した後のモデルで、特定の画像を予測するには?(TensorFlow)
で質問した者です。恥ずかしながら、また分からなくなってしまい、質問させて頂きました。
公式サイト「Transfer learning with a pretrained ConvNet」を実装確認したところです。
こちらのサイトを使って、未知の画像を予測してみたいのですが方法が分かりません。出力して確認したいのは、以下の4点です。

・予測する画像の表示
・予測した確率
・予測ラベル
・正解ラベル(画像のラベル)

予測しようと思って書いみたプログラムは以下(全文)です。
最後に#case1, #case2と書いた「predict」のところです。 arrayがうまいこと配列になっていない?気がしています。(当然、np.argmaxも)
上記4点がうまいこと確認できません。勉強不足でお恥ずかしい限りです。ですが、頑張りたいと思います。
基本的なことで申し訳ないですが、どなたかアドバイスをお願いしてもよろしいでしょうか。

import os
import keras
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential, Model
from keras.layers import Input, Dense, Dropout, Activation, Flatten,MaxPooling2D,Conv2D
from keras import optimizers
import tensorflow as tf
import numpy as np
from keras.preprocessing.image import load_img, img_to_array
from keras.applications.vgg16 import preprocess_input

# 分類クラス
classes = ['cat1','cat2','cat3']
nb_classes = len(classes)
batch_size_for_data_generator = 20

base_dir = "XXX"

train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
test_dir = os.path.join(base_dir, 'test')

train_1_dir = os.path.join(train_dir, '1')
train_2_dir = os.path.join(train_dir, '2')
train_3_dir = os.path.join(train_dir, '3')

validation_1_dir = os.path.join(validation_dir, '1')
validation_2_dir = os.path.join(validation_dir, '2')
validation_3_dir = os.path.join(validation_dir, '3')

test_1_dir = os.path.join(test_dir, '1')
test_2_dir = os.path.join(test_dir, '2')
test_3_dir = os.path.join(test_dir, '3')

# 画像サイズ
img_rows, img_cols = 200, 200

train_datagen = ImageDataGenerator(rescale=1.0 / 255,shear_range=0.2,zoom_range=0.2,horizontal_flip=True)
train_generator = train_datagen.flow_from_directory(directory=train_dir,target_size=(img_rows, img_cols),color_mode='rgb',batch_size=batch_size_for_data_generator,shuffle=True)

test_datagen = ImageDataGenerator(rescale=1.0 / 255)  
validation_generator = test_datagen.flow_from_directory(directory=validation_dir,target_size=(img_rows, img_cols),color_mode='rgb',batch_size=batch_size_for_data_generator,shuffle=True)

IMG_SHAPE = (224, 224, 3)
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                               include_top=False, 
                                               weights='imagenet')
base_model.trainable = False

maxpool_layer = tf.keras.layers.GlobalMaxPooling2D()
prediction_layer = tf.keras.layers.Dense(1)

learning_rate = 0.0001
model = tf.keras.Sequential([
    base_model,
    maxpool_layer,
    prediction_layer
])

base_learning_rate = 0.0001
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=base_learning_rate),
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])
model.summary()

initial_epochs = 10
validation_steps=20
loss0,accuracy0 = model.evaluate(validation_generator, steps = validation_steps)

history = model.fit(train_generator,
                    epochs=initial_epochs,
                    validation_data=validation_generator)

base_model.trainable = True

for layer in base_model.layers[:100]:
  layer.trainable =  False

print("Number of layers in the base model: ", len(base_model.layers))

model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              optimizer = tf.keras.optimizers.RMSprop(lr=base_learning_rate/10),
              metrics=['accuracy'])
model.summary()

fine_tune_epochs = 10
total_epochs =  initial_epochs + fine_tune_epochs

history_fine = model.fit(train_generator,
                         epochs=total_epochs,
                         initial_epoch =  history.epoch[-1],
                         validation_data=validation_generator)

#case1
filename = os.path.join('XXX/', 'XXX.png')
filename

img = load_img(filename, target_size=(224, 224))
x = img_to_array(img)
x = np.expand_dims(x, axis=0)

predict = model.predict(preprocess_input(x))
predict
#array([[4.345547]], dtype=float32)

#case2
print(model.predict(validation_generator)[0])
#[-2.2691705]


使用した画像のサンプル使用した画像のサンプル

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • tabuu

    2020/02/20 16:42

    求めているレベル感が分かりませんが、転移学習を実施することによって正答率がどのように変わるかを試してみたいということであれば以下のページの方が分かり易いと思います。
    https://qiita.com/windows222/items/c7084b1ad0d51971d2b7

    キャンセル

  • Q71

    2020/02/20 17:52

    前の質問には「ThesorFlow、機械学習の初学者です。」と書かれています。転移学習ができるほど、学習が済んでいるのですか。それなら、任意の画像を推測させることもできているのではないですか。
    一歩ずつ、確実に進みましょう。おそらく、機械学習とプログラミング、Pythonコードの3つを同時に進めようとされていると思います。だからこそ余計に、一歩を小さく確実に進めなければなりません。
    試したこと、やったこと、できたことを整理してください。

    キャンセル

  • 51sep

    2020/02/22 08:21

    tabuuさん、情報をありがとうございました。
    恥ずかしながら私は低レベルです。。頑張ります。

    Q71さん、コメントをありがとうございました。
    お言葉ごもっともです。転移学習ができるほど、学習は済んでいませんし、機械学習とプログラミングを同時に学ぶ状況にいます。最初の質問で解決すべきでしたが、力不足でした。前の回答者さんも呆れていることでしょう。でも、頑張ります。

    キャンセル

回答 1

0

はじめてのニューラルネットワーク:分類問題の初歩

モデルの訓練が終わったら、そのモデルを使って画像の分類予測を行うことが出来ます。

にあるコード

predictions = model.predict(test_images)


をして、このpredictionsを見たら、という話でしょうか。
あなたぼ横にいる人には、ここに書いてあることで答えが返ってくるかもしれません。あなたが喋らなくてもあなたの手元にあるコードを覗き込めるのですから。
ネットワークの向こうにいる人にそれはできないので、あなたがしたことを1から、10とまでは言わないけれど、8くらいは書いてもらえないとわかりません。

さて、以前の質問も含めて、いろいろ変更されていると思います。変更点を洗い出して下さい。
チュートリアルは、複数の画像を一度に推論していますが、あなたはそれを単一の画像を推論できるように変更しているのではないですか?そうであれば、自分が何をどう変えたのかよく考えて下さい。


参考にされたTransfer learning with a pretrained ConvNetには、こう書かれています。

In this tutorial, you will learn how to classify images of cats and dogs by using transfer learning from a pre-trained network.

「犬と猫を分類する」と。これは、2クラス分類です。以前の質問で参考にされたはじめてのニューラルネットワーク:分類問題の初歩は、ファッションMNISTで、こちらは10クラス分類です。分類するクラス数はいくつでも良いのですが、2クラスの時だけ、注意が必要です。
犬と猫に分類します。与えられる画像は、馬が混ざっていても良いのですが、モデルは犬と猫しか知らないので、馬であっても犬か猫、どちらか似ている方へ分類します。ここで、「犬である確率は60%」と推論したとしましょう。では、猫である確率は、いくらですか。それを、どうやって計算しますか。もちろん、100-60=40で、猫である確率は40%です。ですから、2クラス分類に限り、最終層の出力がクラス数ではなく、1でもかまわないのです。
あなたは、何クラスの分類をしたいのでしょうか。そのクラスに合わせた出力をして下さい。
また、最終層の出力をsoftmax関数にかけることをお忘れ無く。

ということで、自分が何をしたいのか、参考にしているページが何をしようとしているのか、しっかり抑えて下さい。


畳み込みネットワークを使った分類は、畳み込み層で特徴を抽出し、パーセプトロン層で分類します。
転移学習は、畳み込み層(の係数)は学習せず、パーセプトロン(の係数)を作り替えます。よって、畳み込み層で特徴抽出ができなければ、転移学習は成功しません。
今回、元のネットワークは「カラーの犬と猫」で、転移で学習しようとしたのは「グレースケールの数字」です。そうすると、特徴が全く異なるので、「グレースケールの数字」を分類するために必要な特徴が抽出できないことが考えられます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/29 08:12

    進捗報告しておきます。
    あれから、上記のWarningは解消できました。
    しかしながら、accuracyは低いままで予測もひどい。依然として「ちゃんと学習」ができているのか疑問が残ります。
    そもそも例数も少ないので、何とも言えませんが、他のプログラムでは同じ画像で高い正確度を出しているので、やはり、今回はうまくいっていないのかなと思ってしまいます。
    正確度を上げる問題は、また勉強が必要そうです。

    キャンセル

  • 2020/03/18 04:23

    Q71さん、回答の更新をどうもありがとうございました。
    進捗報告しておきます。
    あれから、予測の仕方はだいぶ分かってきました。
    次のステップとして、accuracyの改善を考えていました。
    モデルを間違えていたので、そこを修正したところaccuracyはあがりましたが、
    ちゃんと学習できているかわかりませんでした。
    とりあえず、2値に戻って確認しようと思いまして、画像データを「1」「3」としました。
    モデルは公式のものに戻しまして、実行したところ、以下のようにlossもaccuracyも変わらず。
    学習率を変えても改善せず。。
    やはり、Q71さんのご指摘の通り「特徴が全く異なるので、「グレースケールの数字」を分類するために必要な特徴が抽出できないことが考えられます。」なのかもしれません。

    そうである場合、次のアプローチはどのようにしたらよいのでしょうか。
    もしまだこの質問が生きていたら、ご助言をいただけると嬉しく思います。

    Epoch 1/10
    2/2 [==============================] - 9s 5s/step - loss: 7.6666 - accuracy: 0.5000 - val_loss: 7.6666 - val_accuracy: 0.5000
    Epoch 2/10
    2/2 [==============================] - 6s 3s/step - loss: 7.6666 - accuracy: 0.5000 - val_loss: 7.6666 - val_accuracy: 0.5000
    省略
    Epoch 9/10
    2/2 [==============================] - 7s 3s/step - loss: 7.6666 - accuracy: 0.5000 - val_loss: 7.6666 - val_accuracy: 0.5000
    Epoch 10/10
    2/2 [==============================] - 6s 3s/step - loss: 7.6666 - accuracy: 0.5000 - val_loss: 7.6666 - val_accuracy: 0.5000

    キャンセル

  • 2020/03/20 07:47

    エポックが進んでも、acc、loss共に変化していないので、まったく学習できていません。
    まず、参考サイトそのままのコードは動作したでしょうか。まずは真似ましょう。守
    それから、データを、元の主旨に沿ったまま、つまり犬猫なら自分で探してきた犬猫に変えてみましょう。破
    その後、自分の目的に沿ったものに変えていきます。離

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.07%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る