<jupyter_start><jupyter_text>各パス指定<jupyter_code>dataset = 'model/keypoint_classifier/keypoint.csv'
model_save_path = 'model/keypoint_classifier/keypoint_classifier.hdf5'<jupyter_output><empty_output><jupyter_text>分類数設定<jupyter_code>NUM_CLASSES = 9<jupyter_output><empty_output><jupyter_text>学習データ読み込み<jupyter_code>X_dataset = np.loadtxt(dataset, delimiter=',', dtype='float32', usecols=list(range(1, (21 * 2) + 1)))
y_dataset = np.loadtxt(dataset, delimiter=',', dtype='int32', usecols=(0))
X_train, X_test, y_train, y_test = train_test_split(X_dataset, y_dataset, train_size=0.75, random_state=RANDOM_SEED)<jupyter_output><empty_output><jupyter_text>モデル構築<jupyter_code>model = tf.keras.models.Sequential([
    tf.keras.layers.Input((21 * 2, )),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(20, activation='relu'),
    tf.keras.layers.Dropout(0.4),
    tf.keras.layers.Dense(10, activation='relu'),
    tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
])
model.summary()  # tf.keras.utils.plot_model(model, show_shapes=True)
# モデルチェックポイントのコールバック
cp_callback = tf.keras.callbacks.ModelCheckpoint(
    model_save_path, verbose=1, save_weights_only=False)
# 早期打ち切り用コールバック
es_callback = tf.keras.callbacks.EarlyStopping(patience=20, verbose=1)
# モデルコンパイル
model.compile(
    optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)<jupyter_output><empty_output><jupyter_text>モデル訓練<jupyter_code>model.fit(
    X_train,
    y_train,
    epochs=1000,
    batch_size=128,
    validation_data=(X_test, y_test),
    callbacks=[cp_callback, es_callback]
)
# モデル評価
val_loss, val_acc = model.evaluate(X_test, y_test, batch_size=128)
# 保存したモデルのロード
model = tf.keras.models.load_model(model_save_path)
# 推論テスト
predict_result = model.predict(np.array([X_test[0]]))
print(np.squeeze(predict_result))
print(np.argmax(np.squeeze(predict_result)))<jupyter_output>[9.4318336e-01 1.5794187e-06 1.0601198e-04 2.9872141e-03 3.7751443e-06
 3.7231963e-02 1.2493904e-02 4.2530341e-04 3.5668034e-03]
0<jupyter_text>混同行列<jupyter_code>import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, classification_report

def print_confusion_matrix(y_true, y_pred, report=True):
    labels = sorted(list(set(y_true)))
    cmx_data = confusion_matrix(y_true, y_pred, labels=labels)
    
    df_cmx = pd.DataFrame(cmx_data, index=labels, columns=labels)
 
    fig, ax = plt.subplots(figsize=(7, 6))
    sns.heatmap(df_cmx, annot=True, fmt='g' ,square=False)
    ax.set_ylim(len(set(y_true)), 0)
    plt.show()
    
    if report:
        print('Classification Report')
        print(classification_report(y_test, y_pred))

Y_pred = model.predict(X_test)
y_pred = np.argmax(Y_pred, axis=1)

print_confusion_matrix(y_test, y_pred)<jupyter_output><empty_output><jupyter_text>Tensorflow-Lite用のモデルへ変換<jupyter_code># 推論専用のモデルとして保存
model.save(model_save_path, include_optimizer=False)
# モデルを変換(量子化)
tflite_save_path = 'model/keypoint_classifier/keypoint_classifier.tflite'

converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_quantized_model = converter.convert()

open(tflite_save_path, 'wb').write(tflite_quantized_model)<jupyter_output>INFO:tensorflow:Assets written to: C:\Users\Gabriel\AppData\Local\Temp\tmpwlgxohhb\assets<jupyter_text>推論テスト<jupyter_code>interpreter = tf.lite.Interpreter(model_path=tflite_save_path)
interpreter.allocate_tensors()
# 入出力テンソルを取得
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
interpreter.set_tensor(input_details[0]['index'], np.array([X_test[0]]))
%%time
# 推論実施
interpreter.invoke()
tflite_results = interpreter.get_tensor(output_details[0]['index'])
print(np.squeeze(tflite_results))
print(np.argmax(np.squeeze(tflite_results)))<jupyter_output>[9.43183362e-01 1.57941849e-06 1.06011976e-04 2.98721087e-03
 3.77514402e-06 3.72319631e-02 1.24939084e-02 4.25303791e-04
 3.56680341e-03]
0
{'fraction_non_alphanumeric': 0.1332835077229696, 'fraction_numerical': 0.05954160438465371, 'mean_word_length': 7.227459016393443, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '344704', 'license': 'Apache-2.0', 'n_tokens_mistral': 1878, 'n_tokens_neox': 1727, 'n_words': 182, 'path': 'keypoint_classification.ipynb', 'repo_name': 'gabesf/hand-gesture-recognition-using-mediapipe', 'size': '4014'}