Brain_Tumor_detect / model_evaluation.py
James106204's picture
Upload folder using huggingface_hub
77fa523 verified
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))
# Vẽ đồ thị loss
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()
# Vẽ đồ thị accuracy
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ơ đồ
"""
# Dự đoán
y_pred = model.predict(X_test)
y_pred_classes = np.argmax(y_pred, axis=1)
y_true = np.argmax(y_test, axis=1)
# In báo cáo phân loại
print("\nBáo cáo phân loại:")
print(classification_report(y_true, y_pred_classes, target_names=classes))
# Tính toán các chỉ số
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)
# In các chỉ số chi tiết
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}")
# Vẽ ma trận nhầm lẫn
plot_confusion_matrix(y_true, y_pred_classes, classes)
# Vẽ đường cong ROC
plot_roc_curve(y_true, y_pred, classes)
# Vẽ biểu đồ các chỉ số
plot_metrics_bar(y_true, y_pred_classes, classes)
# Vẽ đồ thị quá trình huấn luyện nếu có
if history is not None:
plot_training_history(history)
# Tính toán và in các metric
accuracy = np.mean(y_pred_classes == y_true)
print(f"\nĐộ chính xác tổng thể: {accuracy:.4f}")
# Lưu kết quả vào file
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)
}
# Chuyển đổi kết quả thành DataFrame và lưu
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__":
# Tạo parser để nhận tham số từ command line
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()
# Load model
print(f"Đang tải model từ {args.model_path}...")
model = load_model(args.model_path)
# Load dữ liệu test
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)
# Load lịch sử huấn luyện nếu có
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()
# Đánh giá mô hình
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")