実現したいこと
ねじの画像をkerasで学習させ、学習済みモデルをロードしました。
このモデルを用いて、テスト画像でねじを認識できるか試しています。
発生している問題・分からないこと
expected shape=(None, 300, 300, 1)とのエラーが発生している為、
ロードした配列が正しくないと推測しておりますが、対応方法がわかりません。
エラーメッセージ
error
1--------------------------------------------------------------------------- 2ValueError Traceback (most recent call last) 3<ipython-input-160-df9f9fcb6594> in <module> 4 9 5 10 #test = best_model.predict(test_img, verbose=1) 6---> 11 test = best_model.predict(test_img) 7 12 print(test) 8 9~\anaconda3\lib\site-packages\keras\src\utils\traceback_utils.py in error_handler(*args, **kwargs) 10 68 # To get the full stack trace, call: 11 69 # `tf.debugging.disable_traceback_filtering()` 12---> 70 raise e.with_traceback(filtered_tb) from None 13 71 finally: 14 72 del filtered_tb 15 16~\anaconda3\lib\site-packages\keras\src\engine\training.py in tf__predict_function(iterator) 17 13 try: 18 14 do_return = True 19---> 15 retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope) 20 16 except: 21 17 do_return = False 22 23ValueError: in user code: 24 25 File "C:\Users\user\anaconda3\lib\site-packages\keras\src\engine\training.py", line 2341, in predict_function * 26 return step_function(self, iterator) 27 File "C:\Users\user\anaconda3\lib\site-packages\keras\src\engine\training.py", line 2327, in step_function ** 28 outputs = model.distribute_strategy.run(run_step, args=(data,)) 29 File "C:\Users\user\anaconda3\lib\site-packages\keras\src\engine\training.py", line 2315, in run_step ** 30 outputs = model.predict_step(data) 31 File "C:\Users\user\anaconda3\lib\site-packages\keras\src\engine\training.py", line 2283, in predict_step 32 return self(x, training=False) 33 File "C:\Users\user\anaconda3\lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler 34 raise e.with_traceback(filtered_tb) from None 35 File "C:\Users\user\anaconda3\lib\site-packages\keras\src\engine\input_spec.py", line 298, in assert_input_compatibility 36 raise ValueError( 37 38 ValueError: Input 0 of layer "sequential_11" is incompatible with the layer: expected shape=(None, 300, 300, 1), found shape=(None, 300, 3)
該当のソースコード
python
1from tensorflow.python.keras.models import load_model 2import cv2 3 4#モデルを読み込み 5loaded_model = models.load_model('./model/model-40.h5') 6model.summary() #モデル情報を出力 7 8#画像の読み取り 9test_img = cv2.imread("img00.jpg") 10 11test = best_model.predict(test_img) 12print(test)
_ソースコード(最新)
1import cv2 2import numpy as np 3 4#モデルを読み込み 5loaded_model = models.load_model('./model/model-40.h5') 6 7# 画像の読み込み 8test_img = cv2.imread("img01.jpg") 9 10# 画像のリサイズと前処理 11resized_img = cv2.resize(test_img, (300, 300)) 12gray_img = cv2.cvtColor(resized_img, cv2.COLOR_BGR2GRAY) 13normalized_img = gray_img / 255 # 正規化 14 15input_img = np.expand_dims(normalized_img, axis=-1) # チャンネルの次元を追加 16 17# モデルの予測 18prediction = loaded_model.predict(np.array([input_img])) 19 20#結果を出力 21threshold = 0.5 22y_pred = prediction >= threshold 23print(y_pred) 24print(prediction)
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
1.テスト用画像(img00.jpg)を300*300のサイズに変更。
2.model.summary()でモデルの情報を確認しました。
Model: "sequential_13" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_55 (Conv2D) (None, 150, 150, 16) 800 max_pooling2d_55 (MaxPooli (None, 75, 75, 16) 0 ng2D) conv2d_56 (Conv2D) (None, 75, 75, 32) 4640 max_pooling2d_56 (MaxPooli (None, 37, 37, 32) 0 ng2D) conv2d_57 (Conv2D) (None, 37, 37, 64) 18496 max_pooling2d_57 (MaxPooli (None, 18, 18, 64) 0 ng2D) conv2d_58 (Conv2D) (None, 18, 18, 128) 73856 max_pooling2d_58 (MaxPooli (None, 9, 9, 128) 0 ng2D) conv2d_59 (Conv2D) (None, 9, 9, 256) 295168 max_pooling2d_59 (MaxPooli (None, 4, 4, 256) 0 ng2D) flatten_11 (Flatten) (None, 4096) 0 dense_22 (Dense) (None, 64) 262208 dropout_11 (Dropout) (None, 64) 0 dense_23 (Dense) (None, 1) 65 ================================================================= Total params: 655233 (2.50 MB) Trainable params: 655233 (2.50 MB) Non-trainable params: 0 (0.00 Byte) _________________________________________________________________
3.ご教示頂いたコードで試した結果
エラーの発生はなくなりました。
しかし、学習させたねじ画像と、何もない画像の2種類で
試したところ、どちらも同じ出力であった為、
正しく判断できていないようです。
→正規化でうまく数値の出力はできるようになりました。
尚、学習させたモデルを混同行列で検証した結果は下記通りで、
学習自体は問題なくできてそうです。
_画像前処理・正規化追加
1import cv2 2import numpy as np 3 4#モデルを読み込み 5loaded_model = models.load_model('./model/model-40.h5') 6 7# 画像の読み込み 8test_img = cv2.imread("img00.jpg") 9 10# 画像のリサイズと前処理 11resized_img = cv2.resize(test_img, (300, 300)) 12gray_img = cv2.cvtColor(resized_img, cv2.COLOR_BGR2GRAY) 13normalized_img = gray_img / 255 # 正規化 14input_img = np.expand_dims(normalized_img, axis=-1) # チャンネルの次元を追加 15 16# モデルの予測 17prediction = loaded_model.predict(np.array([input_img])) 18print(prediction)
4.出力された数値に関して
予測させた画像と出力された数値の一覧は下表の通りです。
正しく予測できていれば、「True」が出力されると思っていましたが
数値での出力なので、解釈に困っています。
出力値はねじの個数に反応してそうなのですが、
これがねじの個数を認識している数値なのか、そもそもねじを正しく認識できているのか不明です。
⇒学習時の検証画像のみでの結果を確認しました(試した事5に記載しています)
CNNの出力層
1#畳み込み層~プーリング層 2model.add(Conv2D(filters=16,kernel_size=(7,7),strides=(2,2),padding='same',activation='relu',input_shape=(300,300,1))) 3model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2))) 4 5model.add(Conv2D(filters=32,kernel_size=(3,3),activation='relu',padding='same')) 6model.add(MaxPooling2D(pool_size=(2,2),strides=(2,2))) 7 8model.add(Conv2D(filters=64, kernel_size=(3,3), activation="relu", padding="same")) 9model.add(MaxPooling2D(pool_size = (2,2), strides =(2,2))) 10 11model.add(Conv2D(filters=128, kernel_size=(3,3), activation="relu", padding="same")) 12model.add(MaxPooling2D(pool_size = (2,2), strides =(2,2))) 13 14model.add(Conv2D(filters=256, kernel_size=(3,3), activation="relu", padding="same")) 15model.add(MaxPooling2D(pool_size = (2,2), strides =(2,2))) 16 17#全結合層 18model.add(Flatten()) 19 20model.add(Dense(units=64,activation='relu')) 21model.add(Dropout(rate=0.2)) 22model.add(Dense(units=1,activation='sigmoid')) 23 24#コンパイル→ニューラルネットワークモデルの生成終了 25model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
5.学習終了後、学習時に用いた検証画像で予測させた結果
検証画像を一つずつ予測させた結果は下表の通りです。
学習時の前処理と検証時の前処理が異なる?
<結果>
・予測は8割程度合っている。
→学習の検証で用いた画像をそのまま使っているので、結果が異なる事はおかしい?
・逆さ画像は学習させても認識できない。
→学習画像数が不足している?それともこの段階で認識できないのはおかしい?
<前処理>
・学習時の前処理は正規化、リサイズ、グレースケール化を実施。
モデルロード後の前処理も同じ処理を実施。
※コードは次のURLに記載:https://teratail.com/questions/ohu1ivc9a3j5ah
補足
Python 3.8.3
回答1件
あなたの回答
tips
プレビュー