|
|
import numpy as np
|
|
|
import joblib
|
|
|
import json
|
|
|
import argparse
|
|
|
import tensorflow as tf
|
|
|
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
|
|
|
from .sequence_utils import load_sequences_from_csv
|
|
|
|
|
|
def evaluate(data_path, model_path, max_len=30, test_size=0.2):
|
|
|
# Загружаем данные
|
|
|
X_train, X_test, y_train, y_test, le = load_sequences_from_csv(data_path, max_len, test_size)
|
|
|
# Загружаем модель
|
|
|
model = tf.keras.models.load_model(model_path)
|
|
|
# Загружаем классы (или используем le из данных)
|
|
|
try:
|
|
|
classes_path = model_path.replace('.h5', '_classes.pkl')
|
|
|
with open(classes_path, 'rb') as f:
|
|
|
saved_classes = joblib.load(f)
|
|
|
# Проверяем соответствие классов
|
|
|
if list(saved_classes) != list(le.classes_):
|
|
|
print("Warning: classes in model and data differ. Using data classes.")
|
|
|
classes = le.classes_
|
|
|
else:
|
|
|
classes = saved_classes
|
|
|
except:
|
|
|
classes = le.classes_
|
|
|
|
|
|
# Предсказание
|
|
|
y_pred = np.argmax(model.predict(X_test), axis=1)
|
|
|
acc = accuracy_score(y_test, y_pred)
|
|
|
report = classification_report(y_test, y_pred, target_names=classes, output_dict=True)
|
|
|
cm = confusion_matrix(y_test, y_pred).tolist()
|
|
|
|
|
|
print(f"Test accuracy: {acc:.4f}")
|
|
|
print("\nClassification Report:")
|
|
|
for cls in classes:
|
|
|
print(f"{cls}: precision={report[cls]['precision']:.3f}, recall={report[cls]['recall']:.3f}, f1={report[cls]['f1-score']:.3f}")
|
|
|
print("\nConfusion Matrix:")
|
|
|
for row in cm:
|
|
|
print(row)
|
|
|
|
|
|
# Сохраняем отчёт
|
|
|
report_path = model_path.replace('.h5', '_evaluation_report.json')
|
|
|
with open(report_path, 'w') as f:
|
|
|
json.dump({
|
|
|
'accuracy': acc,
|
|
|
'classification_report': report,
|
|
|
'confusion_matrix': cm
|
|
|
}, f, indent=2)
|
|
|
print(f"\nEvaluation report saved to {report_path}")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
parser = argparse.ArgumentParser(description='Оценка LSTM для динамических жестов')
|
|
|
parser.add_argument('--data', required=True, help='Путь к CSV-файлу или папке с CSV-файлами')
|
|
|
parser.add_argument('--model', required=True, help='Путь к обученной модели (.h5)')
|
|
|
parser.add_argument('--max_len', type=int, default=30, help='Длина последовательности (должна совпадать с обучением)')
|
|
|
parser.add_argument('--test_size', type=float, default=0.2, help='Доля тестовой выборки')
|
|
|
args = parser.parse_args()
|
|
|
evaluate(args.data, args.model, args.max_len, args.test_size)
|