diff --git a/Load_process/Load_Indepentend.py b/Load_process/Load_Indepentend.py index 157a6c6..538d8e5 100644 --- a/Load_process/Load_Indepentend.py +++ b/Load_process/Load_Indepentend.py @@ -21,8 +21,8 @@ class Load_Indepentend_Data(): self.test, self.test_label = self.get_Independent_image(Test_data_root) print("\ntest_labels有" + str(len(self.test_label)) + "筆資料\n") - self.validation, self.validation_label = self.get_Independent_image(Validation_data_root) - print("validation_labels有 " + str(len(self.validation_label)) + " 筆資料\n") + # self.validation, self.validation_label = self.get_Independent_image(Validation_data_root) + # print("validation_labels有 " + str(len(self.validation_label)) + " 筆資料\n") def get_Independent_image(self, independent_DataRoot): image_processing = Read_image_and_Process_image(123) diff --git a/Load_process/__pycache__/Load_Indepentend.cpython-311.pyc b/Load_process/__pycache__/Load_Indepentend.cpython-311.pyc index 6cc8851..dbab7c8 100644 Binary files a/Load_process/__pycache__/Load_Indepentend.cpython-311.pyc and b/Load_process/__pycache__/Load_Indepentend.cpython-311.pyc differ diff --git a/Training_Tools/PreProcess.py b/Training_Tools/PreProcess.py new file mode 100644 index 0000000..5b0647d --- /dev/null +++ b/Training_Tools/PreProcess.py @@ -0,0 +1,53 @@ +from torch.utils.data import Dataset, DataLoader, RandomSampler +import torchvision.transforms as transforms +import torch + +class ListDataset(Dataset): + def __init__(self, data_list, labels_list, status): + self.data = data_list + self.labels = labels_list + self.status = status + + def __len__(self): + return len(self.data) + + def __getitem__(self, idx): + sample = self.data[idx] + + if self.status: + from Image_Process.Image_Generator import Image_generator + ImageGenerator = Image_generator("", "", 12) + Transform = ImageGenerator.Generator_Content(5) + sample = Transform(sample) + + label = self.labels[idx] + return sample, label + +class Training_Precesses: + def __init__(self, Training_Datas, Training_Labels, Testing_Datas, Testing_Labels): + self.Training_Datas = Training_Datas + self.Training_Labels = Training_Labels + self.Testing_Datas = Testing_Datas + self.Testing_Labels = Testing_Labels + pass + + def Total_Data_Combine_To_DataLoader(self, Batch_Size): + Training_Dataset = self.Convert_Data_To_DataSet(self.Training_Datas, self.Training_Labels) + Testing_Dataset = self.Convert_Data_To_DataSet(self.Testing_Datas, self.Testing_Labels) + + Training_DataLoader = DataLoader(dataset = Training_Dataset, batch_size = Batch_Size, num_workers = 0, pin_memory=True, shuffle = True) + Testing_DataLoader = DataLoader(dataset = Testing_Dataset, batch_size = 1, num_workers = 0, pin_memory=True, shuffle = True) + + return Training_DataLoader, Testing_DataLoader + + def Convert_Data_To_DataSet(self, Datas : list, Labels : list, status : bool = True): + seed = 42 # 設定任意整數作為種子 + # 產生隨機種子產生器 + generator = torch.Generator() + generator.manual_seed(seed) + + # 創建 Dataset + list_dataset = ListDataset(Datas, Labels, status) + # sampler = RandomSampler(list_dataset, generator = generator) # 創建Sampler + + return list_dataset diff --git a/Training_Tools/Tools.py b/Training_Tools/Tools.py index febafbe..f89d15e 100644 --- a/Training_Tools/Tools.py +++ b/Training_Tools/Tools.py @@ -1,30 +1,8 @@ import pandas as pd from torch.nn import functional import torch -from torch.utils.data import Dataset, DataLoader, RandomSampler -import torchvision.transforms as transforms -class ListDataset(Dataset): - def __init__(self, data_list, labels_list, status): - self.data = data_list - self.labels = labels_list - self.status = status - - def __len__(self): - return len(self.data) - - def __getitem__(self, idx): - sample = self.data[idx] - - if self.status: - from Image_Process.Image_Generator import Image_generator - ImageGenerator = Image_generator("", "", 12) - Transform = ImageGenerator.Generator_Content(5) - sample = Transform(sample) - - label = self.labels[idx] - return sample, label - + class Tool: def __init__(self) -> None: self.__ICG_Training_Root = "" @@ -84,8 +62,8 @@ class Tool: def Get_Save_Roots(self, choose): '''回傳結果為Train, test, validation - choose = 1 => 取ICG Label - else => 取Normal Label + choose = 1 => 取白光 Label + else => 取濾光 Label 若choose != 1 || choose != 2 => 會回傳四個結果 ''' @@ -106,16 +84,4 @@ class Tool: return self.__Comprehensive_Generator_Root def Get_OneHot_Encording_Label(self): - return self.__OneHot_Encording - - def Convert_Data_To_DataSet_And_Put_To_Dataloader(self, Datas : list, Labels : list, Batch_Size : int, status : bool = True): - seed = 42 # 設定任意整數作為種子 - # 產生隨機種子產生器 - generator = torch.Generator() - generator.manual_seed(seed) - - # 創建 Dataset - list_dataset = ListDataset(Datas, Labels, status) - # sampler = RandomSampler(list_dataset, generator = generator) # 創建Sampler - - return DataLoader(dataset = list_dataset, batch_size = Batch_Size, num_workers = 0, pin_memory=True, shuffle = True) \ No newline at end of file + return self.__OneHot_Encording \ No newline at end of file diff --git a/Training_Tools/__pycache__/PreProcess.cpython-311.pyc b/Training_Tools/__pycache__/PreProcess.cpython-311.pyc new file mode 100644 index 0000000..adbd1ed Binary files /dev/null and b/Training_Tools/__pycache__/PreProcess.cpython-311.pyc differ diff --git a/Training_Tools/__pycache__/Tools.cpython-311.pyc b/Training_Tools/__pycache__/Tools.cpython-311.pyc index fc4fe30..9f1b3a4 100644 Binary files a/Training_Tools/__pycache__/Tools.cpython-311.pyc and b/Training_Tools/__pycache__/Tools.cpython-311.pyc differ diff --git a/experiments/Model_All_Step.py b/experiments/Model_All_Step.py index a8da593..9335c3d 100644 --- a/experiments/Model_All_Step.py +++ b/experiments/Model_All_Step.py @@ -1,6 +1,7 @@ from tqdm import tqdm import torch from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score +from sklearn.model_selection import KFold from torchmetrics.functional import auroc import torch.optim as optim import numpy as np @@ -8,14 +9,14 @@ from all_models_tools.all_model_tools import call_back from Model_Loss.Loss import Entropy_Loss from merge_class.merge import merge from draw_tools.Grad_cam import GradCAM +from torch.utils.data import Subset, DataLoader import time class All_Step: - def __init__(self, Training_Data_And_Label, Test_Data_And_Label, Validation_Data_And_Label, Model, Epoch, Number_Of_Classes, Model_Name): - self.Training_Data_And_Label = Training_Data_And_Label - self.Test_Data_And_Label = Test_Data_And_Label - self.Validation_Data_And_Label = Validation_Data_And_Label + def __init__(self, PreProcess_Classes_Data, Batch, Model, Epoch, Number_Of_Classes, Model_Name): + self.PreProcess_Classes_Data = PreProcess_Classes_Data + self.Training_DataLoader, self.Test_Dataloader = self.PreProcess_Classes_Data.Total_Data_Combine_To_DataLoader(Batch) self.Model = Model self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') @@ -40,6 +41,8 @@ class All_Step: val_accuracies = [] Total_Epoch = 0 + K_Flod = KFold(n_splits = 5, shuffle = True, random_state = 42) + for epoch in range(self.Epoch): # 訓練迴圈 self.Model.train() # 開始訓練 running_loss = 0.0 @@ -49,94 +52,103 @@ class All_Step: # 計算每個 epoch 的起始時間 start_time = time.time() - total_samples = len(self.Training_Data_And_Label) + total_samples = len(self.Training_DataLoader) + train_subset = "" + val_subset = "" - epoch_iterator = tqdm(self.Training_Data_And_Label, desc=f"Epoch [{epoch}/{self.Epoch}]") + for fold, (train_idx, vali_idx) in enumerate( K_Flod.split(self.PreProcess_Classes_Data.Training_Datas)): + # Create training and validation subsets for this fold + train_subset = Subset(self.Training_DataLoader, train_idx) + val_subset = Subset(self.Training_DataLoader, vali_idx) - for inputs, labels in epoch_iterator: - inputs, labels = torch.as_tensor(inputs).to(self.device), torch.as_tensor(labels).to(self.device) + Training_Data = DataLoader(train_subset, self.Training_DataLoader.batch_size, num_workers = 0, pin_memory=True, shuffle = True) - Optimizer.zero_grad() - outputs = self.Model(inputs) - loss = criterion(outputs, labels) - loss.backward() - Optimizer.step() - running_loss += loss.item() + epoch_iterator = tqdm(Training_Data, desc=f"Epoch [{epoch}/{self.Epoch}]") - # 收集訓練預測和標籤 - Output_Values, Output_Indexs = torch.max(outputs, dim = 1) - True_Indexs = np.argmax(labels.cpu().numpy(), 1) - - all_train_preds.append(Output_Indexs.cpu().numpy()) - all_train_labels.append(True_Indexs) - - processed_samples += len(inputs) - - # 計算當前進度 - progress = (processed_samples / total_samples) * 100 - - # 計算經過時間和剩餘時間 - elapsed_time = time.time() - start_time - iterations_per_second = processed_samples / elapsed_time if elapsed_time > 0 else 0 - eta = (total_samples - processed_samples) / iterations_per_second if iterations_per_second > 0 else 0 - time_str = f"{int(elapsed_time//60):02d}:{int(elapsed_time%60):02d}<{int(eta//60):02d}:{int(eta%60):02d}" - - # 計算當前批次的精確度(這裡需要根據你的具體需求調整) - batch_accuracy = (Output_Indexs.cpu().numpy() == True_Indexs).mean() - - # 更新進度條顯示 - epoch_iterator.set_description(f"Epoch [{epoch}/{self.Epoch}]") - epoch_iterator.set_postfix_str( - f"{processed_samples}/{total_samples} [{time_str}, {iterations_per_second:.2f}it/s, " + - f"acc={batch_accuracy:.3f}, loss={loss.item():.3f}, ]" - ) - - epoch_iterator.close() - - all_train_preds = Merge_Function.merge_data_main(all_train_preds, 0, len(all_train_preds)) - all_train_labels = Merge_Function.merge_data_main(all_train_labels, 0, len(all_train_labels)) - - Training_Loss = running_loss / len(self.Training_Data_And_Label) - train_accuracy = accuracy_score(all_train_labels, all_train_preds) - - train_losses.append(Training_Loss) - train_accuracies.append(train_accuracy) - - self.Model.eval() - val_loss = 0.0 - all_val_preds = [] - all_val_labels = [] - - with torch.no_grad(): - for inputs, labels in self.Validation_Data_And_Label: + for inputs, labels in epoch_iterator: inputs, labels = torch.as_tensor(inputs).to(self.device), torch.as_tensor(labels).to(self.device) + Optimizer.zero_grad() outputs = self.Model(inputs) loss = criterion(outputs, labels) - val_loss += loss.item() + loss.backward() + Optimizer.step() + running_loss += loss.item() # 收集訓練預測和標籤 Output_Values, Output_Indexs = torch.max(outputs, dim = 1) True_Indexs = np.argmax(labels.cpu().numpy(), 1) + + all_train_preds.append(Output_Indexs.cpu().numpy()) + all_train_labels.append(True_Indexs) - all_val_preds.append(Output_Indexs.cpu().numpy()) - all_val_labels.append(True_Indexs) + processed_samples += len(inputs) - val_loss /= len(self.Validation_Data_And_Label) - val_accuracy = accuracy_score(all_val_labels, all_val_preds) + # 計算當前進度 + progress = (processed_samples / total_samples) * 100 + + # 計算經過時間和剩餘時間 + elapsed_time = time.time() - start_time + iterations_per_second = processed_samples / elapsed_time if elapsed_time > 0 else 0 + eta = (total_samples - processed_samples) / iterations_per_second if iterations_per_second > 0 else 0 + time_str = f"{int(elapsed_time//60):02d}:{int(elapsed_time%60):02d}<{int(eta//60):02d}:{int(eta%60):02d}" - val_losses.append(val_loss) - val_accuracies.append(val_accuracy) - # print(f"Val_loss: {val_loss:.4f}, Val_accuracy: {val_accuracy:0.2f}\n") + # 計算當前批次的精確度(這裡需要根據你的具體需求調整) + batch_accuracy = (Output_Indexs.cpu().numpy() == True_Indexs).mean() - early_stopping(val_loss, self.Model, model_path) - if early_stopping.early_stop: - print("Early stopping triggered. Training stopped.") - Total_Epoch = epoch - break + # 更新進度條顯示 + epoch_iterator.set_description(f"Epoch [{epoch}/{self.Epoch}]") + epoch_iterator.set_postfix_str( + f"{processed_samples}/{total_samples} [{time_str}, {iterations_per_second:.2f}it/s, " + + f"acc={batch_accuracy:.3f}, loss={loss.item():.3f}, ]" + ) - # 學習率調整 - scheduler.step(val_loss) + epoch_iterator.close() + + all_train_preds = Merge_Function.merge_data_main(all_train_preds, 0, len(all_train_preds)) + all_train_labels = Merge_Function.merge_data_main(all_train_labels, 0, len(all_train_labels)) + + Training_Loss = running_loss / len(self.Training_DataLoader) + train_accuracy = accuracy_score(all_train_labels, all_train_preds) + + train_losses.append(Training_Loss) + train_accuracies.append(train_accuracy) + + self.Model.eval() + val_loss = 0.0 + all_val_preds = [] + all_val_labels = [] + + with torch.no_grad(): + for inputs, labels in val_subset: + inputs, labels = torch.as_tensor(inputs).to(self.device), torch.as_tensor(labels).to(self.device) + + outputs = self.Model(inputs) + loss = criterion(outputs, labels) + val_loss += loss.item() + + # 收集訓練預測和標籤 + Output_Values, Output_Indexs = torch.max(outputs, dim = 1) + True_Indexs = np.argmax(labels.cpu().numpy(), 1) + + all_val_preds.append(Output_Indexs.cpu().numpy()) + all_val_labels.append(True_Indexs) + + val_loss /= len(val_subset) + val_accuracy = accuracy_score(all_val_labels, all_val_preds) + + val_losses.append(val_loss) + val_accuracies.append(val_accuracy) + # print(f"Val_loss: {val_loss:.4f}, Val_accuracy: {val_accuracy:0.2f}\n") + + early_stopping(val_loss, self.Model, model_path) + if early_stopping.early_stop: + print("Early stopping triggered. Training stopped.") + Total_Epoch = epoch + break + + # 學習率調整 + scheduler.step(val_loss) return train_losses, val_losses, train_accuracies, val_accuracies, Total_Epoch @@ -148,7 +160,7 @@ class All_Step: loss = 0.0 with torch.no_grad(): - for images, labels in self.Test_Data_And_Label: + for images, labels in self.Test_Dataloader: images, labels = torch.tensor(images).to(self.device), torch.tensor(labels).to(self.device) outputs = cnn_model(images) @@ -163,13 +175,13 @@ class All_Step: Predict_Label_OneHot.append(torch.tensor(outputs, dtype = torch.float32).cpu().numpy()[0]) True_Label_OneHot.append(torch.tensor(labels, dtype = torch.int).cpu().numpy()[0]) - # 創建 GradCAM 實例 - Layers = cnn_model.base_model.body.conv4.pointwise - grad_cam = GradCAM(cnn_model, target_layer="base_model") - # 可視化 Grad-CAM - grad_cam.visualize(outputs, images, target_class = 3, File_Name = counter, model_name = self.Model_Name) + # # 創建 GradCAM 實例 + # Layers = cnn_model.base_model.body.conv4.pointwise + # grad_cam = GradCAM(cnn_model, target_layer="base_model") + # # 可視化 Grad-CAM + # grad_cam.visualize(outputs, images, target_class = 3, File_Name = counter, model_name = self.Model_Name) - loss /= len(self.Test_Data_And_Label) + loss /= len(self.Test_Dataloader) True_Label_OneHot = torch.tensor(True_Label_OneHot, dtype = torch.int) Predict_Label_OneHot = torch.tensor(Predict_Label_OneHot, dtype = torch.float32) diff --git a/experiments/__pycache__/Model_All_Step.cpython-311.pyc b/experiments/__pycache__/Model_All_Step.cpython-311.pyc index 1b9e882..2d95cf8 100644 Binary files a/experiments/__pycache__/Model_All_Step.cpython-311.pyc and b/experiments/__pycache__/Model_All_Step.cpython-311.pyc differ diff --git a/experiments/__pycache__/experiment.cpython-311.pyc b/experiments/__pycache__/experiment.cpython-311.pyc index 881fa87..4fc3c95 100644 Binary files a/experiments/__pycache__/experiment.cpython-311.pyc and b/experiments/__pycache__/experiment.cpython-311.pyc differ diff --git a/experiments/__pycache__/pytorch_Model.cpython-311.pyc b/experiments/__pycache__/pytorch_Model.cpython-311.pyc index 7a5baa0..d6113b4 100644 Binary files a/experiments/__pycache__/pytorch_Model.cpython-311.pyc and b/experiments/__pycache__/pytorch_Model.cpython-311.pyc differ diff --git a/experiments/experiment.py b/experiments/experiment.py index 5f6386b..14ab88c 100644 --- a/experiments/experiment.py +++ b/experiments/experiment.py @@ -5,6 +5,7 @@ from Load_process.file_processing import Process_File from sklearn.metrics import confusion_matrix from experiments.pytorch_Model import ModifiedXception from experiments.Model_All_Step import All_Step +from Training_Tools.PreProcess import Training_Precesses from torchinfo import summary import pandas as pd import numpy as np @@ -13,7 +14,7 @@ import torch.nn as nn import time class experiments(): - def __init__(self, Image_Size, Model_Name, Experiment_Name, Generator_Batch_Size, Epoch, Train_Batch_Size, tools, Number_Of_Classes, status): + def __init__(self, Image_Size, Model_Name, Experiment_Name, Epoch, Train_Batch_Size, tools, Number_Of_Classes, status): ''' # 實驗物件 @@ -49,7 +50,6 @@ class experiments(): self.model_name = Model_Name # 取名,告訴我我是用哪個模型(可能是預處理模型/自己設計的模型) self.experiment_name = Experiment_Name - self.generator_batch_size = Generator_Batch_Size self.epoch = Epoch self.train_batch_size = Train_Batch_Size self.layers = 1 @@ -62,7 +62,7 @@ class experiments(): pass - def processing_main(self, Training_Dataset, counter): + def processing_main(self, Training_Data, Training_Label, counter): Train, Test, Validation = self.Topic_Tool.Get_Save_Roots(self.Status) # 要換不同資料集就要改 start = time.time() @@ -72,22 +72,15 @@ class experiments(): # 將處理好的test Data 與 Validation Data 丟給這個物件的變數 self.test, self.test_label = self.cut_image.test, self.cut_image.test_label - self.validation, self.validation_label = self.cut_image.validation, self.cut_image.validation_label - Testing_Dataset = self.Topic_Tool.Convert_Data_To_DataSet_And_Put_To_Dataloader(self.test, self.test_label, 1) - Validation_Dataset = self.Topic_Tool.Convert_Data_To_DataSet_And_Put_To_Dataloader(self.validation, self.validation_label, 1) + PreProcess = Training_Precesses(Training_Data, Training_Label, self.test, self.test_label) cnn_model = self.construct_model() # 呼叫讀取模型的function print(summary(cnn_model, input_size=(int(self.train_batch_size / 2), 3, self.Image_Size, self.Image_Size))) for name, parameters in cnn_model.named_parameters(): print(f"Layer Name: {name}, Parameters: {parameters.size()}") - step = All_Step(Training_Dataset, Testing_Dataset, Validation_Dataset, cnn_model, self.epoch, self.Number_Of_Classes, self.model_name) - - # model_dir = '../save_the_best_model/Topic/Remove background with Normal image/best_model( 2023-10-17 )-2.h5' # 這是一個儲存模型權重的路徑,每一個模型都有一個自己權重儲存的檔 - # if os.path.exists(model_dir): # 如果這個檔案存在 - # cnn_model.load_weights(model_dir) # 將模型權重讀出來 - # print("讀出權重\n") + step = All_Step(PreProcess, self.train_batch_size, cnn_model, self.epoch, self.Number_Of_Classes, self.model_name) print("\n\n\n讀取訓練資料(70000)執行時間:%f 秒\n\n" % (end - start)) train_losses, val_losses, train_accuracies, val_accuracies, Epoch = step.Training_Step(self.model_name, counter) diff --git a/experiments/pytorch_Model.py b/experiments/pytorch_Model.py index ac5cfc6..cf0b659 100644 --- a/experiments/pytorch_Model.py +++ b/experiments/pytorch_Model.py @@ -10,41 +10,33 @@ class ModifiedXception(nn.Module): def __init__(self, num_classes): super(ModifiedXception, self).__init__() - # 加載 Xception 預訓練模型,去掉最後一層 (fc 層) + # Load Xception pre-trained model (full model, not just features) self.base_model = timm.create_model( - 'xception', - pretrained=True, - features_only=True, # 只保留特徵提取部分 - out_indices=[3] # 選擇特徵層索引(根據模型結構) - ) + 'xception', + pretrained=True, + drop_rate=0.0, # Optional: adjust dropout if needed + ) - # 自定義分類頭 + # Replace the default global pooling with AdaptiveAvgPool2d + self.base_model.global_pool = nn.AdaptiveAvgPool2d(output_size=1) # Output size of 1x1 spatially + + # Replace the final fully connected layer with Identity to get features + self.base_model.fc = nn.Identity() # Output will be 2048 (Xception's default feature size) + + # Custom head: Linear from 2048 to 1370, additional 1370 layer, then to num_classes self.custom_head = nn.Sequential( - nn.AdaptiveAvgPool2d(1), # Global Average Pooling, - nn.Flatten(), - nn.Linear(728, 368), # Xception 輸出特徵維度為2048 - nn.ReLU(), # 可選激活函數 - nn.Linear(368, num_classes), - nn.Sigmoid() + nn.Linear(2048, 1025), # From Xception’s 2048 features to 1370 + nn.ReLU(), # Activation + nn.Dropout(0.6), # Dropout for regularization + nn.Linear(1025, num_classes), # Final output layer + nn.Sigmoid() # Sigmoid for binary/multi-label classification ) - # self.base_model.fc = nn.Identity() # 移除原來的 fully connected 層 - - # # 新增全局平均池化層、隱藏層和輸出層 - # self.global_avg_pool = nn.AdaptiveAvgPool2d(1) # 全局平均池化 - # self.hidden_layer = nn.Linear(2048, 1370) # 隱藏層,輸入大小取決於 Xception 的輸出大小 - # self.output_layer = nn.Linear(1370, 2) # 輸出層,依據分類數目設定 - - # # 激活函數與 dropout - # self.relu = nn.ReLU() - # self.dropout = nn.Dropout(0.6) - def forward(self, x): - x = self.base_model(x) # Xception 主體 - x = x[0] - output = self.custom_head(x) - # x = self.global_avg_pool(x) # 全局平均池化 - # x = self.relu(self.hidden_layer(x)) # 隱藏層 + ReLU - # x = self.dropout(x) # Dropout - # x = self.output_layer(x) # 輸出層 + # Pass through the base Xception model (up to global pooling) + x = self.base_model.forward_features(x) # Get feature maps + x = self.base_model.global_pool(x) # Apply AdaptiveAvgPool2d (output: [B, 2048, 1, 1]) + x = x.flatten(1) # Flatten to [B, 2048] + x = self.base_model.fc(x) # Identity layer (still [B, 2048]) + output = self.custom_head(x) # Custom head processing return output diff --git a/experiments/topic_model.py b/experiments/topic_model.py deleted file mode 100644 index fbf7467..0000000 --- a/experiments/topic_model.py +++ /dev/null @@ -1,298 +0,0 @@ -from convolution_model_tools.convolution_2D_tools import model_2D_tool -from dense_model_tools.dense_tools import model_Dense_Layer -from all_models_tools.all_model_tools import add_optimizers_function, add_Activative, add_dropout, call_back -from keras.activations import softmax, sigmoid -from keras.applications import VGG19, ResNet50, NASNetLarge, DenseNet201, Xception -from keras.applications.efficientnet_v2 import EfficientNetV2L -from keras.layers import BatchNormalization, Flatten, GlobalAveragePooling2D, MaxPooling2D, Dense, Conv2D, Dropout, TimeDistributed, LSTM, Input -from keras import regularizers - -def one_layer_cnn_model(): - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - img_Input = tools.add_2D_input() - x = tools.add_Convolution2D(img_Input, 32) - x = add_Activative(x) - x = tools.add_MaxPooling(x) - - x = tools.add_Convolution2D(x, 64) - x = add_Activative(x) - x = tools.add_MaxPooling(x) - - flatter = tools.add_flatten(x) - - dense = dense_tool.add_dense(64, flatter) - dense = add_Activative(dense) - dense = dense_tool.add_dense(32, dense) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - return img_Input, dense - -def find_example_cnn_model(): - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - img_Input = tools.add_2D_input() - - x = tools.add_Convolution2D(img_Input, 16) - x = add_Activative(x) - x = add_dropout(x, 0.25) - - x = tools.add_Convolution2D(x, 32) - x = add_Activative(x) - x = add_dropout(x, 0.25) - - x = tools.add_MaxPooling(x) - - x = tools.add_Convolution2D(x, 64) - x = add_Activative(x) - x = add_dropout(x, 0.25) - - x = tools.add_MaxPooling(x) - - x = tools.add_Convolution2D(x, 128) - x = add_Activative(x) - x = add_dropout(x, 0.25) - - x = tools.add_MaxPooling(x) - - flatter = tools.add_flatten(x) - - dense = dense_tool.add_dense(64, flatter) - dense = add_Activative(dense) - dense = add_dropout(dense, 0.25) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, sigmoid) - - return img_Input, dense - -def change_example_cnn_model(): - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - img_Input = tools.add_2D_input() - - x = tools.add_Convolution2D(img_Input, 16) - x = add_Activative(x) - x = tools.add_batchnomlization(x) - - x = tools.add_Convolution2D(x, 32) - x = add_Activative(x) - x = tools.add_batchnomlization(x) - - x = tools.add_MaxPooling(x) - - x = tools.add_Convolution2D(x, 64) - x = add_Activative(x) - x = tools.add_batchnomlization(x) - - x = tools.add_MaxPooling(x) - - x = tools.add_Convolution2D(x, 128) - x = add_Activative(x) - x = tools.add_batchnomlization(x) - - x = tools.add_MaxPooling(x) - - flatter = tools.add_flatten(x) - - dense = dense_tool.add_dense(64, flatter) - dense = add_Activative(dense) - dense = add_dropout(dense, 0.3) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return img_Input, dense - -def two_convolution_cnn_model(): - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - img_Input = tools.add_2D_input() - x = tools.add_two_floors_convolution2D(img_Input, 32) - x = tools.add_MaxPooling(x) - - x = tools.add_two_floors_convolution2D(x, 64) - x = tools.add_MaxPooling(x) - - flatter = tools.add_flatten(x) - - dense = dense_tool.add_dense(64, flatter) - dense = add_Activative(dense) - dense = dense_tool.add_dense(32, dense) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - return img_Input, dense - -def VGG19_model(): - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - vgg19 = VGG19(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(vgg19.output) - dense = dense_tool.add_dense(64, flatten) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return vgg19, dense - -def Resnet50_model(): - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - vgg19 = ResNet50(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(vgg19.output) - dense = dense_tool.add_dense(64, flatten) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return vgg19, dense - -def DenseNet201_model(): - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - Densenet201 = DenseNet201(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(Densenet201.output) - dense = dense_tool.add_dense(64, flatten) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return Densenet201, dense - -def Xception_model(): - xception = Xception(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = Flatten()(xception.output) - dense = Dense(units = 64, activation = "relu")(flatten) - dense = Dense(units = 7, activation = "softmax")(dense) - - return xception, dense - -def cnn_LSTM(): - head = Input(shape = (150, 150, 3)) - inputs = Conv2D(filters = 64, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(head) - inputs = Conv2D(filters = 64, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = MaxPooling2D(strides = 2, pool_size = (2, 2))(inputs) - inputs = Dropout(0.25)(inputs) - - inputs = Conv2D(filters = 128, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = Conv2D(filters = 128, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = MaxPooling2D(strides = 2, pool_size = (2, 2))(inputs) - inputs = Dropout(0.25)(inputs) - - inputs = Conv2D(filters = 256, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = Conv2D(filters = 256, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = MaxPooling2D(strides = 2, pool_size = (2, 2))(inputs) - inputs = Dropout(0.25)(inputs) - - inputs = Conv2D(filters = 512, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = Conv2D(filters = 512, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = Conv2D(filters = 512, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = MaxPooling2D(strides = 2, pool_size = (2, 2))(inputs) - inputs = Dropout(0.25)(inputs) - - inputs = Conv2D(filters = 512, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = Conv2D(filters = 512, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = Conv2D(filters = 512, strides = 1, kernel_size = (3, 3), padding = "same", activation = "relu")(inputs) - inputs = MaxPooling2D(strides = 2, pool_size = (2, 2))(inputs) - inputs = Dropout(0.25)(inputs) - inputs = TimeDistributed(Flatten())(inputs) - - inputs = LSTM(units = 49)(inputs) - inputs = Dense(units = 64)(inputs) - output = Dense(units = 7, activation = "softmax")(inputs) - - return head, output - -def add_regularizers_L1(): # 比較正規化 - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - Resnet50 = ResNet50(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(Resnet50.output) - dense = dense_tool.add_regularizer_dense(64, flatten, regularizers.L1()) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return Resnet50, dense - -def add_regularizers_L2(): # 比較正規化 - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - Resnet50 = ResNet50(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(Resnet50.output) - dense = dense_tool.add_regularizer_dense(64, flatten, regularizers.L2()) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return Resnet50, dense - -def add_regularizers_L1L2(): # 比較正規化 - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - Resnet50 = ResNet50(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(Resnet50.output) - dense = dense_tool.add_regularizer_dense(64, flatten, regularizers.L1L2()) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return Resnet50, dense - -def add_layers1_L2(Dense_layers): # 比較正規化 - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - layers = 32 - - Densenet201 = DenseNet201(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(Densenet201.output) - - for layer in range(Dense_layers): - dense = dense_tool.add_regularizer_kernel_dense(unit = layers, input_data = flatten, regularizer = regularizers.L2()) - dense = add_Activative(dense) - layers *= 2 - - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return Densenet201, dense - -def add_layers_another_L2(Dense_layers, layers): # 比較正規化 - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - Densenet201 = DenseNet201(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(Densenet201.output) - - for layer in range(Dense_layers): - dense = dense_tool.add_regularizer_dense(unit = layers, input_data = flatten, regularizer = regularizers.L2()) - dense = add_Activative(dense) - layers /= 2 - - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return Densenet201, dense - -def add_bias_regularizers(): # 比較正規化 - tools = model_2D_tool() - dense_tool = model_Dense_Layer() - - Resnet50 = ResNet50(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) - flatten = tools.add_flatten(Resnet50.output) - dense = dense_tool.add_regularizer_bias_dense(64, flatten, regularizers.L2()) - dense = add_Activative(dense) - dense = dense_tool.add_dense(7, dense) - dense = add_Activative(dense, softmax) - - return Resnet50, dense \ No newline at end of file diff --git a/main.py b/main.py index 834a666..9c06709 100644 --- a/main.py +++ b/main.py @@ -8,7 +8,6 @@ from Calculate_Process.Calculate import Calculate from merge_class.merge import merge import time import torch -import os if __name__ == "__main__": # 測試GPU是否可用 @@ -23,7 +22,7 @@ if __name__ == "__main__": tool.Set_Labels() tool.Set_Save_Roots() - Status = 2 # 決定要使用什麼資料集 + Status = 1 # 決定要使用什麼資料集 Labels = tool.Get_Data_Label() Trainig_Root, Testing_Root, Validation_Root = tool.Get_Save_Roots(Status) # 一般的 Generator_Root = tool.Get_Generator_Save_Roots(Status) @@ -37,14 +36,13 @@ if __name__ == "__main__": Model_Name = "Xception" # 取名,告訴我我是用哪個模型(可能是預處理模型/自己設計的模型) Experiment_Name = "Xception Skin to train Normal stomach cancer" - Generator_Batch_Size = 50 Epoch = 10000 - Train_Batch_Size = 50 + Train_Batch_Size = 64 Image_Size = 256 Prepare = Load_Data_Prepare() loading_data = Load_ImageGenerator(Trainig_Root, Testing_Root, Validation_Root, Generator_Root, Labels, Image_Size) - experiment = experiments(Image_Size, Model_Name, Experiment_Name, Generator_Batch_Size, Epoch, Train_Batch_Size, tool, Classification, Status) + experiment = experiments(Image_Size, Model_Name, Experiment_Name, Epoch, Train_Batch_Size, tool, Classification, Status) image_processing = Read_image_and_Process_image(Image_Size) Merge = merge() Calculate_Tool = Calculate() @@ -81,17 +79,7 @@ if __name__ == "__main__": start = time.time() trains_Data_Image = image_processing.Data_Augmentation_Image(training_data) # 讀檔 - - # total_trains, train_label = shuffle_data(trains_Data_Image, training_label) # 將資料打亂 - # training_data = list(total_trains) # 轉換資料型態 - - training_data, train_label = image_processing.image_data_processing(trains_Data_Image, training_label) # 將讀出來的檔做正規化。降label轉成numpy array 格式 - Training_Dataset = tool.Convert_Data_To_DataSet_And_Put_To_Dataloader(training_data, train_label, Train_Batch_Size) - - # 查看Dataloader的Shape - for idx, data in enumerate(Training_Dataset): - datas = data[0] - print(f"Shape: {datas.shape}") + Training_Data, Training_Label = image_processing.image_data_processing(trains_Data_Image, training_label) # 將讀出來的檔做正規化。降label轉成numpy array 格式 # training_data = image_processing.normalization(training_data) @@ -100,7 +88,7 @@ if __name__ == "__main__": end = time.time() print("\n\n\n讀取訓練資料(70000)執行時間:%f 秒\n\n" % (end - start)) - loss, accuracy, precision, recall, AUC, f = experiment.processing_main(Training_Dataset, Run_Range) # 執行訓練方法 + loss, accuracy, precision, recall, AUC, f = experiment.processing_main(Training_Data, Training_Label, Run_Range) # 執行訓練方法 Calculate_Tool.Append_numbers(loss, accuracy, precision, recall, AUC, f) print("實驗結果") diff --git a/test.ipynb b/test.ipynb index cd5844d..aa43732 100644 --- a/test.ipynb +++ b/test.ipynb @@ -1857,6 +1857,36 @@ "model.base_model.body.conv4.pointwise" ] }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(array([0, 3, 4, 5, 6, 7]), array([1, 2])), (array([0, 1, 2, 4, 6, 7]), array([3, 5])), (array([1, 2, 3, 5, 6, 7]), array([0, 4])), (array([0, 1, 2, 3, 4, 5, 6]), array([7])), (array([0, 1, 2, 3, 4, 5, 7]), array([6]))]\n", + "[0 1 2 3 4 7] [5 6]\n", + "[0 1 2 5 6 7] [3 4]\n", + "[1 2 3 4 5 6] [0 7]\n", + "[0 2 3 4 5 6 7] [1]\n", + "[0 1 3 4 5 6 7] [2]\n" + ] + } + ], + "source": [ + "from sklearn.model_selection import KFold\n", + "\n", + "k = KFold(n_splits = 5, shuffle = True)\n", + "a = [1, 2, 3, 4 ,5, 6,7, 8]\n", + "\n", + "print(list(k.split(a)))\n", + "\n", + "for d, b in k.split(a):\n", + " print(d, b)" + ] + }, { "cell_type": "code", "execution_count": null, @@ -1881,7 +1911,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.10" + "version": "3.11.11" } }, "nbformat": 4,