File size: 7,335 Bytes
77fa523 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | 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") |