142 lines
6.6 KiB
Python
142 lines
6.6 KiB
Python
from experiments.experiment import experiments
|
|
import torch
|
|
import numpy as np
|
|
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score
|
|
from Load_process.LoadData import Loding_Data_Root
|
|
import os
|
|
import seaborn as sns
|
|
import datetime
|
|
from Load_process.file_processing import Process_File
|
|
from Load_process.Load_Indepentend import Load_Indepentend_Data
|
|
from Training_Tools.PreProcess import Training_Precesses
|
|
from Training_Tools.Tools import Tool
|
|
import matplotlib.figure as figure
|
|
import matplotlib.backends.backend_agg as agg
|
|
from Calculate_Process.Calculate import Calculate
|
|
import argparse
|
|
import json
|
|
from utils.Stomach_Config import Training_Config, Loading_Config
|
|
from model_data_processing.processing import shuffle_data
|
|
|
|
if __name__ == "__main__":
|
|
# 解析命令行参数
|
|
parser = argparse.ArgumentParser(description='评估单一类别的准确度、精确度、召回率和F1值')
|
|
parser.add_argument('--target_class', type=int, default=0, help='要评估的目标类别索引 (0, 1, 2)')
|
|
args = parser.parse_args()
|
|
|
|
# 测试GPU是否可用
|
|
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
|
print(f"使用设备: {device}")
|
|
|
|
# 设置GPU
|
|
if torch.cuda.is_available():
|
|
torch.cuda.set_device(0)
|
|
print(f"GPU: {torch.cuda.get_device_name(0)}")
|
|
|
|
# 初始化对象
|
|
tool = Tool()
|
|
Status = 1 # 決定要使用什麼資料集
|
|
|
|
# 取得One-hot encording 的資料
|
|
tool.Set_OneHotEncording(Loading_Config["Training_Labels"])
|
|
Encording_Label = tool.Get_OneHot_Encording_Label()
|
|
|
|
Label_Length = len(Loading_Config["Training_Labels"])
|
|
|
|
# 检查目标类别是否有效
|
|
target_class = args.target_class
|
|
training_labels = Loading_Config["Training_Labels"]
|
|
if target_class < 0 or target_class >= len(training_labels):
|
|
print(f"错误: 目标类别索引 {target_class} 无效,必须在 0 到 {len(training_labels)-1} 之间")
|
|
exit(1)
|
|
|
|
print(f"正在评估类别: {training_labels[target_class]}")
|
|
|
|
load = Loding_Data_Root(Loading_Config["Training_Labels"], Loading_Config["Train_Data_Root"], Loading_Config["ImageGenerator_Data_Root"])
|
|
cut_image = Load_Indepentend_Data(Loading_Config["Training_Labels"], Encording_Label)
|
|
|
|
# 创建模型
|
|
experiment = experiments(Training_Config, Loading_Config, tool, 3, "Test")
|
|
model = experiment.construct_model()
|
|
|
|
# 加载模型权重
|
|
Model_Weight = [
|
|
"../Result/save_the_best_model/Xception Skin trains Stomach Cancer Dataset, and uses WeightRandomSampler Change HSV Channel of V is -150/Xception/best_model( 2025-05-19 )-_fold0.pt",
|
|
"../Result/save_the_best_model/Xception Skin trains Stomach Cancer Dataset, and uses WeightRandomSampler Change HSV Channel of V is -150/Xception/best_model( 2025-05-19 )-_fold1.pt",
|
|
"../Result/save_the_best_model/Xception Skin trains Stomach Cancer Dataset, and uses WeightRandomSampler Change HSV Channel of V is -150/Xception/best_model( 2025-05-19 )-_fold2.pt",
|
|
"../Result/save_the_best_model/Xception Skin trains Stomach Cancer Dataset, and uses WeightRandomSampler Change HSV Channel of V is -150/Xception/best_model( 2025-05-19 )-_fold3.pt",
|
|
"../Result/save_the_best_model/Xception Skin trains Stomach Cancer Dataset, and uses WeightRandomSampler Change HSV Channel of V is -150/Xception/best_model( 2025-05-19 )-_fold4.pt"
|
|
]
|
|
|
|
Calculate_Tool = [Calculate() for i in range(3)]
|
|
i = 0
|
|
for path in Model_Weight:
|
|
if os.path.exists(path):
|
|
model.load_state_dict(torch.load(path))
|
|
print("读取权重完成\n")
|
|
model.eval() # 设置为评估模式
|
|
|
|
# 预处理对象
|
|
preprocess = Training_Precesses(256)
|
|
|
|
cut_image.process_main(Loading_Config["Test_Data_Root"]) # 呼叫處理test Data與Validation Data的function
|
|
test, test_label = cut_image.test, cut_image.test_label
|
|
test, test_label = shuffle_data(test, test_label)
|
|
|
|
# 只评估目标类别
|
|
# 转换为PyTorch张量并移动到设备
|
|
test_dataset = preprocess.Setting_DataSet(cut_image.test, cut_image.test_label, "Transform")
|
|
test_loader = preprocess.Dataloader_Sampler(test_dataset, 1, False)
|
|
|
|
all_results = []
|
|
all_labels = []
|
|
|
|
# 使用PyTorch的预测方式
|
|
with torch.no_grad(): # 不计算梯度
|
|
for inputs, labels, _, _ in test_loader:
|
|
inputs = inputs.to(device)
|
|
labels = labels.to(device)
|
|
|
|
outputs = model(inputs)
|
|
_, predicted = torch.max(outputs, 1)
|
|
all_results.append(predicted.cpu().numpy())
|
|
all_labels.append(np.argmax(labels.cpu().numpy(), axis=1))
|
|
|
|
# 合并结果
|
|
Predict = np.concatenate(all_results)
|
|
y_test = np.concatenate(all_labels)
|
|
|
|
print(f"{training_labels[target_class]} 预测结果: {Predict}\n")
|
|
|
|
# 计算评估指标
|
|
accuracy = accuracy_score(y_test, Predict)
|
|
precision = precision_score(y_test, Predict, average=None)
|
|
recall = recall_score(y_test, Predict, average=None)
|
|
F1 = f1_score(y_test, Predict, average=None)
|
|
|
|
# 计算每个类别的准确率
|
|
class_accuracies = []
|
|
for class_idx in range(len(training_labels)):
|
|
class_mask = (y_test == class_idx)
|
|
class_accuracy = accuracy_score(y_test[class_mask], Predict[class_mask])
|
|
class_accuracies.append(class_accuracy)
|
|
|
|
print(f"运行 {i+1}:\n")
|
|
print(f"整体准确率 (Accuracy): {accuracy:.4f}")
|
|
for class_idx in range(len(training_labels)):
|
|
print(f"类别 {training_labels[class_idx]} 的评估指标:")
|
|
print(f" 准确率 (Accuracy): {class_accuracies[class_idx]:.4f}")
|
|
print(f" 精确率 (Precision): {precision[class_idx]:.4f}")
|
|
print(f" 召回率 (Recall): {recall[class_idx]:.4f}")
|
|
print(f" F1值: {F1[class_idx]:.4f}\n")
|
|
Calculate_Tool[class_idx].Append_numbers(0, class_accuracies[class_idx], precision[class_idx], recall[class_idx], 0, F1[class_idx])
|
|
|
|
i += 1
|
|
|
|
# 计算平均值和标准差
|
|
for i in range(3):
|
|
Calculate_Tool[i].Calculate_Mean()
|
|
Calculate_Tool[i].Calculate_Std()
|
|
print(f"\n{training_labels[target_class]} 类别的评估结果:")
|
|
print(Calculate_Tool[i].Output_Style())
|