| | import numpy as np
|
| | import matplotlib.pyplot as plt
|
| | import seaborn as sns
|
| | from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc, precision_score, f1_score, recall_score
|
| | import pandas as pd
|
| | from tensorflow.keras.models import load_model
|
| | import argparse
|
| |
|
| | def plot_confusion_matrix(y_true, y_pred, classes):
|
| | """
|
| | Vẽ ma trận nhầm lẫn
|
| | """
|
| | cm = confusion_matrix(y_true, y_pred)
|
| | plt.figure(figsize=(10, 8))
|
| | sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
|
| | xticklabels=classes, yticklabels=classes)
|
| | plt.title('Ma trận nhầm lẫn')
|
| | plt.ylabel('Nhãn thực tế')
|
| | plt.xlabel('Nhãn dự đoán')
|
| | plt.savefig('confusion_matrix.png')
|
| | plt.close()
|
| |
|
| | def plot_roc_curve(y_true, y_pred_proba, classes):
|
| | """
|
| | Vẽ đường cong ROC
|
| | """
|
| | plt.figure(figsize=(10, 8))
|
| | for i, class_name in enumerate(classes):
|
| | fpr, tpr, _ = roc_curve(y_true == i, y_pred_proba[:, i])
|
| | roc_auc = auc(fpr, tpr)
|
| | plt.plot(fpr, tpr, label=f'{class_name} (AUC = {roc_auc:.2f})')
|
| |
|
| | plt.plot([0, 1], [0, 1], 'k--')
|
| | plt.xlim([0.0, 1.0])
|
| | plt.ylim([0.0, 1.05])
|
| | plt.xlabel('Tỷ lệ dương tính giả')
|
| | plt.ylabel('Tỷ lệ dương tính thật')
|
| | plt.title('Đường cong ROC')
|
| | plt.legend(loc="lower right")
|
| | plt.savefig('roc_curve.png')
|
| | plt.close()
|
| |
|
| | def plot_training_history(history):
|
| | """
|
| | Vẽ đồ thị quá trình huấn luyện
|
| | """
|
| | plt.figure(figsize=(12, 4))
|
| |
|
| |
|
| | plt.subplot(1, 2, 1)
|
| | plt.plot(history.history['loss'], label='Training Loss')
|
| | plt.plot(history.history['val_loss'], label='Validation Loss')
|
| | plt.title('Loss trong quá trình huấn luyện')
|
| | plt.xlabel('Epoch')
|
| | plt.ylabel('Loss')
|
| | plt.legend()
|
| |
|
| |
|
| | plt.subplot(1, 2, 2)
|
| | plt.plot(history.history['accuracy'], label='Training Accuracy')
|
| | plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
|
| | plt.title('Accuracy trong quá trình huấn luyện')
|
| | plt.xlabel('Epoch')
|
| | plt.ylabel('Accuracy')
|
| | plt.legend()
|
| |
|
| | plt.tight_layout()
|
| | plt.savefig('training_history.png')
|
| | plt.close()
|
| |
|
| | def plot_metrics_bar(y_true, y_pred, classes):
|
| | """
|
| | Vẽ biểu đồ cột cho các chỉ số Precision, Recall và F1-score
|
| | """
|
| | precision = precision_score(y_true, y_pred, average=None)
|
| | recall = recall_score(y_true, y_pred, average=None)
|
| | f1 = f1_score(y_true, y_pred, average=None)
|
| |
|
| | metrics = np.vstack((precision, recall, f1))
|
| |
|
| | plt.figure(figsize=(12, 6))
|
| | x = np.arange(len(classes))
|
| | width = 0.25
|
| |
|
| | plt.bar(x - width, precision, width, label='Precision')
|
| | plt.bar(x, recall, width, label='Recall')
|
| | plt.bar(x + width, f1, width, label='F1-score')
|
| |
|
| | plt.xlabel('Classes')
|
| | plt.ylabel('Scores')
|
| | plt.title('Precision, Recall và F1-score cho từng lớp')
|
| | plt.xticks(x, classes, rotation=45)
|
| | plt.legend()
|
| | plt.tight_layout()
|
| | plt.savefig('metrics_bar.png')
|
| | plt.close()
|
| |
|
| | def evaluate_model(model, X_test, y_test, classes, history=None):
|
| | """
|
| | Đánh giá mô hình và vẽ các sơ đồ
|
| | """
|
| |
|
| | y_pred = model.predict(X_test)
|
| | y_pred_classes = np.argmax(y_pred, axis=1)
|
| | y_true = np.argmax(y_test, axis=1)
|
| |
|
| |
|
| | print("\nBáo cáo phân loại:")
|
| | print(classification_report(y_true, y_pred_classes, target_names=classes))
|
| |
|
| |
|
| | precision = precision_score(y_true, y_pred_classes, average=None)
|
| | recall = recall_score(y_true, y_pred_classes, average=None)
|
| | f1 = f1_score(y_true, y_pred_classes, average=None)
|
| |
|
| |
|
| | print("\nChi tiết các chỉ số cho từng lớp:")
|
| | for i, class_name in enumerate(classes):
|
| | print(f"\n{class_name}:")
|
| | print(f"Precision: {precision[i]:.4f}")
|
| | print(f"Recall: {recall[i]:.4f}")
|
| | print(f"F1-score: {f1[i]:.4f}")
|
| |
|
| |
|
| | plot_confusion_matrix(y_true, y_pred_classes, classes)
|
| |
|
| |
|
| | plot_roc_curve(y_true, y_pred, classes)
|
| |
|
| |
|
| | plot_metrics_bar(y_true, y_pred_classes, classes)
|
| |
|
| |
|
| | if history is not None:
|
| | plot_training_history(history)
|
| |
|
| |
|
| | accuracy = np.mean(y_pred_classes == y_true)
|
| | print(f"\nĐộ chính xác tổng thể: {accuracy:.4f}")
|
| |
|
| |
|
| | results = {
|
| | 'accuracy': accuracy,
|
| | 'precision': precision,
|
| | 'recall': recall,
|
| | 'f1_score': f1,
|
| | 'classification_report': classification_report(y_true, y_pred_classes, target_names=classes, output_dict=True)
|
| | }
|
| |
|
| |
|
| | metrics_df = pd.DataFrame({
|
| | 'Class': classes,
|
| | 'Precision': precision,
|
| | 'Recall': recall,
|
| | 'F1-score': f1
|
| | })
|
| | metrics_df.to_csv('detailed_metrics.csv', index=False)
|
| |
|
| | results_df = pd.DataFrame(results['classification_report']).transpose()
|
| | results_df.to_csv('model_evaluation_results.csv')
|
| |
|
| | return results
|
| |
|
| | if __name__ == "__main__":
|
| |
|
| | parser = argparse.ArgumentParser(description='Đánh giá mô hình phân loại khối u não')
|
| | parser.add_argument('--model_path', type=str, required=True, help='Đường dẫn đến file model (.keras)')
|
| | parser.add_argument('--test_data', type=str, required=True, help='Đường dẫn đến file dữ liệu test (.npy)')
|
| | parser.add_argument('--test_labels', type=str, required=True, help='Đường dẫn đến file nhãn test (.npy)')
|
| | parser.add_argument('--history', type=str, help='Đường dẫn đến file lịch sử huấn luyện (.npy)')
|
| |
|
| | args = parser.parse_args()
|
| |
|
| |
|
| | print(f"Đang tải model từ {args.model_path}...")
|
| | model = load_model(args.model_path)
|
| |
|
| |
|
| | print(f"Đang tải dữ liệu test từ {args.test_data}...")
|
| | X_test = np.load(args.test_data)
|
| | y_test = np.load(args.test_labels)
|
| |
|
| |
|
| | history = None
|
| | if args.history:
|
| | print(f"Đang tải lịch sử huấn luyện từ {args.history}...")
|
| | history = np.load(args.history, allow_pickle=True).item()
|
| |
|
| |
|
| | print("Bắt đầu đánh giá mô hình...")
|
| | results = evaluate_model(
|
| | model=model,
|
| | X_test=X_test,
|
| | y_test=y_test,
|
| | classes=['glioma', 'meningioma', 'notumor', 'pituitary'],
|
| | history=history
|
| | )
|
| |
|
| | print("\nĐánh giá hoàn tất! Các kết quả đã được lưu vào:")
|
| | print("- confusion_matrix.png")
|
| | print("- roc_curve.png")
|
| | print("- metrics_bar.png")
|
| | print("- detailed_metrics.csv")
|
| | print("- model_evaluation_results.csv") |