[深さ学習]手話動作学習モデルの構築(LSTM)
前回の記事で収集したデータセットでLSTMで勉強し、結果を確認したいと思います.
:npyファイルはデータを生成します.
資料は一般的に数値型資料(数値資料)と範疇型資料(分類資料)に分けられる. 数値型データ(数値型データ) 観測値は数値で測定した資料である.(身長、体重、成績、事件数など) 量子化データとも呼ばれる. 観測値の性質から,数値型資料を連続型資料(連続データ)と離散型資料(離散データ)に分類した. 分類資料
-観測結果がいくつかのカテゴリーまたは項目の形式で現れる資料を指す.(ex.性別(男性、女性)、好み、血液型、地域など.)
-品質資料(定性的データ)とも呼ばれます.
-カテゴリ型資料は数値型資料のように表現できる.(ex.好みでは、良い3、普通の2、嫌いな1)ですが、数値型資料のように、好みごとの大きさが1つしか違わないわけではありませんし、良いものと嫌いなものの3倍ではありません.
-順位型資料(シーケンスデータ)と名義型資料(名義データ)に分けることができる.順位型資料は好みのように資料に順序があり、名目型資料は血液型のように順序が存在しない.
機械学習アルゴリズム分類データ(テキスト)を数値データに変換する処理手順 .分類符号化では、Label EncodeとOne-Hot Encodeに大別される. Label Encodeはアルファベット順にソートされ、ソート基準番号によってソートされます.しかしlabel符号化の欠点は,名目型資料型では行番号のデジタル情報がモデルに誤って反映される可能性があることである. One-Hot Encodeは、n個のカテゴリデータをn個のビット(0,1)ベクトルとして表す.簡単に言えば、1つの要素がtrueであり、残りの要素がfalseである方法しかありません.しかしOne-Hot Encodingの欠点は,Dummy VariableTrapと呼ばれる変数の結果が他の変数の助けによって容易に予測できることである. One-Hot Encodeは名目データに用いられ、固有値が多くない場合に用いられ、Label Encodeはランキングデータに用いられる.
トレーニングセットは90%、テストセットは10%に設定されています. sklearn(scikit-learn)のインストール方法 cmd,
私はの勉強をしましたが、参考資料によると正確率は100%で、私の正確率は約67%しかありません.私は不思議に思って、もう一度行います.
2回目の試みはで約93%であった.
なぜを学ぶたびに精度が違うのでしょうか.
一次epochとは、人工ニューラルネットワークにおいてデータセット全体を前方/後方に伝達するプロセスを指す. (データセット全体の学習が完了しました)
しかし驚くべきグラフを見ました...ショックを受けました. それでもテストしたいpyを行いました. ですがtestです.pyで次のエラーが発生しました.model.h 5ファイルが存在しないという意味で、モデルです.h 5はモデルサブフォルダによく存在し、train.ipynbを実行している間はよく動いていましたが、突然エラーが発生してパニックになりました. 今回の精度は約96%だった.
グラフはさっきのグラフとは全然違います.
しかし、なぜ学習が100%の精度に達しなかったのか、グラフの形がそうだったのか知りたい.
ですがtestです.pyで同じエラーが発生しました.model.h 5ファイルを移動し、パスも変更しましたが、同じです.
#1
解決策
https://stackoverflow.com/questions/61699140/oserror-savedmodel-file-does-not-exist-at-dnn-mpg-model-h5-saved-model-pbt/65014543#65014543
https://arca.live/b/programmers/44902070?p=1
解決策NodeJSで実行されているPythonShellはH 5モデルではなくSavedModelのみを読み込むことができます.
https://blog.naver.com/PostView.naver?blogId=heyji1230&logNo=222146936643&redirect=Dlog&widgetTypeCall=true&directAccess=false
https://www.tensorflow.org/guide/keras/save_and_serialize?hl=ko
したがって、上記の列車はモデルをh 5に保存するため、コードをsavedmodelに変換する必要がある.ipynbに追加します.
しかし、同じエラーが発生しました.Google検索中、savedModelをロードする関数とh 5をロードする関数が異なることに気づき、関連内容を調べました.
https://www.tensorflow.org/api_docs/python/tf/saved_model/load:Loading Kerasモデルを参照.
test.pyロードモデルのコードを次のコードに変更します. =>>トラブルシューティング!
#2のエラーを解決し、実行後にWebカメラを開いたが、手話動作を行った場合、以下のエラーが発生して終了する. このエラーをcallメソッドがないために発生したと呼ぶ.callメソッドを追加することで、複数の資料でエラーを解決できるという.
https://lifesaver.codes/answer/subclass-of-tf-keras-model-throws-notimplementederror-when-fit-with-custom-data-43173
トラブルシューティング中
[基礎統計]数値型データと分類型データ
機械学習-epoch,batchsize,反復の意義
データセット
学習LSTM(train.ipynb)
actions = [
'a',
'b',
'c'
]
data = np.concatenate([
np.load('dataset/seq_a_1650133564.npy'),
np.load('dataset/seq_b_1650133564.npy'),
np.load('dataset/seq_c_1650133564.npy')
], axis=0)
data.shape
->作成したデータセットをロードし、1つにマージします.x_data = data[:, :, :-1]
labels = data[:, 0, -1]
print(x_data.shape)
print(labels.shape)
->データセットにはlabel値が含まれます.最後の値はlabel値なので削除し、最後の値だけをlabelとして分離します.from tensorflow.keras.utils import to_categorical
y_data = to_categorical(labels, num_classes=len(actions))
y_data.shape
->One-hot符号化.keras to分類の使用ここでちょっと待ってください。
分類データとは?
-観測結果がいくつかのカテゴリーまたは項目の形式で現れる資料を指す.(ex.性別(男性、女性)、好み、血液型、地域など.)
-品質資料(定性的データ)とも呼ばれます.
-カテゴリ型資料は数値型資料のように表現できる.(ex.好みでは、良い3、普通の2、嫌いな1)ですが、数値型資料のように、好みごとの大きさが1つしか違わないわけではありませんし、良いものと嫌いなものの3倍ではありません.
-順位型資料(シーケンスデータ)と名義型資料(名義データ)に分けることができる.順位型資料は好みのように資料に順序があり、名目型資料は血液型のように順序が存在しない.
分類符号化、一次熱符号化とは何ですか?
from sklearn.model_selection import train_test_split
x_data = x_data.astype(np.float32)
y_data = y_data.astype(np.float32)
x_train, x_val, y_train, y_val = train_test_split(x_data, y_data, test_size=0.1, random_state=2021)
print(x_train.shape, y_train.shape)
print(x_val.shape, y_val.shape)
->トレーニングセットとテストセットを配布します.sklearningを使用したtrain test splitトレーニングセットは90%、テストセットは10%に設定されています.
pip install scikit-lean
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
model = Sequential([
LSTM(64, activation='relu', input_shape=x_train.shape[1:3]), # node 개수 64개
Dense(32, activation='relu'), # node 개수 32개
Dense(len(actions), activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc']) # loss='categorical_crossentropy -> 3개의 action 중 어떤 건지 모델에게 추론하게 함
model.summary()
->モデル定義、シーケンスAPIを使用し、LSTMとDENSEを接続します.from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau
history = model.fit(
x_train,
y_train,
validation_data=(x_val, y_val),
epochs=200,
callbacks=[
ModelCheckpoint('models/model.h5', monitor='val_acc', verbose=1, save_best_only=True, mode='auto'),
ReduceLROnPlateau(monitor='val_acc', factor=0.5, patience=50, verbose=1, mode='auto')
]
)
->学習過程、200回epochを回転します.学習が完了したら、モデルを保存します.私は
ここでちょっと待ってください。
epochとは?
One Epoch is when an ENTIRE dataset is passed forward and backward through the neural network only ONCE
import matplotlib.pyplot as plt
fig, loss_ax = plt.subplots(figsize=(16, 10))
acc_ax = loss_ax.twinx()
loss_ax.plot(history.history['loss'], 'y', label='train loss')
loss_ax.plot(history.history['val_loss'], 'r', label='val loss')
loss_ax.set_xlabel('epoch')
loss_ax.set_ylabel('loss')
loss_ax.legend(loc='upper left')
acc_ax.plot(history.history['acc'], 'b', label='train acc')
acc_ax.plot(history.history['val_acc'], 'g', label='val acc')
acc_ax.set_ylabel('accuracy')
acc_ax.legend(loc='upper left')
plt.show()
勉強が終わったらグラフを描く.Test (test.py)
import cv2
import mediapipe as mp
import numpy as np
from tensorflow.keras.models import load_model
actions = ['a', 'b', 'c']
seq_length = 30
model = load_model('models/model.h5')
# MediaPipe hands model
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
hands = mp_hands.Hands(
max_num_hands=1,
min_detection_confidence=0.5,
min_tracking_confidence=0.5)
cap = cv2.VideoCapture(0)
# w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
# out = cv2.VideoWriter('input.mp4', fourcc, cap.get(cv2.CAP_PROP_FPS), (w, h))
# out2 = cv2.VideoWriter('output.mp4', fourcc, cap.get(cv2.CAP_PROP_FPS), (w, h))
seq = []
action_seq = []
while cap.isOpened():
ret, img = cap.read()
img0 = img.copy()
img = cv2.flip(img, 1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
result = hands.process(img)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
if result.multi_hand_landmarks is not None:
for res in result.multi_hand_landmarks:
joint = np.zeros((21, 4))
for j, lm in enumerate(res.landmark):
joint[j] = [lm.x, lm.y, lm.z, lm.visibility]
# Compute angles between joints
v1 = joint[[0,1,2,3,0,5,6,7,0,9,10,11,0,13,14,15,0,17,18,19], :3] # Parent joint
v2 = joint[[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20], :3] # Child joint
v = v2 - v1 # [20, 3]
# Normalize v
v = v / np.linalg.norm(v, axis=1)[:, np.newaxis]
# Get angle using arcos of dot product
angle = np.arccos(np.einsum('nt,nt->n',
v[[0,1,2,4,5,6,8,9,10,12,13,14,16,17,18],:],
v[[1,2,3,5,6,7,9,10,11,13,14,15,17,18,19],:])) # [15,]
angle = np.degrees(angle) # Convert radian to degree
d = np.concatenate([joint.flatten(), angle])
seq.append(d)
mp_drawing.draw_landmarks(img, res, mp_hands.HAND_CONNECTIONS)
if len(seq) < seq_length:
continue
input_data = np.expand_dims(np.array(seq[-seq_length:], dtype=np.float32), axis=0)
y_pred = model.predict(input_data).squeeze()
i_pred = int(np.argmax(y_pred))
conf = y_pred[i_pred]
if conf < 0.9:
continue
action = actions[i_pred]
action_seq.append(action)
if len(action_seq) < 3:
continue
this_action = '?'
if action_seq[-1] == action_seq[-2] == action_seq[-3]:
this_action = action
cv2.putText(img, f'{this_action.upper()}', org=(int(res.landmark[0].x * img.shape[1]), int(res.landmark[0].y * img.shape[0] + 20)), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=(255, 255, 255), thickness=2)
# out.write(img0)
# out2.write(img)
cv2.imshow('img', img)
if cv2.waitKey(1) == ord('q'):
break
Traceback (most recent call last):
File "c:/Users/JH/Documents/VSCodeSonsuProjects/GESTURE_RECOGNITION/test.py", line 9, in <module>
model = load_model('model.h5')
File "C:\Users\JH\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\keras\saving\save.py", line 211, in load_model
loader_impl.parse_saved_model(filepath)
File "C:\Users\JH\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\saved_model\loader_impl.py", line 111, in parse_saved_model
raise IOError("SavedModel file does not exist at: %s/{%s|%s}" %
OSError: SavedModel file does not exist at: model.h5/{saved_model.pbtxt|saved_model.pb}
学習モデルから始めて、もう一度やってみることにしました。
しかし、なぜ学習が100%の精度に達しなかったのか、グラフの形がそうだったのか知りたい.
Trouble Shooting
#1
OSError: SavedModel file does not exist at: model.h5/{saved_model.pbtxt|saved_model.pb}
解決策
pip install h5py
->がインストールされています.https://stackoverflow.com/questions/61699140/oserror-savedmodel-file-does-not-exist-at-dnn-mpg-model-h5-saved-model-pbt/65014543#65014543
https://arca.live/b/programmers/44902070?p=1
解決策NodeJSで実行されているPythonShellはH 5モデルではなくSavedModelのみを読み込むことができます.
https://blog.naver.com/PostView.naver?blogId=heyji1230&logNo=222146936643&redirect=Dlog&widgetTypeCall=true&directAccess=false
https://www.tensorflow.org/guide/keras/save_and_serialize?hl=ko
したがって、上記の列車はモデルをh 5に保存するため、コードをsavedmodelに変換する必要がある.ipynbに追加します.
import tensorflow as tf
model = tf.keras.models.load_model('model.h5')
tf.saved_model.save('model')
->このコードを実行すると、assetsフォルダとvariablesフォルダ、saved modelを含むmodelというフォルダが作成されます.pbファイル生成.しかし、同じエラーが発生しました.Google検索中、savedModelをロードする関数とh 5をロードする関数が異なることに気づき、関連内容を調べました.
https://www.tensorflow.org/api_docs/python/tf/saved_model/load:Loading Kerasモデルを参照.
test.pyロードモデルのコードを次のコードに変更します.
model = tf.keras.Model(...)
#2
NotImplementedError: When subclassing the `Model` class, you should implement a `call` method.
https://lifesaver.codes/answer/subclass-of-tf-keras-model-throws-notimplementederror-when-fit-with-custom-data-43173
def call(self, inputs, *args, **kwargs):
return self.model(inputs)
-> ソース def call(self, inputs):
self.total.assign_add(tf.reduce_sum(inputs, axis=0))
return self.total
-> ソース import tensorflow as tf
class MyModel(tf.keras.Model):
def __init__(self):
super().__init__()
self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu)
self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax)
def call(self, inputs):
x = self.dense1(inputs)
return self.dense2(x)
model = MyModel()
-> ソース トラブルシューティング中
リファレンス
[基礎統計]数値型データと分類型データ
機械学習-epoch,batchsize,反復の意義
Reference
この問題について([深さ学習]手話動作学習モデルの構築(LSTM)), 我々は、より多くの情報をここで見つけました https://velog.io/@jihyeon9975/딥러닝-수어-동작-학습-모델-구축하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol