376 lines
19 KiB
Python
376 lines
19 KiB
Python
from Training_Tools.PreProcess import Training_Precesses
|
||
from Load_process.Load_Indepentend import Load_Indepentend_Data
|
||
from _validation.ValidationTheEnterData import validation_the_enter_data
|
||
from utils.Stomach_Config import Training_Config, Loading_Config, Save_Result_File_Config
|
||
# from experiments.Training.Identification_Block_Training import Identification_Block_Training_Step
|
||
# from experiments.Training.Segmentation_Block_Training import Segmentation_Block_Training_Step
|
||
from experiments.Training.Xception_Identification_Test import Xception_Identification_Block_Training_Step
|
||
from Load_process.LoadData import Loding_Data_Root
|
||
from Load_process.LoadData import Load_Data_Prepare
|
||
from model_data_processing.processing import make_label_list
|
||
from merge_class.merge import merge
|
||
from Training_Tools.Tools import Tool
|
||
|
||
import torch
|
||
import time
|
||
import numpy as np
|
||
|
||
class experiments():
|
||
def __init__(self, Xception_Training_Data, Xception_Training_Label, Xception_Training_Mask_Data, status):
|
||
'''
|
||
# 實驗物件
|
||
|
||
## 說明:
|
||
* 用於開始訓練pytorch的物件,裡面分為數個方法,負責處理實驗過程的種種
|
||
|
||
## parmeter:
|
||
* cut_image: 呼叫切割影像物件
|
||
* merge: 合併的物件
|
||
* model_name: 模型名稱,告訴我我是用哪個模型(可能是預處理模型/自己設計的模型)
|
||
* experiment_name: 實驗名稱
|
||
* epoch: 訓練次數
|
||
* train_batch_size: 訓練資料的batch
|
||
* convolution_name: Grad-CAM的最後一層的名稱
|
||
* Number_Of_Classes: Label的類別
|
||
* Status: 選擇現在資料集的狀態
|
||
* device: 決定使用GPU或CPU
|
||
|
||
## Method:
|
||
* processing_main: 實驗物件的進入點
|
||
* construct_model: 決定實驗用的Model
|
||
* Training_Step: 訓練步驟,開始進行訓練驗證的部分
|
||
* Evaluate_Model: 驗證模型的準確度
|
||
* record_matrix_image: 劃出混淆矩陣(熱力圖)
|
||
* record_everyTime_test_result: 記錄我單次的訓練結果並將它輸出到檔案中
|
||
'''
|
||
self.model_name = Training_Config["Model_Name"] # 取名,告訴我我是用哪個模型(可能是預處理模型/自己設計的模型)
|
||
self.epoch = Training_Config["Epoch"]
|
||
self.train_batch_size = Training_Config["Train_Batch_Size"]
|
||
self.Image_Size = Training_Config["Image_Size"]
|
||
|
||
self.Xception_Training_Data = Xception_Training_Data
|
||
self.Xception_Training_Label = Xception_Training_Label
|
||
self.Xception_Training_Mask_Data = Xception_Training_Mask_Data
|
||
self.Grad = None
|
||
|
||
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
||
self.validation_obj = validation_the_enter_data() # 呼叫驗證物件
|
||
|
||
pass
|
||
|
||
def processing_main(self):
|
||
print(f"Testing Data Prepring!!!!")
|
||
tool = Tool()
|
||
Merge = merge()
|
||
Prepare = Load_Data_Prepare()
|
||
|
||
# 取得One-hot encording 的資料
|
||
tool.Set_OneHotEncording(Loading_Config["Training_Labels"])
|
||
Encording_Label = tool.Get_OneHot_Encording_Label()
|
||
Label_Length = len(Loading_Config["Training_Labels"])
|
||
|
||
start = time.time()
|
||
# self.cut_image.process_main(Loading_Config["Test_Data_Root"], Loading_Config["Annotation_Testing_Root"]) # 呼叫處理test Data與Validation Data的function
|
||
|
||
tmp_load = Loding_Data_Root(Loading_Config["Training_Labels"], Loading_Config['Test_Data_Root'], None)
|
||
Data_Dict_Data = tmp_load.process_main(False)
|
||
|
||
Total_Size_List = []
|
||
Train_Size = 0
|
||
print("前處理後資料集總數")
|
||
for label in Loading_Config["Training_Labels"]:
|
||
Train_Size += len(Data_Dict_Data[label])
|
||
Total_Size_List.append(len(Data_Dict_Data[label]))
|
||
print(f"Labels: {label}, 總數為: {len(Data_Dict_Data[label])}")
|
||
|
||
print("總共有 " + str(Train_Size) + " 筆資料")
|
||
|
||
# 做出跟資料相同數量的Label
|
||
Classes = []
|
||
i = 0
|
||
for encording in Encording_Label:
|
||
Classes.append(make_label_list(Total_Size_List[i], encording))
|
||
i += 1
|
||
|
||
# 將資料做成Dict的資料型態
|
||
Prepare.Set_Final_Dict_Data(Loading_Config["Training_Labels"], Data_Dict_Data, Classes, Label_Length)
|
||
Final_Dict_Data = Prepare.Get_Final_Data_Dict()
|
||
keys = list(Final_Dict_Data.keys())
|
||
|
||
Testing_Data = Merge.merge_all_image_data(Final_Dict_Data[keys[0]], Final_Dict_Data[keys[1]]) # 將訓練資料合併成一個list
|
||
for i in range(2, Label_Length):
|
||
Testing_Data = Merge.merge_all_image_data(Testing_Data, Final_Dict_Data[keys[i]]) # 將訓練資料合併成一個list
|
||
|
||
Testing_Label = Merge.merge_all_image_data(Final_Dict_Data[keys[Label_Length]], Final_Dict_Data[keys[Label_Length + 1]]) #將訓練資料的label合併成一個label的list
|
||
for i in range(Label_Length + 2, 2 * Label_Length):
|
||
Testing_Label = Merge.merge_all_image_data(Testing_Label, Final_Dict_Data[keys[i]]) # 將訓練資料合併成一個list
|
||
|
||
end = time.time()
|
||
print("讀取testing與validation資料(154)執行時間:%f 秒\n" % (end - start))
|
||
|
||
# 將處理好的test Data 與 Validation Data 丟給這個物件的變數
|
||
print("Testing Data is Prepared finish!!!!")
|
||
|
||
PreProcess = Training_Precesses(self.Image_Size)
|
||
|
||
Test_Dataset = PreProcess.Setting_DataSet(
|
||
Testing_Data,
|
||
Testing_Label,
|
||
None,
|
||
"Transform"
|
||
)
|
||
self.Test_Dataloader = PreProcess.Dataloader_Sampler(Test_Dataset, 1, False)
|
||
|
||
# 創建Normal vs Others的訓練數據集
|
||
Training_Data = PreProcess.Setting_DataSet(
|
||
self.Xception_Training_Data,
|
||
self.Xception_Training_Label,
|
||
None,
|
||
"Transform"
|
||
)
|
||
|
||
print("Training is started!!\n")
|
||
|
||
# 創建訓練步驟物件
|
||
identification_Normal_step = Xception_Identification_Block_Training_Step(Training_Config["Three_Classes_Experiment_Name"], Save_Result_File_Config["Three_Classes_Identification_Best_Model"])
|
||
# 訓練Normal vs Others分類模型
|
||
Best_Model_Path = identification_Normal_step.Processing_Main(Training_Data, self.Test_Dataloader)
|
||
|
||
# # 分類正常跟其他資料集的測試資料
|
||
# Normal_And_Other_Test_Data = self.cut_image.test.copy()
|
||
# normal_vs_others_Test_labels = []
|
||
|
||
# # 將標籤轉換為二分類:Normal(1) vs Others(0)
|
||
# for label in self.cut_image.test_label:
|
||
# if np.argmax(label) == 1: # Normal_Crop
|
||
# # Normal類別標籤為[0, 1]
|
||
# normal_vs_others_Test_labels.append(np.array([0, 1]))
|
||
# else:
|
||
# # 其他類別標籤為[1, 0]
|
||
# normal_vs_others_Test_labels.append(np.array([1, 0]))
|
||
|
||
# # 創建Normal vs Others的測試數據集
|
||
# normal_vs_others_test_dataset = PreProcess.Setting_DataSet(
|
||
# Normal_And_Other_Test_Data,
|
||
# normal_vs_others_Test_labels,
|
||
# None,
|
||
# "Transform"
|
||
# )
|
||
# normal_vs_others_test_dataloader = PreProcess.Dataloader_Sampler(normal_vs_others_test_dataset, 1, False)
|
||
|
||
# # =========================================================================================================================================================================================
|
||
|
||
# # 分類分割模型的測試資料
|
||
# # 使用CA資料和Have_Question資料訓練分割模型
|
||
# ca_have_question_test_data = []
|
||
# ca_have_question_test_labels = []
|
||
|
||
# # 篩選CA和Have_Question資料
|
||
# for i, label in enumerate(self.cut_image.test_label):
|
||
# # 檢查是否為CA或Have_Question類別
|
||
# if np.argmax(label) == 0 or np.argmax(label) == 2: # stomach_cancer_Crop或Have_Question_Crop
|
||
# ca_have_question_test_data.append(self.cut_image.test[i])
|
||
# ca_have_question_test_labels.append(self.cut_image.test_label[i])
|
||
|
||
# print(f"CA and Have_Question Test Data Count: {len(ca_have_question_test_data)}")
|
||
# print(f"CA and Have_Question Test Mask Count: {len(self.cut_image.test_mask)}")
|
||
|
||
# # 創建CA和Have_Question的訓練數據集
|
||
# segumentation_test_dataset = PreProcess.Setting_DataSet(
|
||
# ca_have_question_test_data,
|
||
# ca_have_question_test_labels,
|
||
# self.cut_image.test_mask,
|
||
# "Transform"
|
||
# )
|
||
# Segumentation_test_dataloader = PreProcess.Dataloader_Sampler(segumentation_test_dataset, 1, False)
|
||
|
||
# # =========================================================================================================================================================================================
|
||
|
||
# # 非胃癌有病與胃癌資料的分類測試資料
|
||
# # 準備CA vs Have_Question的訓練數據
|
||
# ca_vs_have_question_test_data = []
|
||
# ca_vs_have_question_test_labels = []
|
||
|
||
# # 篩選CA和Have_Question資料
|
||
# for i, label in enumerate(self.cut_image.test_label):
|
||
# if np.argmax(label) == 0: # stomach_cancer_Crop
|
||
# ca_vs_have_question_test_data.append(self.cut_image.test[i])
|
||
# ca_vs_have_question_test_labels.append(np.array([1, 0])) # CA類別標籤為[1, 0]
|
||
# elif np.argmax(label) == 2: # Have_Question_Crop
|
||
# ca_vs_have_question_test_data.append(self.cut_image.test[i])
|
||
# ca_vs_have_question_test_labels.append(np.array([0, 1])) # Have_Question類別標籤為[0, 1]
|
||
|
||
# # 創建CA vs Have_Question的測試數據集
|
||
# ca_vs_have_question_test_dataset = PreProcess.Setting_DataSet(
|
||
# ca_vs_have_question_test_data,
|
||
# ca_vs_have_question_test_labels,
|
||
# None,
|
||
# "Transform"
|
||
# )
|
||
# ca_vs_have_question_test_dataloader = PreProcess.Dataloader_Sampler(ca_vs_have_question_test_dataset, 1, False)
|
||
|
||
# # =========================================================================================================================================================================================
|
||
|
||
# 建立最終測試資料(不含遮罩)
|
||
# Testing_Data, Testing_Label = self.cut_image.test.copy(), self.cut_image.test_label.copy()
|
||
# Test_Dataset = PreProcess.Setting_DataSet(
|
||
# Testing_Data,
|
||
# Testing_Label,
|
||
# None,
|
||
# "Transform"
|
||
# )
|
||
# self.Test_Dataloader = PreProcess.Dataloader_Sampler(Test_Dataset, 1, False)
|
||
|
||
# =========================================================================================================================================================================================
|
||
|
||
# identification_Normal_step = Identification_Block_Training_Step(Training_Config["Normal_Experiment_Name"], Save_Result_File_Config["Normal_Identification_Best_Model"])
|
||
# identification_CA_step = Identification_Block_Training_Step(Training_Config["CA_Experiment_Name"], Save_Result_File_Config["CA_Identification_Best_Model"])
|
||
# segmentation_step = Segmentation_Block_Training_Step(Save_Result_File_Config["Segmentation_Best_Model"])
|
||
|
||
# print("\n=== 第一階段:訓練正常資料分類模型 ===\n")
|
||
# # 第一組:訓練Normal資料和其他資料的分類模型
|
||
# print("\n--- Normal vs Others分類模型 ---\n")
|
||
|
||
# # 準備Normal vs Others的訓練數據
|
||
# # 分類testing的資料
|
||
# normal_vs_others_data = self.Xception_Training_Data.copy()
|
||
# normal_vs_others_labels = []
|
||
|
||
# # 將標籤轉換為二分類:Normal(1) vs Others(0)
|
||
# for label in self.Xception_Training_Label:
|
||
# if np.argmax(label) == 1: # Normal_Crop
|
||
# # Normal類別標籤為[0, 1]
|
||
# normal_vs_others_labels.append(np.array([0, 1]))
|
||
# else:
|
||
# # 其他類別標籤為[1, 0]
|
||
# normal_vs_others_labels.append(np.array([1, 0]))
|
||
|
||
# # 創建Normal vs Others的訓練數據集
|
||
# normal_vs_others_dataset = PreProcess.Setting_DataSet(
|
||
# normal_vs_others_data,
|
||
# normal_vs_others_labels,
|
||
# None,
|
||
# "Transform"
|
||
# )
|
||
|
||
# # 訓練Normal vs Others分類模型
|
||
# Best_Normal_Model_Path, Normal_Calculate_Process, Normal_Calculate_Tool = identification_Normal_step.Processing_Main(normal_vs_others_dataset, normal_vs_others_test_dataloader)
|
||
|
||
|
||
# # 訓練流程:先訓練分割模型,再訓練分類模型
|
||
# print("\n=== 第二階段:訓練分割模型 ===\n")
|
||
# # 使用CA資料和Have_Question資料訓練分割模型
|
||
# ca_have_question_data = []
|
||
# ca_have_question_labels = []
|
||
|
||
# # 篩選CA和Have_Question資料
|
||
# for i, label in enumerate(self.Xception_Training_Label):
|
||
# # 檢查是否為CA或Have_Question類別
|
||
# if np.argmax(label) == 0 or np.argmax(label) == 2: # stomach_cancer_Crop或Have_Question_Crop
|
||
# ca_have_question_data.append(self.Xception_Training_Data[i])
|
||
# ca_have_question_labels.append(self.Xception_Training_Label[i])
|
||
|
||
# # 創建CA和Have_Question的訓練數據集
|
||
# ca_have_question_dataset = PreProcess.Setting_DataSet(
|
||
# ca_have_question_data,
|
||
# ca_have_question_labels,
|
||
# self.Xception_Training_Mask_Data,
|
||
# "Transform"
|
||
# )
|
||
|
||
# # 執行分割模型訓練,並獲取處理後的圖像
|
||
# segmentation_best_model_path, avg_test_loss = segmentation_step.Processing_Main(
|
||
# ca_have_question_dataset,
|
||
# return_processed_images=True,
|
||
# test_dataloader=Segumentation_test_dataloader
|
||
# )
|
||
|
||
# print(f"分割模型訓練完成,模型路徑: {segmentation_best_model_path}")
|
||
|
||
# # 將處理後的圖像保存起來,用於後續分析或可視化
|
||
# # 這裡可以添加保存處理後圖像的代碼,例如使用torchvision.utils.save_image
|
||
|
||
# print("\n=== 第三階段:訓練CA資料分類模型 ===\n")
|
||
# # 第二組:訓練CA資料和Have_Question資料的分類模型
|
||
# print("\n--- 訓練CA vs Have_Question分類模型 ---\n")
|
||
|
||
# Load = Loding_Data_Root(Loading_Config["XML_Loading_Label"], Save_Result_File_Config["Segument_Bounding_Box_Image"], None)
|
||
# CA_Laod_Data_Dict = Load.process_main(False)
|
||
|
||
# Total_Size_List = []
|
||
# Train_Size = 0
|
||
|
||
# print("前處理後資料集總數")
|
||
# for label in Loading_Config["XML_Loading_Label"]:
|
||
# Train_Size += len(CA_Laod_Data_Dict[label])
|
||
# Total_Size_List.append(len(CA_Laod_Data_Dict[label]))
|
||
# print(f"Labels: {label}, 總數為: {len(CA_Laod_Data_Dict[label])}")
|
||
|
||
# print("總共有 " + str(Train_Size) + " 筆資料")
|
||
|
||
# # 做出跟資料相同數量的Label
|
||
# Classes = []
|
||
# Encording_Label = np.array([[1, 0], [0, 1]])
|
||
# i = 0
|
||
# for encording in Encording_Label:
|
||
# Classes.append(make_label_list(Total_Size_List[i], encording))
|
||
# i += 1
|
||
|
||
# # 將資料做成Dict的資料型態
|
||
# Prepare = Load_Data_Prepare()
|
||
# Merge = merge()
|
||
# Label_Length = len(Loading_Config["XML_Loading_Label"])
|
||
|
||
# Prepare.Set_Final_Dict_Data(Loading_Config["XML_Loading_Label"], CA_Laod_Data_Dict, Classes, Label_Length)
|
||
# Final_Dict_Data = Prepare.Get_Final_Data_Dict()
|
||
# keys = list(Final_Dict_Data.keys())
|
||
|
||
# Training_Data = Merge.merge_all_image_data(Final_Dict_Data[keys[0]], Final_Dict_Data[keys[1]]) # 將訓練資料合併成一個list
|
||
# for i in range(2, Label_Length):
|
||
# Training_Data = Merge.merge_all_image_data(Training_Data, Final_Dict_Data[keys[i]]) # 將訓練資料合併成一個list
|
||
|
||
# Training_Label = Merge.merge_all_image_data(Final_Dict_Data[keys[Label_Length]], Final_Dict_Data[keys[Label_Length + 1]]) #將訓練資料的label合併成一個label的list
|
||
# for i in range(Label_Length + 2, 2 * Label_Length):
|
||
# Training_Label = Merge.merge_all_image_data(Training_Label, Final_Dict_Data[keys[i]]) # 將訓練資料合併成一個list
|
||
|
||
# # 創建CA vs Have_Question的訓練數據集
|
||
# ca_vs_have_question_dataset = PreProcess.Setting_DataSet(
|
||
# Training_Data,
|
||
# Training_Label,
|
||
# None,
|
||
# "Transform"
|
||
# )
|
||
|
||
# # 訓練CA vs Have_Question分類模型
|
||
# Best_CA_Model_Path, CA_Calculate_Process, CA_Calculate_Tool = identification_CA_step.Processing_Main(ca_vs_have_question_dataset, ca_vs_have_question_test_dataloader)
|
||
|
||
# # 顯示訓練完成的指標平均值
|
||
# print("\n=== Normal and another的指標平均值 ===\n")
|
||
# print(f"Normal and another identification result is \n {Normal_Calculate_Process.Output_Style()}\n")
|
||
|
||
# print("\n=== Normal and another各類別的指標平均值 ===\n")
|
||
# for Calculate_Every_Class in Normal_Calculate_Tool:
|
||
# print(f"\nNormal and another identification result is \n {Calculate_Every_Class.Output_Style()}\n")
|
||
# print("\n\n")
|
||
|
||
# # 顯示訓練完成的指標平均值
|
||
# print("\n=== CA and Have Question的指標平均值 ===\n")
|
||
# print(f"CA and Have Question identification result is \n {CA_Calculate_Process.Output_Style()}\n")
|
||
|
||
# print("\n=== CA and Have Question各類別的指標平均值 ===\n")
|
||
# for Calculate_Every_Class in CA_Calculate_Tool:
|
||
# print(f"\nCA vs Have_Question identification result is \n {Calculate_Every_Class.Output_Style()}\n")
|
||
# print("\n")
|
||
|
||
# evaluator = ModelEvaluator(Save_Result_File_Config["Normal_Identification_Best_Model"], Save_Result_File_Config["CA_Identification_Best_Model"])
|
||
# metrics, results_dir = evaluator.run_evaluation()
|
||
|
||
# if metrics:
|
||
# print(f"\n最終結果摘要:")
|
||
# print(f"準確率: {metrics['accuracy']:.4f}")
|
||
# print(f"精確率: {metrics['precision_macro']:.4f}")
|
||
# print(f"召回率: {metrics['recall_macro']:.4f}")
|
||
# print(f"F1分數: {metrics['f1_macro']:.4f}")
|
||
# print(f"結果保存位置: {results_dir}")
|
||
|
||
# return Best_Normal_Model_Path, Best_CA_Model_Path, segmentation_best_model_path |