20250308 commits: K-Fold script have inital struction, but have some question
This commit is contained in:
@@ -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)
|
||||
|
||||
Binary file not shown.
53
Training_Tools/PreProcess.py
Normal file
53
Training_Tools/PreProcess.py
Normal file
@@ -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
|
||||
@@ -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)
|
||||
return self.__OneHot_Encording
|
||||
BIN
Training_Tools/__pycache__/PreProcess.cpython-311.pyc
Normal file
BIN
Training_Tools/__pycache__/PreProcess.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
@@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
22
main.py
22
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("實驗結果")
|
||||
|
||||
32
test.ipynb
32
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,
|
||||
|
||||
Reference in New Issue
Block a user