悩んでいる事・解決したいこと
現在、こちらのサイト 乃木坂メンバーの顔をCNNで分類を参考にしながら、機械学習を行ってサッカー選手の顔を識別するプログラムを書いています。
機械学習を行う部分(learn.py)までは正しく実行できたものの、テストを行うtest4.py(上記サイトにおけるpredict.py)部分で下記のようなエラーが出てしまいました。
学習したモデルの精度などを検証したいので、このテスト用プログラムを動かしたいです。
load_modelの部分でエラーが出ているので、学習したモデルを読み込む部分でエラーが起きていることはわかったのですが、対象方法と原因が分からないので教えていただきたいです。
最近になってpythonと機械学習について学び始めたので知識も浅いうえ、初めての質問でつたない部分が多いと思いますが、何卒よろしくお願いいたします。
発生している問題・エラーメッセージ
Traceback (most recent call last): File "test4.py", line 49, in <module> model = load_model('./my_model.h5') File "C:\venv\tf115py36\lib\site-packages\keras\engine\saving.py", line 492, in load_wrapper return load_function(*args, **kwargs) File "C:\venv\tf115py36\lib\site-packages\keras\engine\saving.py", line 584, in load_model model = _deserialize_model(h5dict, custom_objects, compile) File "C:\venv\tf115py36\lib\site-packages\keras\engine\saving.py", line 273, in _deserialize_model model_config = json.loads(model_config.decode('utf-8')) AttributeError: 'str' object has no attribute 'decode'
該当のソースコード
学習用プログラム(learn.py)
python
1import os 2import cv2 3import numpy as np 4import h5py 5import matplotlib.pyplot as plt 6from keras.layers import Activation, Conv2D, Dense, Flatten, MaxPooling2D 7from keras.models import Sequential 8from keras.utils.np_utils import to_categorical 9 10name = ["kane","keisuke","sissoko"] 11 12# 教師データのラベル付け 13X_train = [] 14Y_train = [] 15for i in range(len(name)): 16 img_file_name_list=os.listdir("c:/venv/tf115py36/soccer/train/"+name[i]) 17 print(len(img_file_name_list)) 18 for j in range(0,len(img_file_name_list)-1): 19 n=os.path.join("./train/"+name[i]+"/",img_file_name_list[j]) 20 img = cv2.imread(n) 21 b,g,r = cv2.split(img) 22 img = cv2.merge([r,g,b]) 23 X_train.append(img) 24 Y_train.append(i) 25 26# テストデータのラベル付け 27X_test = [] # 画像データ読み込み 28Y_test = [] # ラベル(名前) 29for i in range(len(name)): 30 img_file_name_list=os.listdir("./test/"+name[i]) 31 print(len(img_file_name_list)) 32 for j in range(0,len(img_file_name_list)-1): 33 n=os.path.join("./test/"+name[i]+"/",img_file_name_list[j]) 34 img = cv2.imread(n) 35 b,g,r = cv2.split(img) 36 img = cv2.merge([r,g,b]) 37 X_test.append(img) 38 # ラベルは整数値 39 Y_test.append(i) 40X_train=np.array(X_train) 41X_test=np.array(X_test) 42 43 44y_train = to_categorical(Y_train) 45y_test = to_categorical(Y_test) 46 47# モデルの定義 48model = Sequential() 49model.add(Conv2D(input_shape=(64, 64, 3), filters=32,kernel_size=(3, 3), 50 strides=(1, 1), padding="same")) 51model.add(MaxPooling2D(pool_size=(2, 2))) 52model.add(Conv2D(filters=32, kernel_size=(3, 3), 53 strides=(1, 1), padding="same")) 54model.add(MaxPooling2D(pool_size=(2, 2))) 55model.add(Conv2D(filters=32, kernel_size=(3, 3), 56 strides=(1, 1), padding="same")) 57model.add(MaxPooling2D(pool_size=(2, 2))) 58model.add(Flatten()) 59model.add(Dense(256)) 60model.add(Activation("sigmoid")) 61model.add(Dense(128)) 62model.add(Activation('sigmoid')) 63model.add(Dense(3)) 64model.add(Activation('softmax')) 65 66# コンパイル 67model.compile(optimizer='sgd', 68 loss='categorical_crossentropy', 69 metrics=['accuracy']) 70 71# 学習 72history = model.fit(X_train, y_train, batch_size=32, 73 epochs=70, verbose=1, validation_data=(X_test, y_test)) 74 75# 汎化制度の評価・表示 76score = model.evaluate(X_test, y_test, batch_size=32, verbose=0) 77print('validation loss:{0[0]}\nvalidation accuracy:{0[1]}'.format(score)) 78 79#acc, val_accのプロット 80plt.plot(history.history["accuracy"], label="acc", ls="-", marker="o") 81plt.plot(history.history["val_accuracy"], label="val_acc", ls="-", marker="x") 82plt.ylabel("accuracy") 83plt.xlabel("epoch") 84plt.legend(loc="best") 85plt.show() 86 87#モデルを保存 88model.save("my_model.h5")
テスト用プログラム(test4.py)
python
1import numpy as np 2import matplotlib.pyplot as plt 3import cv2 4from keras.models import load_model 5import sys 6 7def detect_face(image): 8 print(image.shape) 9 #opencvを使って顔抽出 10 image_gs = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 11 cascade = cv2.CascadeClassifier("c:/pytools/opcs/cascades/haarcascade_frontalface_alt.xml") 12 # 顔認識の実行 13 face_list=cascade.detectMultiScale(image_gs, scaleFactor=1.1, minNeighbors=2,minSize=(64,64)) 14 #顔が1つ以上検出された時 15 if len(face_list) > 0: 16 for rect in face_list: 17 x,y,width,height=rect 18 cv2.rectangle(image, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (255, 0, 0), thickness=3) 19 img = image[rect[1]:rect[1]+rect[3],rect[0]:rect[0]+rect[2]] 20 if image.shape[0]<64: 21 print("small") 22 continue 23 img = cv2.resize(image,(64,64)) 24 img=np.expand_dims(img,axis=0) 25 name = detect_who(img) 26 cv2.putText(image,name,(x,y+height+20),cv2.FONT_HERSHEY_DUPLEX,1,(255,0,0),2) 27 #顔が検出されなかった時 28 else: 29 print("no face") 30 return image 31 32def detect_who(img): 33 #予測 34 name="" 35 print(model.predict(img)) 36 nameNumLabel=np.argmax(model.predict(img)) 37 if nameNumLabel== 0: 38 name="kane" 39 elif nameNumLabel==1: 40 name="keisuke" 41 elif nameNumLabel==2: 42 name="sissoko" 43 return name 44 45 46if __name__ == '__main__': 47 48 model = load_model('./my_model.h5') 49 50 if len(sys.argv) != 2: 51 print('invalid argment') 52 sys.exit() 53 else: 54 im_jpg = sys.argv[1] 55 image=cv2.imread("./predict/"+im_jpg) 56 if image is None: 57 print("None image:") 58 b,g,r = cv2.split(image) 59 image = cv2.merge([r,g,b]) 60 whoImage=detect_face(image) 61 62 plt.imshow(whoImage) 63 plt.show()
試したこと
・エラーの内容の検索
AttributeError: 'str' object has no attribute 'decode'で検索してみたものの効果的な対象方法は見つかりませんでした。
・kerasの公式ドキュメントを読む
Keras FAQ: Kerasに関するよくある質問
こちらを読んでみたところ、モデルと重みを分けて保存・ロードする方法も書かれていたので、下記のように試してみました。
・JSON形式でのモデルの保存とロード
上記のドキュメントとこちらのサイトを参考にしました
Kerasで作成したモデルのアーキテクチャと重みの保存/読み込み方法
結果としては
モデルの構成確認 model.summary()までは実行されるものの、モデルの重みを読み込む部分(model.load_weights)で同様のエラーが出ました。
json形式で保存したモデルの構成は表示されていることから、json形式でモデルの保存自体はできているということ・h5形式のファイルの保存・読み込みに問題があることが推測できました。
しかし、結局エラーへの対処方法はわかりませんでした。
補足情報(FW/ツールのバージョンなど)
windows10 pro 64bit
python3.6.8
tensorflow1.15
keras 2.3.1
あなたの回答
tips
プレビュー