commit 4bd0ae023d6b347cff745bc38c1ba060de594640 Author: whitekirin <113206109@gms.tcu.edu.tw> Date: Sat Dec 7 02:00:39 2024 +0800 Firsh Push at 20241207 diff --git a/.hypothesis/unicode_data/13.0.0/charmap.json.gz b/.hypothesis/unicode_data/13.0.0/charmap.json.gz new file mode 100644 index 0000000..ae80d58 Binary files /dev/null and b/.hypothesis/unicode_data/13.0.0/charmap.json.gz differ diff --git a/Calculate_Process/Calculate.py b/Calculate_Process/Calculate.py new file mode 100644 index 0000000..00f44ce --- /dev/null +++ b/Calculate_Process/Calculate.py @@ -0,0 +1,74 @@ +import numpy as np +import pandas as pd +from decimal import Decimal, ROUND_HALF_UP + +class Calculate(): + def __init__(self) -> None: + self.Loss, self.Accuracy, self.Precision, self.Recall, self.F1, self.AUC = 0, 0, 0, 0, 0, 0 + self.Loss_Record, self.Accuracy_Record, self.Precision_Record, self.Recall_Record, self.F1_Record, self.AUC_Record = [], [], [], [], [], [] + self.History = [] + pass + + def Append_numbers(self, Loss, Accuracy, Precision, Recall, AUC, F1): + self.Loss_Record.append(Loss) + self.Accuracy_Record.append(Accuracy) + self.Precision_Record.append(Precision) + self.Recall_Record.append(Recall) + self.F1_Record.append(F1) + self.AUC_Record.append(AUC) + pass + + def Calculate_Mean(self): + Loss_Mean = np.mean(self.Loss_Record) + Accuracy_Mean = np.mean(self.Accuracy_Record) + Precision_Mean = np.mean(self.Precision_Record) + Recall_Mean = np.mean(self.Recall_Record) + F1_Mean = np.mean(self.F1_Record) + AUC_Mean = np.mean(self.AUC_Record) + + Mean_DataFram = pd.DataFrame( + { + "loss" : "{:.2f}".format(Loss_Mean), + "precision" : "{:.2f}%".format(Precision_Mean * 100), + "recall" : "{:.2f}%".format(Recall_Mean * 100), + "accuracy" : "{:.2f}%".format(Accuracy_Mean * 100), + "f" : "{:.2f}%".format(F1_Mean * 100), + "AUC" : "{:.2f}%".format(AUC_Mean * 100) + }, index = [0] + ) + self.History.append(Mean_DataFram) + return Mean_DataFram + + def Calculate_Std(self): + Loss_Std = Decimal(str(np.std(self.Loss_Record))).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) + Accuracy_Std = Decimal(str(np.std(self.Accuracy_Record))).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) + Precision_Std = Decimal(str(np.std(self.Precision_Record))).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) + Recall_Std = Decimal(str(np.std(self.Recall_Record))).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) + F1_Std = Decimal(str(np.std(self.F1_Record))).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) + AUC_Std = Decimal(str(np.std(self.AUC_Record))).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) + + Std_DataFram = pd.DataFrame( + { + "loss" : "{:.2f}".format(Loss_Std), + "precision" : "{:.2f}".format(Precision_Std), + "recall" : "{:.2f}".format(Recall_Std), + "accuracy" : "{:.2f}".format(Accuracy_Std), + "f" : "{:.2f}".format(F1_Std), + "AUC" : "{:.2f}".format(AUC_Std) + }, index = [0] + ) + self.History.append(Std_DataFram) + return Std_DataFram + + def Output_Style(self): + Result = pd.DataFrame( + { + "loss" : "{}±{}".format(self.History[0]["loss"][0], self.History[1]["loss"][0]), + "precision" : "{}±{}".format(self.History[0]["precision"][0], self.History[1]["precision"][0]), + "recall" : "{}±{}".format(self.History[0]["recall"][0], self.History[1]["recall"][0]), + "accuracy" : "{}±{}".format(self.History[0]["accuracy"][0], self.History[1]["accuracy"][0]), + "f" : "{}±{}".format(self.History[0]["f"][0], self.History[1]["f"][0]), + "AUC" : "{}±{}".format(self.History[0]["AUC"][0], self.History[1]["AUC"][0]) + }, index = [0] + ) + return Result \ No newline at end of file diff --git a/Calculate_Process/__init__.py b/Calculate_Process/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Calculate_Process/__pycache__/Calculate.cpython-310.pyc b/Calculate_Process/__pycache__/Calculate.cpython-310.pyc new file mode 100644 index 0000000..d80438e Binary files /dev/null and b/Calculate_Process/__pycache__/Calculate.cpython-310.pyc differ diff --git a/Calculate_Process/__pycache__/__init__.cpython-310.pyc b/Calculate_Process/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..655d557 Binary files /dev/null and b/Calculate_Process/__pycache__/__init__.cpython-310.pyc differ diff --git a/Image_Process/Image_Generator.py b/Image_Process/Image_Generator.py new file mode 100644 index 0000000..1622232 --- /dev/null +++ b/Image_Process/Image_Generator.py @@ -0,0 +1,201 @@ +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +from _validation.ValidationTheEnterData import validation_the_enter_data +from Load_process.file_processing import Process_File +from keras.preprocessing.image import ImageDataGenerator +from Load_process.LoadData import Load_Data_Prepare + +class Image_generator(): + '''製作資料強化''' + def __init__(self, Generator_Root, Labels) -> None: + self._validation = validation_the_enter_data() + self.stop = 0 + self.Labels = Labels + self.Generator_Root = Generator_Root + pass + + def Processing_Main(self, Training_Dict_Data_Root): + data_size = 0 + + # 製作標準資料增強 + ''' + 這裡我想要做的是依照paper上的資料強化IMAGE DATA COLLECTION AND IMPLEMENTATION OF DEEP LEARNING-BASED MODEL IN DETECTING MONKEYPOX DISEASE USING MODIFIED VGG16 + 產生出資料強化後的影像 + ''' + print("\nAugmentation one monkeypox image") + data_size = self.get_processing_Augmentation(Training_Dict_Data_Root, 1, data_size) + self.stop += data_size + + # 製作標準資料增強 + ''' + 這裡我想要做的是依照paper上的資料強化IMAGE DATA COLLECTION AND IMPLEMENTATION OF DEEP LEARNING-BASED MODEL IN DETECTING MONKEYPOX DISEASE USING MODIFIED VGG16 + 產生出資料強化後的影像 + ''' + print("\nAugmentation two monkeypox image") + data_size = self.get_processing_Augmentation(Training_Dict_Data_Root, 2, data_size) + self.stop += data_size + + # 製作標準資料增強 + ''' + 這裡我想要做的是依照paper上的資料強化IMAGE DATA COLLECTION AND IMPLEMENTATION OF DEEP LEARNING-BASED MODEL IN DETECTING MONKEYPOX DISEASE USING MODIFIED VGG16 + 產生出資料強化後的影像 + ''' + print("\nAugmentation three monkeypox image") + data_size = self.get_processing_Augmentation(Training_Dict_Data_Root, 3, data_size) + self.stop += data_size + + + # 製作標準資料增強 + ''' + 這裡我想要做的是依照paper上的資料強化IMAGE DATA COLLECTION AND IMPLEMENTATION OF DEEP LEARNING-BASED MODEL IN DETECTING MONKEYPOX DISEASE USING MODIFIED VGG16 + 產生出資料強化後的影像 + ''' + print("\nAugmentation four monkeypox image") + data_size = self.get_processing_Augmentation(Training_Dict_Data_Root, 4, data_size) + + print() + + def get_processing_Augmentation(self, original_image_root : dict, Augment_choose, data_size): + Prepaer = Load_Data_Prepare() + + self.get_data_roots = original_image_root # 要處理的影像路徑 + Prepaer.Set_Label_List(self.Labels) + data_size = self.Generator_main(self.Generator_Root, Augment_choose, data_size) # 執行 + return data_size + + def Generator_main(self, save_roots, stardand, data_size): + ''' + Parameter: + labels = 取得資料的標籤 + save_root = 要儲存資料的地方 + strardand = 要使用哪種Image Augmentation + ''' + File = Process_File() + + for label in self.Labels: # 分別對所有類別進行資料強化 + image = self.load_data(label) # 取的資料 + save_root = File.Make_Save_Root(label, save_roots) # 合併路徑 + + if File.JudgeRoot_MakeDir(save_root): # 判斷要存的資料夾存不存在,不存在則創立 + print("The file is exist") + + train_Generator = self.Generator_Content(stardand) # 取的要做怎樣的資料強化 + stop_counter = 0 + for batches in train_Generator.flow(image, batch_size = 16): # 執行資料強化 + ''' + 程式碼中的 batch_size 參數被設置為 12, 這表示每次從訓練資料集中產生 12 個影像資料,作為一個 batch。當程式碼迭代 train_Generator 物件時,每次從訓練資料集中取出一個 batch 的影像,並逐一處理其中的每個影像。 + + 在迭代過程中, counter 變數用於計算存儲的 Numpy 陣列檔案的數量,而 i 變數用於計算迭代的次數。當 i 的值是 417 的倍數時, if i % 417 == 0: 條件就會成立,進而執行 break 語句,退出外層迴圈。因此,最多只會從訓 + 練資料集中產生 417 個 batch 的影像資料。如果資料集中的影像總數不能被 12 整除,最後一個 batch 的影像數量會少於 12。因此, 最終產生的 Numpy 陣列檔案數量可能小於 image 資料集的影像總數除以 12。 + + 總之,根據程式碼的設計,最多只會從訓練資料集中產生 417 個 batch 的影像資料,並將它們存儲為 Numpy 陣列檔案。在最後一個 batch 中的影像數量可能少於 12。 + + * train_Generator: 是一個ImageDataGenerator物件, 它從訓練資料中產生影像資料,這些影像資料可以用於訓練神經網路模型。 + * flow(): 方法是ImageDataGenerator物件的一個方法, 它可以從資料集中產生一個batch的影像資料。image 是要傳遞給ImageDataGenerator的影像資料, batch_size 是一個batch中包含的影像數量。 + * for batch in train_Generator.flow(image, batch_size = 12): 語句會迭代ImageDataGenerator物件產生的影像batch, 這些影像batch會逐一傳遞給batch 變數。 + * for batches in batch: 語句會迭代batch中的每個影像資料, 這些影像資料會逐一傳遞給batches 變數。 + * self.save_dir("image_" + label + str(counter) + ".npy", batches): 語句會以Numpy陣列的形式將每個影像資料存儲為一個Numpy陣列檔案, 檔案名稱會包含影像標籤和計數器。 + * counter += 1: 語句會將計數器增加1, 以便標識存儲的Numpy陣列檔案。 + * i += 1: 語句會增加迭代器的值, 以便在每417個影像batch之後退出迴圈。 + * if i % 417 == 0: break 語句會檢查迭代器是否達到了417的倍數, 如果是, 就會退出外層的迴圈, 以便結束影像資料的存儲。 + ''' + for batch in batches: # 分別抓出每一張照片來儲存 + File.Save_CV2_File("image_" + label + str(data_size) + ".png", save_root, batch) # 存檔 + data_size += 1 + stop_counter += 1 + + if stop_counter >= self.stop: # 若做指定次數則停止 + break + print(str(label) + "有" + str(stop_counter) + "筆資料") + + return data_size + + def load_data(self, label): + '''Images is readed by myself''' + image_processing = Read_image_and_Process_image() + img = image_processing.Data_Augmentation_Image(self.get_data_roots[label]) + + self.stop = len(img) * 1.5 + return img + + def Generator_Content(self, judge): # 影像資料增強 + ''' + ImageGenerator的參數: + featurewise_center : 布爾值。將輸入數據的均值設置為0,逐特徵進行。 + samplewise_center : 布爾值。將每個樣本的均值設置為0。 + featurewise_std_normalization : Boolean. 布爾值。將輸入除以數據標準差,逐特徵進行。 + samplewise_std_normalization : 布爾值。將每個輸入除以其標準差。 + zca_epsilon : ZCA 白化的epsilon 值,默認為1e-6。 + zca_whitening : 布爾值。是否應用ZCA 白化。 + rotation_range : 整數。隨機旋轉的度數範圍。 + width_shift_range : 浮點數、一維數組或整數 + float: 如果<1,則是除以總寬度的值,或者如果>=1,則為像素值。 + 1-D 數組: 數組中的隨機元素。 + int: 來自間隔 (-width_shift_range, +width_shift_range) 之間的整數個像素。 + width_shift_range=2時,可能值是整數[-1, 0, +1],與 width_shift_range=[-1, 0, +1] 相同;而 width_shift_range=1.0 時,可能值是 [-1.0, +1.0) 之間的浮點數。 + height_shift_range : 浮點數、一維數組或整數 + float: 如果<1,則是除以總寬度的值,或者如果>=1,則為像素值。 + 1-D array-like: 數組中的隨機元素。 + int: 來自間隔 (-height_shift_range, +height_shift_range) 之間的整數個像素。 + height_shift_range=2時,可能值是整數[-1, 0, +1],與 height_shift_range=[-1, 0, +1] 相同;而 height_shift_range=1.0 時,可能值是 [-1.0, +1.0) 之間的浮點數。 + shear_range : 浮點數。剪切強度(以弧度逆時針方向剪切角度)。 + zoom_range : 浮點數或[lower, upper]。隨機縮放範圍。如果是浮點數,[lower, upper] = [1-zoom_range, 1+zoom_range]。 + channel_shift_range : 浮點數。隨機通道轉換的範圍。 + fill_mode : {"constant", "nearest", "reflect" or "wrap"} 之一。默認為'nearest'。輸入邊界以外的點根據給定的模式填充: + 'constant': kkkkkkkk|abcd|kkkkkkkk (cval=k) + 'nearest': aaaaaaaa|abcd|dddddddd + 'reflect': abcddcba|abcd|dcbaabcd + 'wrap': abcdabcd|abcd|abcdabcd + cval : 浮點數或整數。用於邊界之外的點的值,當 fill_mode = "constant" 時。 + horizontal_flip : 布爾值。隨機水平翻轉。 + vertical_flip : 布爾值。隨機垂直翻轉。 + rescale : 重縮放因子。默認為None。如果是None 或0,不進行縮放,否則將數據乘以所提供的值(在應用任何其他轉換之前)。 + preprocessing_function : 應用於每個輸入的函數。這個函數會在任何其他改變之前運行。這個函數需要一個參數:一張圖像(秩為3 的Numpy 張量),並且應該輸出一個同尺寸的Numpy 張量。 + data_format : 圖像數據格式,{"channels_first", "channels_last"} 之一。"channels_last" 模式表示圖像輸入尺寸應該為(samples, height, width, channels),"channels_first" 模式表示輸入尺寸應該為(samples, channels, height, width)。默認為在Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值。如果你從未設置它,那它就是"channels_last"。 + validation_split : 浮點數。Float. 保留用於驗證的圖像的比例(嚴格在0和1之間)。 + dtype : 生成數組使用的數據類型。 + ''' + if judge == 1: + datagen = ImageDataGenerator( + rotation_range=30, # 旋轉影像 + width_shift_range=0.1, # 圖像隨機水平移動,位移距離為圖像長度乘以參數(0.1) + height_shift_range=0.1, # 圖像隨機垂直移動,位移距離為圖像長度乘以參數(0.1) + zoom_range=0.2, # 隨機縮放範圍,[lower, upper] = [1-zoom_range, 1+zoom_range] + horizontal_flip=False, # 水平翻轉 + vertical_flip=False, # 垂直翻轉 + fill_mode='nearest' # 在旋轉或平移造成空隙時,則空隙補常數 + ) + if judge == 2: + datagen = ImageDataGenerator( + rotation_range=180, + width_shift_range=0.2, + height_shift_range=0.1, + zoom_range=0.1, + horizontal_flip=True, + vertical_flip=True, + fill_mode='nearest' + ) + if judge == 3: + datagen = ImageDataGenerator( + rotation_range=45, # 旋轉影像 + width_shift_range=0.02, # 圖像隨機水平移動,位移距離為圖像長度乘以參數(0.1) + height_shift_range=0.02, # 圖像隨機垂直移動,位移距離為圖像長度乘以參數(0.1) + shear_range = 0.02, + zoom_range=0.02, # 隨機縮放範圍,[lower, upper] = [1-zoom_range, 1+zoom_range] + horizontal_flip = True, + fill_mode = "reflect" + ) + + if judge == 4: # 第二份paper的資料強化 + datagen = ImageDataGenerator( + rotation_range=50, # 旋轉影像 + width_shift_range=0.2, # 圖像隨機水平移動,位移距離為圖像長度乘以參數(0.1) + height_shift_range=0.2, # 圖像隨機垂直移動,位移距離為圖像長度乘以參數(0.1) + shear_range = 0.25, + zoom_range=0.1, # 隨機縮放範圍,[lower, upper] = [1-zoom_range, 1+zoom_range] + channel_shift_range = 20 # 隨機通道轉換的範圍 + ) + + if judge == 5: # 第一份paper的資料強化 + datagen = ImageDataGenerator(rescale = 1 / 255) + + return datagen \ No newline at end of file diff --git a/Image_Process/__pycache__/Image_Generator.cpython-310.pyc b/Image_Process/__pycache__/Image_Generator.cpython-310.pyc new file mode 100644 index 0000000..65bf14f Binary files /dev/null and b/Image_Process/__pycache__/Image_Generator.cpython-310.pyc differ diff --git a/Image_Process/__pycache__/Image_Generator.cpython-39.pyc b/Image_Process/__pycache__/Image_Generator.cpython-39.pyc new file mode 100644 index 0000000..f79f6e0 Binary files /dev/null and b/Image_Process/__pycache__/Image_Generator.cpython-39.pyc differ diff --git a/Image_Process/__pycache__/LoadData.cpython-310.pyc b/Image_Process/__pycache__/LoadData.cpython-310.pyc new file mode 100644 index 0000000..b26d190 Binary files /dev/null and b/Image_Process/__pycache__/LoadData.cpython-310.pyc differ diff --git a/Image_Process/__pycache__/LoadData.cpython-311.pyc b/Image_Process/__pycache__/LoadData.cpython-311.pyc new file mode 100644 index 0000000..177a3ee Binary files /dev/null and b/Image_Process/__pycache__/LoadData.cpython-311.pyc differ diff --git a/Image_Process/__pycache__/LoadData.cpython-39.pyc b/Image_Process/__pycache__/LoadData.cpython-39.pyc new file mode 100644 index 0000000..df1ec75 Binary files /dev/null and b/Image_Process/__pycache__/LoadData.cpython-39.pyc differ diff --git a/Image_Process/__pycache__/image_enhancement.cpython-310.pyc b/Image_Process/__pycache__/image_enhancement.cpython-310.pyc new file mode 100644 index 0000000..8a72a00 Binary files /dev/null and b/Image_Process/__pycache__/image_enhancement.cpython-310.pyc differ diff --git a/Image_Process/__pycache__/image_enhancement.cpython-39.pyc b/Image_Process/__pycache__/image_enhancement.cpython-39.pyc new file mode 100644 index 0000000..3e71607 Binary files /dev/null and b/Image_Process/__pycache__/image_enhancement.cpython-39.pyc differ diff --git a/Image_Process/__pycache__/load_and_ImageGenerator.cpython-310.pyc b/Image_Process/__pycache__/load_and_ImageGenerator.cpython-310.pyc new file mode 100644 index 0000000..3197bf1 Binary files /dev/null and b/Image_Process/__pycache__/load_and_ImageGenerator.cpython-310.pyc differ diff --git a/Image_Process/__pycache__/load_and_ImageGenerator.cpython-311.pyc b/Image_Process/__pycache__/load_and_ImageGenerator.cpython-311.pyc new file mode 100644 index 0000000..9fa399d Binary files /dev/null and b/Image_Process/__pycache__/load_and_ImageGenerator.cpython-311.pyc differ diff --git a/Image_Process/__pycache__/load_and_ImageGenerator.cpython-39.pyc b/Image_Process/__pycache__/load_and_ImageGenerator.cpython-39.pyc new file mode 100644 index 0000000..3155ea7 Binary files /dev/null and b/Image_Process/__pycache__/load_and_ImageGenerator.cpython-39.pyc differ diff --git a/Image_Process/__pycache__/load_paper_data.cpython-39.pyc b/Image_Process/__pycache__/load_paper_data.cpython-39.pyc new file mode 100644 index 0000000..0cfaf1e Binary files /dev/null and b/Image_Process/__pycache__/load_paper_data.cpython-39.pyc differ diff --git a/Image_Process/__pycache__/make_ImageGenerator.cpython-310.pyc b/Image_Process/__pycache__/make_ImageGenerator.cpython-310.pyc new file mode 100644 index 0000000..78e0f15 Binary files /dev/null and b/Image_Process/__pycache__/make_ImageGenerator.cpython-310.pyc differ diff --git a/Image_Process/__pycache__/make_ImageGenerator.cpython-311.pyc b/Image_Process/__pycache__/make_ImageGenerator.cpython-311.pyc new file mode 100644 index 0000000..c5af7e8 Binary files /dev/null and b/Image_Process/__pycache__/make_ImageGenerator.cpython-311.pyc differ diff --git a/Image_Process/__pycache__/make_ImageGenerator.cpython-39.pyc b/Image_Process/__pycache__/make_ImageGenerator.cpython-39.pyc new file mode 100644 index 0000000..da6f48b Binary files /dev/null and b/Image_Process/__pycache__/make_ImageGenerator.cpython-39.pyc differ diff --git a/Image_Process/image_enhancement.py b/Image_Process/image_enhancement.py new file mode 100644 index 0000000..ce3cc4e --- /dev/null +++ b/Image_Process/image_enhancement.py @@ -0,0 +1,87 @@ +import cv2 +import numpy as np + +def shapen(image): # 銳化處理 + sigma = 100 + blur_img = cv2.GaussianBlur(image, (0, 0), sigma) + usm = cv2.addWeighted(image, 1.5, blur_img, -0.5, 0) + + return usm + +def increase_contrast(image): # 增加資料對比度 + output = image # 建立 output 變數 + alpha = 2 + beta = 10 + cv2.convertScaleAbs(image, output, alpha, beta) # 套用 convertScaleAbs + + return output + +def adaptive_histogram_equalization(image): + ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) + channels = cv2.split(ycrcb) + clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) + clahe.apply(channels[0], channels[0]) + + ycrcb = cv2.merge(channels) + Change_image = cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR) + + return Change_image + +def Remove_Background(image, Matrix_Size): + skinCrCbHist = np.zeros((256,256), dtype= np.uint8) + cv2.ellipse(skinCrCbHist, (113,155),(23,25), 43, 0, 360, (255, 255, 255), -1) #繪製橢圓弧線 + + img_ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) + y,cr,cb = cv2.split(img_ycrcb) #拆分出Y,Cr,Cb值 + + skin = np.zeros(cr.shape, dtype = np.uint8) #掩膜 + (x,y) = cr.shape + + # 依序取出圖片中每個像素 + for i in range(x): + for j in range(y): + if skinCrCbHist [cr[i][j], cb[i][j]] > 0: #若不在橢圓區間中 + skin[i][j] = 255 + # 如果該像素的灰階度大於 200,調整該像素的透明度 + # 使用 255 - gray[y, x] 可以將一些邊緣的像素變成半透明,避免太過鋸齒的邊緣 + # img_change = cv2.cvtColor(img_change, cv2.COLOR_BGRA2BGR) + img = cv2.bitwise_and(image, image, mask = skin) + img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + h = image.shape[0] # 取得圖片高度 + w = image.shape[1] # 取得圖片寬度 + + for x in range(w): + for y in range(h): + if img_gray[y, x] == 0: + # if x == 0 and y == 0: # 當X Y都在左上角時 + # image[y, x] = Add(1, Matrix_Size, image[y, x]) / Matrix_Size + # if x == w - 1 and y == 0: # 當X Y都在右上角時 + # image[y, x] = Add(w - Matrix_Size, w, image[y, x]) / Matrix_Size + # if x == 0 and y == h - 1: # 當X Y都在左下角時 + # image[y, x] = (image[y - 1, x] + image[y - 1, x + 1] + image[y, x + 1]) / 3 + # if x == w - 1 and y == h - 1: # 當X Y都在右下角時 + # image[y, x] = (image[y, x - 1] + image[y - 1, x - 1] + image[y - 1, x]) / 3 + + # if (x > 0 and x < w - 1) and y == 0: # 當上面的X Y從左到右 + # image[y, x] = (image[y, x - 1] + image[y + 1, x - 1] + image[y + 1, x] + image[y, x + 1] + image[y + 1, x + 1]) / 5 + # if (x > 0 and x < w - 1) and y == h - 1: # 當下面的X Y從左到右 + # image[y, x] = (image[y, x - 1] + image[y - 1, x - 1] + image[y - 1, x] + image[y, x + 1] + image[y - 1, x + 1]) / 5 + # if x == 0 and (y > 0 and y < h - 1): # 當左邊的X Y從上到下 + # image[y, x] = (image[y - 1, x] + image[y - 1, x + 1] + image[y, x + 1] + image[y + 1, x + 1] + image[y + 1, x]) / 5 + # if x == w - 1 and (y > 0 and y < h - 1): # 當右邊X Y從上到下 + # image[y, x] = (image[y - 1, x] + image[y - 1, x - 1] + image[y, x - 1] + image[y + 1, x - 1] + image[y + 1, x]) / 5 + + if (x >= 1 and x < w - 1) and (y >= 1 and y < h - 1): # 當y >= 2 且 X >= 2 + image[y, x] = Add(x, y, image, Matrix_Size) / Matrix_Size + # BGRA_image[y, x, 3] = 255 - gray[y, x] + return image + + +def Add(width_Center, Height_Center, image, Mask_Size): + total = 0 + for i in range(Mask_Size): + for j in range(Mask_Size): + total += image[width_Center - ((Mask_Size - 1) / 2) + j, Height_Center - ((Mask_Size - 1) / 2) + i] + + return total \ No newline at end of file diff --git a/Image_Process/load_and_ImageGenerator.py b/Image_Process/load_and_ImageGenerator.py new file mode 100644 index 0000000..38c98f2 --- /dev/null +++ b/Image_Process/load_and_ImageGenerator.py @@ -0,0 +1,62 @@ +from Load_process.LoadData import Loding_Data_Root +from Image_Process.Image_Generator import Image_generator +from Load_process.file_processing import Process_File +from model_data_processing.processing_for_cut_image import Cut_Indepentend_Data +from Load_process.Loading_Tools import Load_Data_Prepare, Load_Data_Tools + +class Load_ImageGenerator(): + ''' + 這是一個拿來進行資料強化的物件,最主要結合了學姊給的資料強化與我自行設定的資料強化。 +藉由此物件先將資料讀取出來,並將資料分別進行資料強化,利用資料強化來迷部資料的不平衡 +這只是其中一個實驗 + +Parmeter + standard_root: 做跟學姊給的資料強化同一種的資料強化 + myself_root: 資料強化的內容參數是我自己設定的 + IndependentDataRoot: 要存回去的資料夾路徑 + Herpeslabels: 皰疹的類別 + MonKeyPoxlabels: 猴痘的類別(猴痘、水痘、正常) + herpes_data: 合併herpes Dataset的資料成一個List + MonkeyPox_data: 合併MonkeyPox DataSet 的資料成一個List + ''' + def __init__(self, Training_Root,Test_Root, Validation_Root, Generator_Root, Labels) -> None: + self.Training_Root = Training_Root + self.TestRoot = Test_Root + self.ValidationRoot = Validation_Root + self.GeneratoRoot = Generator_Root + self.Labels = Labels + pass + + def process_main(self, Data_Length : int): + File = Process_File() + Prepare = Load_Data_Prepare() + load = Loding_Data_Root(self.Labels, self.Training_Root, self.GeneratoRoot) + Indepentend = Cut_Indepentend_Data(self.Training_Root, self.Labels) + Load_Tool = Load_Data_Tools() + Generator = Image_generator(self.GeneratoRoot, self.Labels) + + # 將測試資料獨立出來 + test_size = 0.1 + Indepentend.IndependentData_main(self.TestRoot, test_size) + + # 將驗證資料獨立出來 + test_size = 0.1 + Indepentend.IndependentData_main(self.ValidationRoot, test_size) + + if not File.Judge_File_Exist(self.GeneratoRoot): # 檔案若不存在 + # 確定我要多少個List + Prepare.Set_Data_Content([], Data_Length) + + # 製作讀檔字典並回傳檔案路徑 + Prepare.Set_Label_List(self.Labels) + Prepare.Set_Data_Dictionary(Prepare.Get_Label_List(), Prepare.Get_Data_Content(), Data_Length) + Original_Dict_Data_Root = Prepare.Get_Data_Dict() + get_all_original_image_data = Load_Tool.get_data_root(self.Training_Root, Original_Dict_Data_Root, Prepare.Get_Label_List()) + + # 儲存資料強化後資料 + Generator.Processing_Main(get_all_original_image_data) # 執行資料強化 + else: # 若檔案存在 + print("standard data and myself data are exist\n") + + # 執行讀檔 + return load.process_main() \ No newline at end of file diff --git a/Load_process/LoadData.py b/Load_process/LoadData.py new file mode 100644 index 0000000..a3d50d9 --- /dev/null +++ b/Load_process/LoadData.py @@ -0,0 +1,38 @@ +from Load_process.file_processing import Process_File +from Load_process.Loading_Tools import Load_Data_Prepare, Load_Data_Tools +from merge_class.merge import merge + +class Loding_Data_Root(Process_File): + def __init__(self, Labels, Training_Root, Generator_Root): + self.Label_List = Labels + self.Train_Root = Training_Root + self.Generator_Root = Generator_Root + + super().__init__() + pass + + def process_main(self): + '''處理讀Training、Image Generator檔資料''' + Merge = merge() + + get_Image_Data = self.get_Image_data_roots(self.Train_Root) + Get_ImageGenerator_Image_Data = self.get_Image_data_roots(self.Generator_Root) + + Get_Total_Image_Data_Root = Merge.merge_dict_to_dict(get_Image_Data, Get_ImageGenerator_Image_Data) + + return Get_Total_Image_Data_Root + + def get_Image_data_roots(self, DataRoot) -> dict: + Prepare = Load_Data_Prepare() + Loading_Tool = Load_Data_Tools() + + # Setting the dictionary's content on Prepare.Set_Data_Dictionary object + Prepare.Set_Label_List(self.Label_List) + Prepare.Set_Data_Content([], len(self.Label_List)) + Prepare.Set_Data_Dictionary(Prepare.Get_Label_List(), Prepare.Get_Data_Content(), len(self.Label_List)) + + # Gets the classifcation's total data + get_image_data = Loading_Tool.get_data_root(DataRoot, Prepare.Get_Data_Dict(), Prepare.Get_Label_List()) + + # return get_NPC_original_image_data + return get_image_data \ No newline at end of file diff --git a/Load_process/Load_Indepentend.py b/Load_process/Load_Indepentend.py new file mode 100644 index 0000000..32029d8 --- /dev/null +++ b/Load_process/Load_Indepentend.py @@ -0,0 +1,78 @@ +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +from model_data_processing.processing import shuffle_data +from merge_class.merge import merge +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +from Load_process.LoadData import Load_Data_Prepare, Load_Data_Tools + +class Load_Indepentend_Data(): + def __init__(self, Labels, OneHot_Encording): + ''' + 影像切割物件 + label有2類,會將其轉成one-hot-encoding的形式 + [0, 1] = NPC_negative + [1, 0] = NPC_positive + ''' + self.merge = merge() + self.Labels = Labels + self.OneHot_Encording = OneHot_Encording + pass + + def process_main(self, Test_data_root, Validation_data_root): + 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") + + def get_Independent_image(self, independent_DataRoot): + image_processing = Read_image_and_Process_image() + + classify_image = [] + Total_Dict_Data_Root = self.Get_Independent_data_Root(independent_DataRoot) # 讀取測試資料集的資料 + Total_Dict_Data_Root = self.Specified_Amount_Of_Data(Total_Dict_Data_Root) # 打亂並取出指定資料筆數的資料 + Total_List_Data_Root = [Total_Dict_Data_Root[self.Labels[0]], Total_Dict_Data_Root[self.Labels[1]]] + + test_label, Classify_Label = [], [] + i = 0 # 計算classify_image的counter,且計算總共有幾筆資料 + for test_title in Total_List_Data_Root: # 藉由讀取所有路徑來進行讀檔 + test_label = image_processing.make_label_list(len(test_title), self.OneHot_Encording[i]) # 製作對應圖片數量的label出來+ + print(self.Labels[i] + " 有 " + str(len(test_label)) + " 筆資料 ") + + classify_image.append(test_title) + Classify_Label.append(test_label) + i += 1 + + original_test_root = self.merge.merge_data_main(classify_image, 0, 2) + original_test_label = self.merge.merge_data_main(Classify_Label, 0, 2) + + test = [] + test = image_processing.Data_Augmentation_Image(original_test_root) + test, test_label = image_processing.image_data_processing(test, original_test_label) + test = image_processing.normalization(test) + + return test, test_label + + + def Get_Independent_data_Root(self, load_data_root): + Prepare = Load_Data_Prepare() + Load_Tool = Load_Data_Tools() + + Prepare.Set_Data_Content([], len(self.Labels)) + Prepare.Set_Data_Dictionary(self.Labels, Prepare.Get_Data_Content(), 2) + Get_Data_Dict_Content = Prepare.Get_Data_Dict() + Total_Data_Roots = Load_Tool.get_data_root(load_data_root, Get_Data_Dict_Content, self.Labels) + + return Total_Data_Roots + + def Specified_Amount_Of_Data(self, Data): # 打亂資料後重新處理 + Data = shuffle_data(Data, self.Labels, 2) + tmp = [] + if len(Data[self.Labels[0]]) >= len(Data[self.Labels[1]]): + for i in range(len(Data[self.Labels[1]])): + tmp.append(Data[self.Labels[0]][i]) + Data[self.Labels[0]] = tmp + else: + for i in range(len(Data[self.Labels[0]])): + tmp.append(Data[self.Labels[1]][i]) + Data[self.Labels[1]] = tmp + return Data \ No newline at end of file diff --git a/Load_process/Loading_Tools.py b/Load_process/Loading_Tools.py new file mode 100644 index 0000000..c52db80 --- /dev/null +++ b/Load_process/Loading_Tools.py @@ -0,0 +1,90 @@ +import os +import glob + +class Load_Data_Prepare: + def __init__(self) -> None: + self.__Label_List = [] + self.__Data_List = [] + self.__Contect_Dictionary = {} + self.__Final_Dict_data = {} + self.__PreSave_Data_Root = [] # 所有要讀取資料所在的位置 + self.__Data_Content = [] + pass + + def Set_Data_Content(self, Content, Length): + tmp = [] + for i in range(Length): + tmp.append(Content) + + self.__Data_Content = tmp + + def Set_Label_List(self, Label_List): # 為讀取檔案準備label list + self.__Label_List = Label_List + pass + + def Set_Data_List(self, Data_List): + self.__Data_List = Data_List + pass + + def Set_Data_Dictionary(self, Label : list, Content : list, Total_Label_Size : int): + '''將資料合併成1個Dict''' + for i in range(Total_Label_Size): + temp = {Label[i] : Content[i]} + self.__Contect_Dictionary.update(temp) + pass + + def Set_Final_Dict_Data(self, Name : list, Label_Root : list, Label_LabelEncoding : list, Label_Len : int): + ''' + Name : 讀取出來的Data Root的名字 + Label_Root: 所有影像資料的路徑 + Label_LabelEncoding: LabelEncoding後的資料 + Label_Len: Label的大小 + ''' + for i in range(Label_Len): + temp = {Name[i] + "_Data_Root" : Label_Root[Name[i]]} + self.__Final_Dict_data.update(temp) + + for i in range(Label_Len): + temp = {Name[i] + "_Data_LabelEncoding" : Label_LabelEncoding[i]} + self.__Final_Dict_data.update(temp) + + def Set_PreSave_Data_Root(self, PreSave_Roots : list): + for Root in PreSave_Roots: + self.__PreSave_Data_Root.append(Root) + + def Get_Label_List(self): + ''' + 將private的資料讀取出來 + 現在要放入需要的Label 需要先Set Label + ''' + return self.__Label_List + + def Get_Data_List(self): + return self.__Data_List + + def Get_Data_Dict(self): + return self.__Contect_Dictionary + + def Get_Final_Data_Dict(self): + return self.__Final_Dict_data + + def Get_PreSave_Data_Root(self): + return self.__PreSave_Data_Root + + def Get_Data_Content(self): + return self.__Data_Content + +class Load_Data_Tools(): + def __init__(self) -> None: + pass + + def get_data_root(self, root, data_dict, classify_label, judge = True) -> dict : + '''取得資料路徑''' + for label in classify_label: + if judge: + path = os.path.join(root, label, "*") + else: + path = os.path.join(root, "*") + path = glob.glob(path) + data_dict[label] = path + return data_dict \ No newline at end of file diff --git a/Load_process/__pycache__/LoadData.cpython-310.pyc b/Load_process/__pycache__/LoadData.cpython-310.pyc new file mode 100644 index 0000000..bf860ef Binary files /dev/null and b/Load_process/__pycache__/LoadData.cpython-310.pyc differ diff --git a/Load_process/__pycache__/LoadData.cpython-39.pyc b/Load_process/__pycache__/LoadData.cpython-39.pyc new file mode 100644 index 0000000..8cece7f Binary files /dev/null and b/Load_process/__pycache__/LoadData.cpython-39.pyc differ diff --git a/Load_process/__pycache__/Load_Indepentend.cpython-310.pyc b/Load_process/__pycache__/Load_Indepentend.cpython-310.pyc new file mode 100644 index 0000000..0cd0a7a Binary files /dev/null and b/Load_process/__pycache__/Load_Indepentend.cpython-310.pyc differ diff --git a/Load_process/__pycache__/Load_Indepentend_Data.cpython-310.pyc b/Load_process/__pycache__/Load_Indepentend_Data.cpython-310.pyc new file mode 100644 index 0000000..81748f3 Binary files /dev/null and b/Load_process/__pycache__/Load_Indepentend_Data.cpython-310.pyc differ diff --git a/Load_process/__pycache__/Loading_Tools.cpython-310.pyc b/Load_process/__pycache__/Loading_Tools.cpython-310.pyc new file mode 100644 index 0000000..232b6bf Binary files /dev/null and b/Load_process/__pycache__/Loading_Tools.cpython-310.pyc differ diff --git a/Load_process/__pycache__/file_processing.cpython-310.pyc b/Load_process/__pycache__/file_processing.cpython-310.pyc new file mode 100644 index 0000000..f950070 Binary files /dev/null and b/Load_process/__pycache__/file_processing.cpython-310.pyc differ diff --git a/Load_process/__pycache__/file_processing.cpython-311.pyc b/Load_process/__pycache__/file_processing.cpython-311.pyc new file mode 100644 index 0000000..7871ace Binary files /dev/null and b/Load_process/__pycache__/file_processing.cpython-311.pyc differ diff --git a/Load_process/__pycache__/file_processing.cpython-39.pyc b/Load_process/__pycache__/file_processing.cpython-39.pyc new file mode 100644 index 0000000..6dd3b90 Binary files /dev/null and b/Load_process/__pycache__/file_processing.cpython-39.pyc differ diff --git a/Load_process/file_processing.py b/Load_process/file_processing.py new file mode 100644 index 0000000..c6a44dd --- /dev/null +++ b/Load_process/file_processing.py @@ -0,0 +1,49 @@ +import os +import cv2 +import numpy as np +import datetime +import pandas as pd + +class Process_File(): + def __init__(self) -> None: + pass + def JudgeRoot_MakeDir(self, file_root): # 先判斷檔案是否存在,再決定是否要進行開檔 + if self.Judge_File_Exist(file_root): + return True + else: + self.Make_Dir(file_root) + return False + + def Judge_File_Exist(self, file_root): + '''判斷檔案是否存在,存在回傳true,否則為False''' + if os.path.exists(file_root): + return True + else: + return False + + def Make_Dir(self, file_root): # 建立資料夾 + os.makedirs(file_root) + + def Make_Save_Root(self, FileName, File_root): # 合併路徑 + return os.path.join(File_root, FileName) + + def Save_CV2_File(self, FileName, save_root, image): # 存CSV檔 + save_root = self.Make_Save_Root(FileName, save_root) + cv2.imwrite(save_root, image) + + def Save_NPY_File(self, FileName, save_root, image): # 存.npy檔 + save_root = self.Make_Save_Root(FileName, save_root) + np.save(save_root, image) + + def Save_CSV_File(self, file_name, data): # 儲存訓練結果 + Save_Root = '../Result/save_the_train_result(' + str(datetime.date.today()) + ")" + self.JudgeRoot_MakeDir(Save_Root) + modelfiles = self.Make_Save_Root(file_name + ".csv", Save_Root) # 將檔案名稱及路徑字串合併成完整路徑 + data.to_csv(modelfiles, mode = "a") + + def Save_TXT_File(self, content, File_Name): + model_dir = '../Result/save_the_train_result(' + str(datetime.date.today()) + ")" # 儲存的檔案路徑,由save_the_train_result + 當天日期 + self.JudgeRoot_MakeDir(model_dir) + modelfiles = self.Make_Save_Root(File_Name + ".txt", model_dir) # 將檔案名稱及路徑字串合併成完整路徑 + with open(modelfiles, mode = 'a') as file: + file.write(content) \ No newline at end of file diff --git a/Processing_image.py b/Processing_image.py new file mode 100644 index 0000000..c1d826b --- /dev/null +++ b/Processing_image.py @@ -0,0 +1,32 @@ +from merge_class.merge import merge +from Load_process.Loading_Tools import Load_Data_Prepare +from Load_process.LoadData import Loding_Data_Root +from Training_Tools.Tools import Tool +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +from matplotlib import pyplot as plt + +if __name__ == "__main__": + Merge = merge() + read = Read_image_and_Process_image() + tool = Tool() + Prepare = Load_Data_Prepare() + + tool.Set_Labels() + tool.Set_Save_Roots() + Labels = tool.Get_Data_Label() + Trainig_Root, Testing_Root, Validation_Root = tool.Get_Save_Roots(2) + + load = Loding_Data_Root(Labels, Trainig_Root, "") + Data_Root = load.get_Image_data_roots(Trainig_Root) + + # 將資料做成Dict的資料型態 + Prepare.Set_Final_Dict_Data(Labels, Data_Root, [[], []], 2) + 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 + + Image = read.Data_Augmentation_Image(training_data) + plt.imshow(Image[0]) + plt.show() + diff --git a/README.md b/README.md new file mode 100644 index 0000000..24be781 --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +main.py: 主程式檔 + +## load_process +### 負責讀取影像檔案、分割獨立資料(測試、驗證)、讀取獨立資料、一般檔案的操作 +File_Process : 檔案操作的主程式,包含開檔、創立檔案、判斷檔案是否存在等都是他負責的範圍。是一般物件也是LoadData的父物件 +LoadData : 讀檔主程式,一切讀檔動作由他開始。繼承File_Process(子物件) +Cutting_Indepentend_Image : 讀取獨立資料(testing、Validation)的物件 + +## Image_Process +### 負責進行資料擴增、影像處理等的操作 +* Generator_Content : 負責建立基礎Generator項目,為Image_Generator的父類別 +* Image_Generator : 負責製造資料擴增的資料,並將資料存到檔案中。繼承Generator_Content(子物件) +* image_enhancement : 負責進行影像處理並將資料回傳 + +## Model_Tools +### 負責進行模型的基礎架構,包含Convolution、Dense、以及其他模型的配件 +* All_Model_Tools : 所有模型的附加工具,是所有的父類別 + + ## CNN + ### 包含所有CNN的工具與應用架構 + * CNN_Tools : 為卷積層的工具,包含一維、二維、三維捲積。CNN_Application的父類別,繼承All_Model_Tools(子類別) + * CNN_Application : 為Convolution的應用架構。繼承CNN_Tools(子類別) + + ## Dense + ### 包含所有Dense的應用 + * Dense_Application : 為全連階層工具,包含一般Dense layer與增加正則化之Dense layer。繼承All_Model_Tools() + + ## Model_Construction + ### 包含所有要進行實驗的模型架構 + * Model_Constructions : 所有模型的實驗架構 + +## Data_Merge +### 負責進行資料的合併 +* Merge : 負責合併Dict、List到List並匯出 + +## initalization +### 負責初始化特定物件 +* Img_initalization : 針對影像資料的初始化 +* Data_Initalization : 針對數據資料的初始化 + +## Validation_Program +### 負責驗證程式碼內的資料型態或輸入錯誤等問題 +* Validation : 驗證程式碼錯誤 + +## Draw +### 負責畫圖的工具 +* Draw_Tools : 畫出混淆矩陣、走勢圖的工具 +* Grad_CAM : 畫出模型可視化的熱力圖的工具 + +## Experiment +### 執行實驗的主程式 +* Experiment : 負責執行讀檔、設定模型Compile的細節、執行訓練、驗證結果等功能 diff --git a/Read_and_process_image/ReadAndProcess.py b/Read_and_process_image/ReadAndProcess.py new file mode 100644 index 0000000..6b34b61 --- /dev/null +++ b/Read_and_process_image/ReadAndProcess.py @@ -0,0 +1,75 @@ +import cv2 +import numpy as np + +class Read_image_and_Process_image: + def __init__(self) -> None: + pass + def get_data(self, path): + '''讀檔''' + img_size = 512 # 縮小後的影像 + try: + img_arr = cv2.imread(path, cv2.IMREAD_COLOR) # 讀檔(彩色) + # img_arr = cv2.imread(path, cv2.IMREAD_GRAYSCALE) # 讀檔(灰階) + resized_arr = cv2.resize(img_arr, (img_size, img_size)) # 濤整圖片大小 + except Exception as e: + print(e) + + return resized_arr + + def Data_Augmentation_Image(self, path): + resized_arr = [] + + for p in path: + img_size = 512 # 縮小後的影像 + try: + img_arr = cv2.imread(p, cv2.IMREAD_COLOR) # 讀檔(彩色) + # img_arr = cv2.imread(path, cv2.IMREAD_GRAYSCALE) # 讀檔(灰階) + resized_arr.append(cv2.resize(img_arr, (img_size, img_size))) # 濤整圖片大小 + except Exception as e: + print(e) + + return np.array(resized_arr) + + def image_data_processing(self, data, label): + '''讀檔後處理圖片''' + img_size = 512 + data = np.asarray(data).astype(np.float32) # 將圖list轉成np.array + data = data.reshape(-1, img_size, img_size, 3) # 更改陣列形狀 + label = np.array(label) # 將label從list型態轉成 numpy array + return data, label + + def normalization(self, images): + imgs = [] + for img in images: + img = np.asarray(img).astype(np.float32) # 將圖list轉成np.array + img = img / 255 # 標準化影像資料 + imgs.append(img) + + return np.array(imgs) + + # def load_numpy_data(self, file_names): + # '''載入numpy圖檔,並執行影像處理提高特徵擷取''' + # i = 0 + # numpy_image = [] + # original_image = [] + # for file_name in file_names: + # compare = str(file_name).split(".") + # if compare[-1] == "npy": + # image = np.load(file_name) # 讀圖片檔 + # numpy_image.append(image) # 合併成一個陣列 + # else: + # original_image.append(file_name) + + # original_image = self.get_data(original_image) + + # for file in original_image: + # numpy_image.append(file) + + # return numpy_image + + def make_label_list(self, length, content): + '''製作label的列表''' + label_list = [] + for i in range(length): + label_list.append(content) + return label_list \ No newline at end of file diff --git a/Read_and_process_image/__init__.py b/Read_and_process_image/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Read_and_process_image/__pycache__/ReadAndProcess.cpython-310.pyc b/Read_and_process_image/__pycache__/ReadAndProcess.cpython-310.pyc new file mode 100644 index 0000000..2969226 Binary files /dev/null and b/Read_and_process_image/__pycache__/ReadAndProcess.cpython-310.pyc differ diff --git a/Read_and_process_image/__pycache__/ReadAndProcess.cpython-311.pyc b/Read_and_process_image/__pycache__/ReadAndProcess.cpython-311.pyc new file mode 100644 index 0000000..5efc188 Binary files /dev/null and b/Read_and_process_image/__pycache__/ReadAndProcess.cpython-311.pyc differ diff --git a/Read_and_process_image/__pycache__/ReadAndProcess.cpython-39.pyc b/Read_and_process_image/__pycache__/ReadAndProcess.cpython-39.pyc new file mode 100644 index 0000000..083de5a Binary files /dev/null and b/Read_and_process_image/__pycache__/ReadAndProcess.cpython-39.pyc differ diff --git a/Read_and_process_image/__pycache__/__init__.cpython-310.pyc b/Read_and_process_image/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..47c799c Binary files /dev/null and b/Read_and_process_image/__pycache__/__init__.cpython-310.pyc differ diff --git a/Read_and_process_image/__pycache__/__init__.cpython-311.pyc b/Read_and_process_image/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..b14b642 Binary files /dev/null and b/Read_and_process_image/__pycache__/__init__.cpython-311.pyc differ diff --git a/Read_and_process_image/__pycache__/__init__.cpython-39.pyc b/Read_and_process_image/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..660ec1c Binary files /dev/null and b/Read_and_process_image/__pycache__/__init__.cpython-39.pyc differ diff --git a/SCP_Process/Scp_Process.py b/SCP_Process/Scp_Process.py new file mode 100644 index 0000000..1a38d6f --- /dev/null +++ b/SCP_Process/Scp_Process.py @@ -0,0 +1,29 @@ +import paramiko +from scp import SCPClient +import os +from Load_process.file_processing import Process_File + +class SCP(): + def __init__(self) -> None: + pass + def createSSHClient(self, server, port, user, password): + client = paramiko.SSHClient() + client.load_system_host_keys() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy) + client.connect(server, port, user, password) + + return client + + def Process_Main(self, Remote_Save_Root, Local_Save_Root, File_Name): + Process_File_Tool = Process_File() + + ssh = self.createSSHClient("10.1.29.28", 31931, "root", "whitekirin") + + Process_File_Tool.JudgeRoot_MakeDir(Local_Save_Root) + + with SCPClient(ssh.get_transport()) as scp: + scp.get(Remote_Save_Root, Local_Save_Root + "/" + File_Name) + + os.remove(Remote_Save_Root + "/" + File_Name, Local_Save_Root) + + print("傳輸成功\n") \ No newline at end of file diff --git a/SCP_Process/__pycache__/Scp_Process.cpython-310.pyc b/SCP_Process/__pycache__/Scp_Process.cpython-310.pyc new file mode 100644 index 0000000..c2c647f Binary files /dev/null and b/SCP_Process/__pycache__/Scp_Process.cpython-310.pyc differ diff --git a/To_load_Input_Data/__pycache__/read_input_data.cpython-39.pyc b/To_load_Input_Data/__pycache__/read_input_data.cpython-39.pyc new file mode 100644 index 0000000..569aeb9 Binary files /dev/null and b/To_load_Input_Data/__pycache__/read_input_data.cpython-39.pyc differ diff --git a/To_load_Input_Data/read_input_data.py b/To_load_Input_Data/read_input_data.py new file mode 100644 index 0000000..63f467a --- /dev/null +++ b/To_load_Input_Data/read_input_data.py @@ -0,0 +1,98 @@ +import tensorflow as tf +import os + +class read_Input_Data: + def __init__(self) -> None: + pass + def save_tfrecords(self, images, label): + '''將資料儲存為TFRecord數據''' + image_width, image_height = 64, 64 + image_channel = 3 + tfrecod_data_root = "../../Dataset/tfrecode_Dataset/tfrecod_data.tfrecords" + if not os.path.exists(tfrecod_data_root): + os.makedirs(tfrecod_data_root) + + TFWriter = tf.python_io.TFRecordWriter(tfrecod_data_root) + + try: + for i in range(len(images)): + if images[i] is None: + print('Error image:' + images[i]) + else: + #圖片轉為字串 + image_raw = str(images[i]) + + + # 將 tf.train.Feature 合併成 tf.train.Features + train_feature = tf.train.Features(feature={ + 'Label' : self.int64_feature(label), + 'image_raw' : self.bytes_feature(image_raw), + 'channel' : self.int64_feature(image_channel), + 'width' : self.int64_feature(image_width), + 'height' : self.int64_feature(image_height)} + ) + + # 將 tf.train.Features 轉成 tf.train.Example + train_example = tf.train.Example(features = train_feature) + + # 將 tf.train.Example 寫成 tfRecord 格式 + TFWriter.write(train_example.SerializeToString()) + + except Exception as e: + print(e) + + TFWriter.close() + print('Transform done!') + + return tfrecod_data_root + + # 轉Bytes資料為 tf.train.Feature 格式 + def int64_feature(self, value): + if not isinstance(value, list): + value = [value] + return tf.train.Feature(int64_list=tf.train.Int64List(value=value)) + + def bytes_feature(self, value): + return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) + + def Data_Decompile(self, example): + '''反編譯TFR數據''' + feature_description = { + 'data': tf.io.FixedLenFeature([], tf.string), + 'label': tf.io.FixedLenFeature([], tf.float32), + } + parsed_example = tf.io.parse_single_example(example, features=feature_description) + + x_sample = tf.io.parse_tensor(parsed_example['data'], tf.float32) + y_sample = parsed_example['label'] + + return x_sample, y_sample + + def load_dataset(self, filepaths): + ''' + 載入TFR數據集 + * dataset.shuffle(shuffle_buffer_size): + 隨機打亂此數據集的元素。 + + 該數據集用 buffer_size 元素填充緩衝區,然後從該緩衝區中隨機採樣元素,用新元素替換所選元素。 + 為了完美改組,需要緩衝區大小大於或等於數據集的完整大小。 + + 例如,如果您的數據集包含 10,000 個元素,但 buffer_size 設置為 1,000, + 則 shuffle 最初只會從緩衝區的前 1,000 個元素中選擇一個隨機元素。 + 一旦選擇了一個元素,它在緩衝區中的空間將被下一個(即第 1,001 個)元素替換,從而保持 1,000 個元素的緩衝區。 + ''' + shuffle_buffer_size = 700 + batch_size = 128 + tfrecod_data_root = "../../Dataset/tfrecode_Dataset" + + dataset = tf.data.TFRecordDataset(filepaths) + dataset = dataset.shuffle(shuffle_buffer_size) + dataset = dataset.map(map_func=self.Data_Decompile, num_parallel_calls= 8) + dataset = dataset.batch(batch_size).prefetch(64) + + # 產生文件名隊列 + filename_queue = tf.train.string_input_producer([filename], + shuffle=True, + num_epochs=3) + + return dataset \ No newline at end of file diff --git a/Training_Tools/Tools.py b/Training_Tools/Tools.py new file mode 100644 index 0000000..94828c1 --- /dev/null +++ b/Training_Tools/Tools.py @@ -0,0 +1,83 @@ +import pandas as pd +from sklearn.preprocessing import OneHotEncoder + +class Tool: + def __init__(self) -> None: + self.__ICG_Training_Root = "" + self.__Normal_Training_Root = "" + self.__Comprehensive_Training_Root = "" + + self.__ICG_Test_Data_Root = "" + self.__Normal_Test_Data_Root = "" + self.__Comprehensive_Testing_Root = "" + + self.__ICG_Validation_Data_Root = "" + self.__Normal_Validation_Data_Root = "" + self.__Comprehensive_Validation_Root = "" + + self.__ICG_ImageGenerator_Data_Root = "" + self.__Normal_ImageGenerator_Data_Root = "" + self.__Comprehensive_Generator_Root = "" + + self.__Labels = [] + self.__OneHot_Encording = [] + pass + + def Set_Labels(self): + self.__Labels = ["stomach_cancer_Crop", "Normal_Crop"] + + def Set_Save_Roots(self): + self.__ICG_Training_Root = "../Dataset/Training/CA_ICG" + self.__Normal_Training_Root = "../Dataset/Training/CA" + self.__Comprehensive_Training_Root = "../Dataset/Training/Mixed" + + self.__ICG_Test_Data_Root = "../Dataset/Training/CA_ICG_TestData" + self.__Normal_Test_Data_Root = "../Dataset/Training/Normal_TestData" + self.__Comprehensive_Testing_Root = "../Dataset/Training/Comprehensive_TestData" + + self.__ICG_Validation_Data_Root = "../Dataset/Training/CA_ICG_ValidationData" + self.__Normal_Validation_Data_Root = "../Dataset/Training/Normal_ValidationData" + self.__Comprehensive_Validation_Root = "../Dataset/Training/Comprehensive_ValidationData" + + self.__ICG_ImageGenerator_Data_Root = "../Dataset/Training/ICG_ImageGenerator" + self.__Normal_ImageGenerator_Data_Root = "../Dataset/Training/Normal_ImageGenerator" + self.__Comprehensive_Generator_Root = "../Dataset/Training/Comprehensive_ImageGenerator" + + def Set_OneHotEncording(self, Content): + Array_To_DataFrame = pd.DataFrame(Content) + onehotencoder = OneHotEncoder() + onehot = onehotencoder.fit_transform(Array_To_DataFrame).toarray() + + self.__OneHot_Encording = onehot + + def Get_Data_Label(self): + ''' + 取得所需資料的Labels + ''' + return self.__Labels + + def Get_Save_Roots(self, choose): + '''回傳結果為Train, test, validation + choose = 1 => 取ICG Label + else => 取Normal Label + + 若choose != 1 || choose != 2 => 會回傳四個結果 + ''' + if choose == 1: + return self.__ICG_Training_Root, self.__ICG_Test_Data_Root, self.__ICG_Validation_Data_Root + if choose == 2: + return self.__Normal_Training_Root, self.__Normal_Test_Data_Root, self.__Normal_Validation_Data_Root + else: + return self.__Comprehensive_Training_Root, self.__Comprehensive_Testing_Root, self.__Comprehensive_Validation_Root + + def Get_Generator_Save_Roots(self, choose): + '''回傳結果為Train, test, validation''' + if choose == 1: + return self.__ICG_ImageGenerator_Data_Root + if choose == 2: + return self.__Normal_ImageGenerator_Data_Root + else: + return self.__Comprehensive_Generator_Root + + def Get_OneHot_Encording_Label(self): + return self.__OneHot_Encording \ No newline at end of file diff --git a/Training_Tools/__init__.py b/Training_Tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Training_Tools/__pycache__/Tools.cpython-310.pyc b/Training_Tools/__pycache__/Tools.cpython-310.pyc new file mode 100644 index 0000000..9851f21 Binary files /dev/null and b/Training_Tools/__pycache__/Tools.cpython-310.pyc differ diff --git a/Training_Tools/__pycache__/__init__.cpython-310.pyc b/Training_Tools/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..5ae6a0b Binary files /dev/null and b/Training_Tools/__pycache__/__init__.cpython-310.pyc differ diff --git a/_validation/ValidationTheEnterData.py b/_validation/ValidationTheEnterData.py new file mode 100644 index 0000000..a043542 --- /dev/null +++ b/_validation/ValidationTheEnterData.py @@ -0,0 +1,14 @@ +class validation_the_enter_data: + def __init__(self) -> None: + pass + def validation_string(self, content, Comparison): + if content == Comparison: + return True + else: + return False + + def validation_type(self, enter, Type: type): + if not isinstance(enter, Type): + return False + else: + return True \ No newline at end of file diff --git a/_validation/__pycache__/ValidationTheEnterData.cpython-310.pyc b/_validation/__pycache__/ValidationTheEnterData.cpython-310.pyc new file mode 100644 index 0000000..c31063d Binary files /dev/null and b/_validation/__pycache__/ValidationTheEnterData.cpython-310.pyc differ diff --git a/_validation/__pycache__/ValidationTheEnterData.cpython-311.pyc b/_validation/__pycache__/ValidationTheEnterData.cpython-311.pyc new file mode 100644 index 0000000..75327b1 Binary files /dev/null and b/_validation/__pycache__/ValidationTheEnterData.cpython-311.pyc differ diff --git a/_validation/__pycache__/ValidationTheEnterData.cpython-39.pyc b/_validation/__pycache__/ValidationTheEnterData.cpython-39.pyc new file mode 100644 index 0000000..e30b818 Binary files /dev/null and b/_validation/__pycache__/ValidationTheEnterData.cpython-39.pyc differ diff --git a/all_models_tools/__init__.py b/all_models_tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/all_models_tools/__pycache__/__init__.cpython-310.pyc b/all_models_tools/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..9197dcd Binary files /dev/null and b/all_models_tools/__pycache__/__init__.cpython-310.pyc differ diff --git a/all_models_tools/__pycache__/__init__.cpython-311.pyc b/all_models_tools/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..1ac5718 Binary files /dev/null and b/all_models_tools/__pycache__/__init__.cpython-311.pyc differ diff --git a/all_models_tools/__pycache__/__init__.cpython-39.pyc b/all_models_tools/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..96dacd1 Binary files /dev/null and b/all_models_tools/__pycache__/__init__.cpython-39.pyc differ diff --git a/all_models_tools/__pycache__/all_model_tools.cpython-310.pyc b/all_models_tools/__pycache__/all_model_tools.cpython-310.pyc new file mode 100644 index 0000000..2d3fe16 Binary files /dev/null and b/all_models_tools/__pycache__/all_model_tools.cpython-310.pyc differ diff --git a/all_models_tools/__pycache__/all_model_tools.cpython-311.pyc b/all_models_tools/__pycache__/all_model_tools.cpython-311.pyc new file mode 100644 index 0000000..3114077 Binary files /dev/null and b/all_models_tools/__pycache__/all_model_tools.cpython-311.pyc differ diff --git a/all_models_tools/__pycache__/all_model_tools.cpython-39.pyc b/all_models_tools/__pycache__/all_model_tools.cpython-39.pyc new file mode 100644 index 0000000..3e86d88 Binary files /dev/null and b/all_models_tools/__pycache__/all_model_tools.cpython-39.pyc differ diff --git a/all_models_tools/__pycache__/pre_train_model_construction.cpython-310.pyc b/all_models_tools/__pycache__/pre_train_model_construction.cpython-310.pyc new file mode 100644 index 0000000..e1031d1 Binary files /dev/null and b/all_models_tools/__pycache__/pre_train_model_construction.cpython-310.pyc differ diff --git a/all_models_tools/__pycache__/pre_train_model_construction.cpython-39.pyc b/all_models_tools/__pycache__/pre_train_model_construction.cpython-39.pyc new file mode 100644 index 0000000..c9ef141 Binary files /dev/null and b/all_models_tools/__pycache__/pre_train_model_construction.cpython-39.pyc differ diff --git a/all_models_tools/all_model_tools.py b/all_models_tools/all_model_tools.py new file mode 100644 index 0000000..924c54f --- /dev/null +++ b/all_models_tools/all_model_tools.py @@ -0,0 +1,40 @@ +from keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint +from keras.layers import GlobalAveragePooling2D, Dense, Reshape, Multiply +from Load_process.file_processing import Process_File +import datetime + +def attention_block(input): + channel = input.shape[-1] + + GAP = GlobalAveragePooling2D()(input) + + block = Dense(units = channel // 16, activation = "relu")(GAP) + block = Dense(units = channel, activation = "sigmoid")(block) + block = Reshape((1, 1, channel))(block) + + block = Multiply()([input, block]) + + return block + +def call_back(model_name, index): + File = Process_File() + + model_dir = '../Result/save_the_best_model/' + model_name + File.JudgeRoot_MakeDir(model_dir) + modelfiles = File.Make_Save_Root('best_model( ' + str(datetime.date.today()) + " )-" + str(index) + ".weights.h5", model_dir) + + model_mckp = ModelCheckpoint(modelfiles, monitor='val_loss', save_best_only=True, save_weights_only = True, mode='auto') + + earlystop = EarlyStopping(monitor='val_loss', patience=74, verbose=1) # 提早停止 + + reduce_lr = ReduceLROnPlateau( + monitor = 'val_loss', + factor = 0.94, # 學習率降低的量。 new_lr = lr * factor + patience = 2, # 沒有改進的時期數,之後學習率將降低 + verbose = 0, + mode = 'auto', + min_lr = 0 # 學習率下限 + ) + + callbacks_list = [model_mckp, earlystop, reduce_lr] + return callbacks_list \ No newline at end of file diff --git a/all_models_tools/pre_train_model_construction.py b/all_models_tools/pre_train_model_construction.py new file mode 100644 index 0000000..8b72d80 --- /dev/null +++ b/all_models_tools/pre_train_model_construction.py @@ -0,0 +1,116 @@ +from all_models_tools.all_model_tools import attention_block +from keras.activations import softmax, sigmoid +from keras.applications import VGG16,VGG19, ResNet50, ResNet50V2, ResNet101, ResNet101V2, ResNet152, ResNet152V2, InceptionV3, InceptionResNetV2, MobileNet, MobileNetV2, DenseNet121, NASNetLarge, Xception +from keras.layers import GlobalAveragePooling2D, Dense, Flatten +from keras import regularizers +from keras.layers import Add +from application.Xception_indepentment import Xception_indepentment + +def Original_VGG19_Model(): + vgg19 = VGG19(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(vgg19.output) + dense = Dense(units = 4096, activation = "relu")(GAP) + dense = Dense(units = 4096, activation = "relu")(dense) + output = Dense(units = 2, activation = "softmax")(dense) + + return vgg19.input, output + +def Original_ResNet50_model(): + xception = ResNet50(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(xception.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return xception.input, dense + +def Original_NASNetLarge_model(): + nasnetlarge = NASNetLarge(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(nasnetlarge.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return nasnetlarge.input, dense + +def Original_DenseNet121_model(): + Densenet201 = DenseNet121(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(Densenet201.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return Densenet201.input, dense + +def Original_Xception_model(): + xception = Xception(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(xception.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return xception.input, dense + +def Original_VGG16_Model(): + vgg16 = VGG16(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + flatten = Flatten()(vgg16.output) + dense = Dense(units = 4096, activation = "relu")(flatten) + dense = Dense(units = 4096, activation = "relu")(dense) + output = Dense(units = 2, activation = "softmax")(dense) + + return vgg16.input, output + +def Original_ResNet50v2_model(): + resnet50v2 = ResNet50V2(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(resnet50v2.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return resnet50v2.input, dense + +def Original_ResNet101_model(): + resnet101 = ResNet101(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(resnet101.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return resnet101.input, dense + +def Original_ResNet101V2_model(): + resnet101v2 = ResNet101V2(include_top = False, weights = "imagenet", input_shape = (512, 512, 3)) + GAP = GlobalAveragePooling2D()(resnet101v2.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return resnet101v2.input, dense + +def Original_ResNet152_model(): + resnet152 = ResNet152(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(resnet152.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return resnet152.input, dense + +def Original_ResNet152V2_model(): + resnet152v2 = ResNet152V2(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(resnet152v2.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return resnet152v2.input, dense + +def Original_InceptionV3_model(): + inceptionv3 = InceptionV3(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(inceptionv3.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return inceptionv3.input, dense + +def Original_InceptionResNetV2_model(): + inceptionResnetv2 = InceptionResNetV2(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(inceptionResnetv2.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return inceptionResnetv2.input, dense + +def Original_MobileNet_model(): + mobilenet = MobileNet(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(mobilenet.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return mobilenet.input, dense + +def Original_MobileNetV2_model(): + mobilenetv2 = MobileNetV2(include_top = False, weights = "imagenet", input_shape = (200, 200, 3)) + GAP = GlobalAveragePooling2D()(mobilenetv2.output) + dense = Dense(units = 2, activation = "softmax")(GAP) + + return mobilenetv2.input, dense \ No newline at end of file diff --git a/all_models_tools/pytorch_Model.py b/all_models_tools/pytorch_Model.py new file mode 100644 index 0000000..e69de29 diff --git a/application/Xception_indepentment.py b/application/Xception_indepentment.py new file mode 100644 index 0000000..3d27bd5 --- /dev/null +++ b/application/Xception_indepentment.py @@ -0,0 +1,256 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +# SENet + # block = layers.GlobalAveragePooling2D()(residual) + # block = layers.Dense(units = residual.shape[-1] // 16, activation = "relu")(block) + # block = layers.Dense(units = residual.shape[-1], activation = "sigmoid")(block) + # block = Reshape((1, 1, residual.shape[-1]))(block) + # residual = Multiply()([residual, block]) + + + +from keras import backend +from keras import layers +from keras.layers import Reshape, Multiply, Conv1D +import math + +def Xception_indepentment(input_shape=None): + + channel_axis = 1 if backend.image_data_format() == "channels_first" else -1 + + img_input = layers.Input(shape=input_shape) + x = layers.Conv2D( + 32, (3, 3), strides=(2, 2), use_bias=False, name="block1_conv1" + )(img_input) + x = layers.BatchNormalization(axis=channel_axis, name="block1_conv1_bn")(x) + x = layers.Activation("relu", name="block1_conv1_act")(x + ) + x = layers.Conv2D(64, (3, 3), use_bias=False, name="block1_conv2")(x) + x = layers.BatchNormalization(axis=channel_axis, name="block1_conv2_bn")(x) + x = layers.Activation("relu", name="block1_conv2_act")(x) + + residual = layers.Conv2D( + 128, (1, 1), strides=(2, 2), padding="same", use_bias=False + )(x) + residual = layers.BatchNormalization(axis=channel_axis)(residual) + + # 注意力機制區域 + kernel = int(abs((math.log(residual.shape[-1], 2) + 1) / 2)) + if kernel % 2: + kernel_size = kernel + else: + kernel_size = kernel + 1 + + block = layers.GlobalAveragePooling2D()(residual) + block = Reshape(target_shape = (residual.shape[-1], 1))(block) + block = Conv1D(filters = 1, kernel_size = kernel_size, padding = "same", use_bias = False, activation = "sigmoid")(block) + block = Reshape((1, 1, residual.shape[-1]))(block) + residual = Multiply()([residual, block]) + + x = layers.SeparableConv2D( + 128, (3, 3), padding="same", use_bias=False, name="block2_sepconv1" + )(x) + x = layers.BatchNormalization(axis=channel_axis, name="block2_sepconv1_bn")( + x + ) + x = layers.Activation("relu", name="block2_sepconv2_act")(x) + + x = layers.SeparableConv2D( + 128, (3, 3), padding="same", use_bias=False, name="block2_sepconv2" + )(x) + x = layers.BatchNormalization(axis=channel_axis, name="block2_sepconv2_bn")( + x + ) + + x = layers.MaxPooling2D( + (3, 3), strides=(2, 2), padding="same", name="block2_pool" + )(x) + x = layers.add([x, residual]) + + residual = layers.Conv2D( + 256, (1, 1), strides=(2, 2), padding="same", use_bias=False + )(x) + residual = layers.BatchNormalization(axis=channel_axis)(residual) + + # 注意力機制區域 + kernel = int(abs((math.log(residual.shape[-1], 2) + 1) / 2)) + if kernel % 2: + kernel_size = kernel + else: + kernel_size = kernel + 1 + + block = layers.GlobalAveragePooling2D()(residual) + block = Reshape(target_shape = (residual.shape[-1], 1))(block) + block = Conv1D(filters = 1, kernel_size = kernel_size, padding = "same", use_bias = False, activation = "sigmoid")(block) + block = Reshape((1, 1, residual.shape[-1]))(block) + residual = Multiply()([residual, block]) + + x = layers.Activation("relu", name="block3_sepconv1_act")(x) + x = layers.SeparableConv2D( + 256, (3, 3), padding="same", use_bias=False, name="block3_sepconv1" + )(x) + x = layers.BatchNormalization(axis=channel_axis, name="block3_sepconv1_bn")( + x + ) + x = layers.Activation("relu", name="block3_sepconv2_act")(x) + + x = layers.SeparableConv2D( + 256, (3, 3), padding="same", use_bias=False, name="block3_sepconv2" + )(x) + x = layers.BatchNormalization(axis=channel_axis, name="block3_sepconv2_bn")(x) + + x = layers.MaxPooling2D( + (3, 3), strides=(2, 2), padding="same", name="block3_pool" + )(x) + x = layers.add([x, residual]) + + residual = layers.Conv2D( + 728, (1, 1), strides=(2, 2), padding="same", use_bias=False + )(x) + residual = layers.BatchNormalization(axis=channel_axis)(residual) + + # 注意力機制區域 + kernel = int(abs((math.log(residual.shape[-1], 2) + 1) / 2)) + if kernel % 2: + kernel_size = kernel + else: + kernel_size = kernel + 1 + + block = layers.GlobalAveragePooling2D()(residual) + block = Reshape(target_shape = (residual.shape[-1], 1))(block) + block = Conv1D(filters = 1, kernel_size = kernel_size, padding = "same", use_bias = False, activation = "sigmoid")(block) + block = Reshape((1, 1, residual.shape[-1]))(block) + residual = Multiply()([residual, block]) + + x = layers.Activation("relu", name="block4_sepconv1_act")(x) + x = layers.SeparableConv2D( + 728, (3, 3), padding="same", use_bias=False, name="block4_sepconv1" + )(x) + x = layers.BatchNormalization(axis=channel_axis, name="block4_sepconv1_bn")( + x + ) + x = layers.Activation("relu", name="block4_sepconv2_act")(x) + + x = layers.SeparableConv2D( + 728, (3, 3), padding="same", use_bias=False, name="block4_sepconv2" + )(x) + x = layers.BatchNormalization(axis=channel_axis, name="block4_sepconv2_bn")( + x + ) + + x = layers.MaxPooling2D( + (3, 3), strides=(2, 2), padding="same", name="block4_pool" + )(x) + x = layers.add([x, residual]) + + for i in range(8): + residual = x + prefix = "block" + str(i + 5) + + x = layers.Activation("relu", name=prefix + "_sepconv1_act")(x) + x = layers.SeparableConv2D( + 728, + (3, 3), + padding="same", + use_bias=False, + name=prefix + "_sepconv1", + )(x) + x = layers.BatchNormalization( + axis=channel_axis, name=prefix + "_sepconv1_bn" + )(x) + x = layers.Activation("relu", name=prefix + "_sepconv2_act")(x) + + x = layers.SeparableConv2D( + 728, + (3, 3), + padding="same", + use_bias=False, + name=prefix + "_sepconv2", + )(x) + x = layers.BatchNormalization( + axis=channel_axis, name=prefix + "_sepconv2_bn" + )(x) + x = layers.Activation("relu", name=prefix + "_sepconv3_act")(x) + + x = layers.SeparableConv2D( + 728, + (3, 3), + padding="same", + use_bias=False, + name=prefix + "_sepconv3", + )(x) + x = layers.BatchNormalization( + axis=channel_axis, name=prefix + "_sepconv3_bn" + )(x) + + x = layers.add([x, residual]) + + residual = layers.Conv2D( + 1024, (1, 1), strides=(2, 2), padding="same", use_bias=False + )(x) + residual = layers.BatchNormalization(axis=channel_axis)(residual) + + # 注意力機制區域 + kernel = int(abs((math.log(residual.shape[-1], 2) + 1) / 2)) + if kernel % 2: + kernel_size = kernel + else: + kernel_size = kernel + 1 + + block = layers.GlobalAveragePooling2D()(residual) + block = Reshape(target_shape = (residual.shape[-1], 1))(block) + block = Conv1D(filters = 1, kernel_size = kernel_size, padding = "same", use_bias = False, activation = "sigmoid")(block) + block = Reshape((1, 1, residual.shape[-1]))(block) + residual = Multiply()([residual, block]) + + x = layers.Activation("relu", name="block13_sepconv1_act")(x) + x = layers.SeparableConv2D( + 728, (3, 3), padding="same", use_bias=False, name="block13_sepconv1" + )(x) + x = layers.BatchNormalization( + axis=channel_axis, name="block13_sepconv1_bn" + )(x) + x = layers.Activation("relu", name="block13_sepconv2_act")(x) + + x = layers.SeparableConv2D( + 1024, (3, 3), padding="same", use_bias=False, name="block13_sepconv2" + )(x) + x = layers.BatchNormalization( + axis=channel_axis, name="block13_sepconv2_bn" + )(x) + + x = layers.MaxPooling2D( + (3, 3), strides=(2, 2), padding="same", name="block13_pool" + )(x) + x = layers.add([x, residual]) + + x = layers.SeparableConv2D( + 1536, (3, 3), padding="same", use_bias=False, name="block14_sepconv1" + )(x) + x = layers.BatchNormalization( + axis=channel_axis, name="block14_sepconv1_bn" + )(x) + x = layers.Activation("relu", name="block14_sepconv1_act")(x) + + x = layers.SeparableConv2D( + 2048, (3, 3), padding="same", use_bias=False, name="block14_sepconv2" + )(x) + x = layers.BatchNormalization( + axis=channel_axis, name="block14_sepconv2_bn" + )(x) + x = layers.Activation("relu", name="block14_sepconv2_act")(x) + + return img_input, block \ No newline at end of file diff --git a/application/__pycache__/Xception.cpython-39.pyc b/application/__pycache__/Xception.cpython-39.pyc new file mode 100644 index 0000000..7c76306 Binary files /dev/null and b/application/__pycache__/Xception.cpython-39.pyc differ diff --git a/application/__pycache__/Xception_indepentment.cpython-310.pyc b/application/__pycache__/Xception_indepentment.cpython-310.pyc new file mode 100644 index 0000000..7aca993 Binary files /dev/null and b/application/__pycache__/Xception_indepentment.cpython-310.pyc differ diff --git a/application/__pycache__/Xception_indepentment.cpython-311.pyc b/application/__pycache__/Xception_indepentment.cpython-311.pyc new file mode 100644 index 0000000..3ef9b81 Binary files /dev/null and b/application/__pycache__/Xception_indepentment.cpython-311.pyc differ diff --git a/application/__pycache__/Xception_indepentment.cpython-39.pyc b/application/__pycache__/Xception_indepentment.cpython-39.pyc new file mode 100644 index 0000000..27d7957 Binary files /dev/null and b/application/__pycache__/Xception_indepentment.cpython-39.pyc differ diff --git a/best_model( 2023-10-17 )-2.h5 b/best_model( 2023-10-17 )-2.h5 new file mode 100644 index 0000000..09430e3 Binary files /dev/null and b/best_model( 2023-10-17 )-2.h5 differ diff --git a/claculate_output_data.py b/claculate_output_data.py new file mode 100644 index 0000000..1209e9c --- /dev/null +++ b/claculate_output_data.py @@ -0,0 +1,85 @@ +import csv +import numpy as np + +judge = input("是否需要移動? (Y/N)") + +if judge == 'y' or judge == 'Y': + times = int(input("輸入要移動幾天: ")) + + for i in range(times): + date = input("輸入被移動的日期: ") + dateroot = "../Model_training_result/save_the_train_result(2024-" + date + ")/train_result.csv" + quantity_data = int(input("輸入要取出的資料筆數: ")) + + next_date = input("移動到哪一天? ") + + with open(dateroot, "r", newline = '') as csvFile: + data = csv.reader(csvFile) + data = list(data) + + with open("../Model_training_result/save_the_train_result(2024-" + next_date + ")/train_result.csv", "a+", newline = '') as csvFile1: + writer = csv.writer(csvFile1) + for i in range((quantity_data * 2 + 1) * -1 + 1, 0, 1): + writer.writerow(data[i]) + print("Data has been moved finish\n") + + + +date = input("輸入計算的日期: ") +with open("../Model_training_result/save_the_train_result(2024-" + date + ")/train_result.csv", newline = '') as csvfile: + rows = csv.reader(csvfile) + + row = list(rows) + + calcalate_loss = 0 + calculate_precision = 0 + calculate_recall = 0 + calculate_accuracy = 0 + calculate_f = 0 + calculate_auc = 0 + + list_loss = [] + list_precision = [] + list_recall = [] + list_accuracy = [] + list_f = [] + list_auc = [] + + for i in range(-1, -10, -2): + calcalate_loss += float(row[i][2]) + list_loss.append(float(row[i][2])) + + precision = str(row[i][3]).split("%") + calculate_precision += float(precision[0]) + list_precision.append(float(precision[0])) + + + recall = str(row[i][4]).split("%") + calculate_recall += float(recall[0]) + list_recall.append(float(recall[0])) + + accuracy = str(row[i][5]).split("%") + calculate_accuracy += float(accuracy[0]) + list_accuracy.append(float(accuracy[0])) + + f = str(row[i][6]).split("%") + calculate_f += float(f[0]) + list_f.append(float(f[0])) + + auc = str(row[i][7]).split("%") + calculate_auc += float(auc[0]) + list_auc.append(float(auc[0])) + +calculate_list = [calcalate_loss, calculate_precision, calculate_recall, calculate_accuracy, calculate_f, calculate_auc] +average = [] +for i in range(len(calculate_list)): + average.append((calculate_list[i] / 5)) + +std_list = [list_precision, list_recall, list_accuracy, list_f, list_auc] +standard = [] +standard.append(np.std(list_loss)) +for i in range(len(std_list)): + standard.append((np.std(std_list[i]) / 100)) + +for i in range(len(average)): + print("{:.2f}±{:.3f}".format(average[i], standard[i])) \ No newline at end of file diff --git a/draw_tools/Grad_cam.py b/draw_tools/Grad_cam.py new file mode 100644 index 0000000..bc7acae --- /dev/null +++ b/draw_tools/Grad_cam.py @@ -0,0 +1,92 @@ +from Load_process.file_processing import Process_File +from keras.models import Model +from matplotlib import pyplot as plt +import cv2 +import numpy as np +from keras import backend as K +from keras.preprocessing import image +import tensorflow as tf +import datetime + +class Grad_CAM: + def __init__(self, Label, One_Hot, Experiment_Name, Layer_Name) -> None: + self.experiment_name = Experiment_Name + self.Layer_Name = Layer_Name + self.Label = Label + self.One_Hot_Label = One_Hot + self.Save_File_Name = self.Convert_One_Hot_To_int() + + pass + + def process_main(self, model, index, images): + for i in range(len(images)): + array = np.expand_dims(images[i], axis=0) # 替圖片增加一個維度,代表他的數量 + heatmap = self.gradcam(array, model) + self.plot_heatmap(heatmap, images[i], self.Save_File_Name[i], index, i) + + pass + + def Convert_One_Hot_To_int(self): + return [np.argmax(Label)for Label in self.One_Hot_Label] + + + def gradcam(self, Image, model, pred_index = None): + # 首先,我們創建了一個模型,將輸入圖像映射為最後一個卷積層的激活值以及輸出的預測結果。 + grad_model = Model( + [model.inputs], [model.get_layer(self.Layer_Name).output, model.output] + ) + + # 然後,我們計算了對於輸入圖像而言預測類別的最高梯度,並相對於最後一個卷積層的激活值進行了計算。 + with tf.GradientTape() as tape: # 創建一個梯度紀錄器,並做前向傳播 + last_conv_layer_output, preds = grad_model(Image) + if pred_index is None: + pred_index = tf.argmax(preds[0]) + class_channel = preds[:, pred_index] + + # 這是輸出神經元(預測的頂部或所選的)對於最後一個卷積層的輸出特徵圖的梯度。 + grads = tape.gradient(class_channel, last_conv_layer_output) + + # 這是一個向量,其中每個項目是在特定特徵圖通道上梯度的平均強度。 + pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2)) + + # 我們將特徵圖陣列中的每個通道乘以「這個通道相對於頂部預測類別的重要性」,然後將所有通道加總起來,以獲得熱圖類別激活。n + last_conv_layer_output = last_conv_layer_output[0] + heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis] + heatmap = tf.squeeze(heatmap) + + # For visualization purpose, we will also normalize the heatmap between 0 & 1 + heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap) + return heatmap.numpy() + + def plot_heatmap(self, heatmap, img, Label, index, Title): + File = Process_File() + + # ReLU + heatmap = np.maximum(heatmap, 0) + # 正規化 + heatmap /= np.max(heatmap) + + # 讀取影像 + # img = cv2.imread(img) + fig, ax = plt.subplots() + # im = cv2.resize(cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2RGB), (img.shape[1], img.shape[0])) + + # 拉伸 heatmap + img_path = cv2.resize(img, (512, 512)) + heatmap = cv2.resize(heatmap, (512, 512)) + heatmap = np.uint8(255 * heatmap) + + img_path = cv2.cvtColor(img_path, cv2.COLOR_BGR2RGB) + + # 以 0.6 透明度繪製原始影像 + ax.imshow(img_path, alpha=1) + # 以 0.4 透明度繪製熱力圖 + ax.imshow(heatmap, cmap='jet', alpha=0.3) + + save_root = '../Result/CNN_result_of_reading('+ str(datetime.date.today()) + " )/" + str(Label) + File.JudgeRoot_MakeDir(save_root) + save_root = File.Make_Save_Root(self.experiment_name + "-" + str(index) + "-" + str(Title) + ".png", save_root) + # 存plt檔 + plt.savefig(save_root) + plt.close("all") # 關閉圖表 + pass \ No newline at end of file diff --git a/draw_tools/__init__.py b/draw_tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/draw_tools/__pycache__/Grad_cam.cpython-310.pyc b/draw_tools/__pycache__/Grad_cam.cpython-310.pyc new file mode 100644 index 0000000..3b6a4f4 Binary files /dev/null and b/draw_tools/__pycache__/Grad_cam.cpython-310.pyc differ diff --git a/draw_tools/__pycache__/Grad_cam.cpython-39.pyc b/draw_tools/__pycache__/Grad_cam.cpython-39.pyc new file mode 100644 index 0000000..8a191c5 Binary files /dev/null and b/draw_tools/__pycache__/Grad_cam.cpython-39.pyc differ diff --git a/draw_tools/__pycache__/__init__.cpython-310.pyc b/draw_tools/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..5aa1dfc Binary files /dev/null and b/draw_tools/__pycache__/__init__.cpython-310.pyc differ diff --git a/draw_tools/__pycache__/__init__.cpython-311.pyc b/draw_tools/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..747e1cf Binary files /dev/null and b/draw_tools/__pycache__/__init__.cpython-311.pyc differ diff --git a/draw_tools/__pycache__/__init__.cpython-39.pyc b/draw_tools/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..88e8105 Binary files /dev/null and b/draw_tools/__pycache__/__init__.cpython-39.pyc differ diff --git a/draw_tools/__pycache__/draw.cpython-310.pyc b/draw_tools/__pycache__/draw.cpython-310.pyc new file mode 100644 index 0000000..5cd8dd1 Binary files /dev/null and b/draw_tools/__pycache__/draw.cpython-310.pyc differ diff --git a/draw_tools/__pycache__/draw.cpython-311.pyc b/draw_tools/__pycache__/draw.cpython-311.pyc new file mode 100644 index 0000000..f8d3ce6 Binary files /dev/null and b/draw_tools/__pycache__/draw.cpython-311.pyc differ diff --git a/draw_tools/__pycache__/draw.cpython-39.pyc b/draw_tools/__pycache__/draw.cpython-39.pyc new file mode 100644 index 0000000..7750a6d Binary files /dev/null and b/draw_tools/__pycache__/draw.cpython-39.pyc differ diff --git a/draw_tools/draw.py b/draw_tools/draw.py new file mode 100644 index 0000000..e72d0d3 --- /dev/null +++ b/draw_tools/draw.py @@ -0,0 +1,77 @@ +from matplotlib import pyplot as plt +import seaborn as sns +import datetime +import matplotlib.figure as figure +import matplotlib.backends.backend_agg as agg +from Load_process.file_processing import Process_File + +def plot_history(history_value, file_name, model_name): + File = Process_File() + + plt.figure(figsize=(16,4)) + plt.subplot(1,2,1) + plt.plot(history_value.history['accuracy']) + plt.plot(history_value.history['val_accuracy']) + plt.ylabel('Accuracy') + plt.xlabel('epoch') + plt.legend(['Train','Validation'], loc='upper left') + plt.title('Model Accuracy') + + plt.subplot(1,2,2) + plt.plot(history_value.history['loss']) + plt.plot(history_value.history['val_loss']) + plt.ylabel('loss') + plt.xlabel('epoch') + plt.legend(['Train','Validation'], loc='upper left') + plt.title('Model Loss') + + model_dir = '../Result/save_the_train_image( ' + str(datetime.date.today()) + " )" + File.JudgeRoot_MakeDir(model_dir) + modelfiles = File.Make_Save_Root(str(model_name) + " " + str(file_name) + ".png", model_dir) + plt.savefig(modelfiles) + plt.close("all") # 關閉圖表 + +def draw_heatmap(matrix, model_name, index): # 二分類以上混淆矩陣做法 + File = Process_File() + + # 创建热图 + fig = figure.Figure(figsize=(6, 4)) + canvas = agg.FigureCanvasAgg(fig) + Ax = fig.add_subplot(111) + sns.heatmap(matrix, square = True, annot = True, fmt = 'd', linecolor = 'white', cmap = "Purples", ax = Ax)#画热力图,cmap表示设定的颜色集 + + model_dir = '../Result/model_matrix_image ( ' + str(datetime.date.today()) + " )" + File.JudgeRoot_MakeDir(model_dir) + modelfiles = File.Make_Save_Root(str(model_name) + "-" + str(index) + ".png", model_dir) + + # confusion.figure.savefig(modelfiles) + # 设置图像参数 + Ax.set_title(str(model_name) + " confusion matrix") + Ax.set_xlabel("X-Predict label of the model") + Ax.set_ylabel("Y-True label of the model") + + # 保存图像到文件中 + canvas.print_figure(modelfiles) + +def Confusion_Matrix_of_Two_Classification(Model_Name, Matrix, index): + File = Process_File() + + fx = sns.heatmap(Matrix, annot=True, cmap='turbo') + + # labels the title and x, y axis of plot + fx.set_title('Plotting Confusion Matrix using Seaborn\n\n') + fx.set_xlabel('answer Values ') + fx.set_ylabel('Predicted Values') + + # labels the boxes + fx.xaxis.set_ticklabels(['False','True']) + fx.yaxis.set_ticklabels(['False','True']) + + model_dir = '../Result/model_matrix_image ( ' + str(datetime.date.today()) + " )" + File.JudgeRoot_MakeDir(model_dir) + modelfiles = File.Make_Save_Root(str(Model_Name) + "-" + str(index) + ".png", model_dir) + + plt.savefig(modelfiles) + plt.close("all") # 關閉圖表 + + pass \ No newline at end of file diff --git a/experiments/__init__.py b/experiments/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/experiments/__pycache__/__init__.cpython-310.pyc b/experiments/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..9b93567 Binary files /dev/null and b/experiments/__pycache__/__init__.cpython-310.pyc differ diff --git a/experiments/__pycache__/__init__.cpython-311.pyc b/experiments/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..7c47fb4 Binary files /dev/null and b/experiments/__pycache__/__init__.cpython-311.pyc differ diff --git a/experiments/__pycache__/__init__.cpython-39.pyc b/experiments/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..2e1dfa5 Binary files /dev/null and b/experiments/__pycache__/__init__.cpython-39.pyc differ diff --git a/experiments/__pycache__/experiment.cpython-310.pyc b/experiments/__pycache__/experiment.cpython-310.pyc new file mode 100644 index 0000000..b215461 Binary files /dev/null and b/experiments/__pycache__/experiment.cpython-310.pyc differ diff --git a/experiments/__pycache__/experiment.cpython-311.pyc b/experiments/__pycache__/experiment.cpython-311.pyc new file mode 100644 index 0000000..b48f212 Binary files /dev/null and b/experiments/__pycache__/experiment.cpython-311.pyc differ diff --git a/experiments/__pycache__/experiment.cpython-39.pyc b/experiments/__pycache__/experiment.cpython-39.pyc new file mode 100644 index 0000000..44ad1be Binary files /dev/null and b/experiments/__pycache__/experiment.cpython-39.pyc differ diff --git a/experiments/__pycache__/model.cpython-39.pyc b/experiments/__pycache__/model.cpython-39.pyc new file mode 100644 index 0000000..058061a Binary files /dev/null and b/experiments/__pycache__/model.cpython-39.pyc differ diff --git a/experiments/__pycache__/original_image_model.cpython-39.pyc b/experiments/__pycache__/original_image_model.cpython-39.pyc new file mode 100644 index 0000000..e9a99ca Binary files /dev/null and b/experiments/__pycache__/original_image_model.cpython-39.pyc differ diff --git a/experiments/__pycache__/topic_model.cpython-39.pyc b/experiments/__pycache__/topic_model.cpython-39.pyc new file mode 100644 index 0000000..7329ccc Binary files /dev/null and b/experiments/__pycache__/topic_model.cpython-39.pyc differ diff --git a/experiments/experiment.py b/experiments/experiment.py new file mode 100644 index 0000000..77d3145 --- /dev/null +++ b/experiments/experiment.py @@ -0,0 +1,199 @@ +from all_models_tools.all_model_tools import call_back +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +from draw_tools.draw import plot_history, Confusion_Matrix_of_Two_Classification +from keras import regularizers +from Load_process.Load_Indepentend import Load_Indepentend_Data +from _validation.ValidationTheEnterData import validation_the_enter_data +from keras.layers import GlobalAveragePooling2D, Dense, Dropout +from keras.applications import Xception +from Load_process.file_processing import Process_File +from merge_class.merge import merge +from draw_tools.Grad_cam import Grad_CAM +from sklearn.metrics import confusion_matrix +from keras.models import Model +from keras.optimizers import SGD +from Image_Process.Image_Generator import Image_generator +import pandas as pd +import keras +import numpy as np +import time + +class experiments(): + def __init__(self, tools, status): + ''' + parmeter: + * validation_obj : 驗證物件 + * cut_image : 切割影像物件 + * image_processing : 讀檔與讀檔資料處理物件 + * merge : 合併物件 + * model_name: 取名,告訴我我是用哪個模型(可能是預處理模型/自己設計的模型) + * generator_batch_size: 每一批次要讀多少檔出來 + * epoch: 訓練次數 + * train_batch_size: 訓練時要多少批次的影像為1組 + * generator_batch_size: 減少圖片數量對GPU記憶體的用量, 減少張數用的 + * experiment_name : 本次實驗名稱 + * convolution_name : Pre-train model 的最後一層Convolotion的名稱 + ''' + + self.Topic_Tool = tools + + self.validation_obj = validation_the_enter_data() # 呼叫驗證物件 + self.cut_image = Load_Indepentend_Data(self.Topic_Tool.Get_Data_Label(), self.Topic_Tool.Get_OneHot_Encording_Label()) # 呼叫切割影像物件 + self.image_processing = Read_image_and_Process_image() + self.merge = merge() + + self.model_name = "Xception" # 取名,告訴我我是用哪個模型(可能是預處理模型/自己設計的模型) + self.experiment_name = "Xception Skin to train Normal stomach cancer" + # self.file_name = "Remove background of Chickenpox with normal image" + self.generator_batch_size = 50 + self.epoch = 10000 + self.train_batch_size = 128 + self.layers = 1 + self.convolution_name = self.get_layer_name(self.model_name) + + self.Grad = "" + self.Status = status + + pass + + def processing_main(self, train, train_label, counter): + Train, Test, Validation = self.Topic_Tool.Get_Save_Roots(self.Status) # 要換不同資料集就要改 + + + start = time.time() + self.cut_image.process_main(Test, Validation) # 呼叫處理test Data與Validation Data的function + end = time.time() + print("讀取testing與validation資料(154)執行時間:%f 秒\n" % (end - start)) + + Generator = Image_generator("", "") + + # 將處理好的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 + + self.Grad = Grad_CAM(self.Topic_Tool.Get_Data_Label(), self.test_label, self.experiment_name, self.convolution_name) + + cnn_model = self.construct_model() # 呼叫讀取模型的function + + # 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") + + Optimizer = SGD(learning_rate = 0.045, momentum = 0.9) # 決定優化器與學習率 + + cnn_model.compile( + loss = "binary_crossentropy", + optimizer = Optimizer, + metrics= + [ + 'accuracy', + keras.metrics.Precision(name='precision'), + keras.metrics.Recall(name='recall'), + keras.metrics.AUC(name = 'AUC'), + ] + ) + + train_data = Generator.Generator_Content(5) # 叫入ImageGeneratorr的物件,為了要讓我訓練時可以分批次讀取資料,GPU記憶體才不會爆 + cnn_model.summary() # 顯示模型架構 + print("\n\n\n讀取訓練資料(70000)執行時間:%f 秒\n\n" % (end - start)) + history = cnn_model.fit( + train_data.flow(train, train_label, batch_size = self.generator_batch_size), + # x = train, + # y = train_label, + epochs = self.epoch, + batch_size = self.train_batch_size, + validation_data = (self.validation, self.validation_label), + callbacks = call_back(self.experiment_name, counter) # 呼叫 call back list + # callbacks = call_back("best_model", self.counter) # 呼叫 call back list + ) + + Matrix = self.record_matrix_image(cnn_model, self.experiment_name, counter) # 紀錄混淆矩陣的function + loss, accuracy, precision, recall, AUC = cnn_model.evaluate(self.test, self.test_label) # 預測結果 + + # 防分母為0的時候 + if recall == 0 or precision == 0: + f = 0 + else: + f = (1 + 0.5 * 0.5) * ((recall * precision) / (0.5 * 0.5 * recall + precision)) + + print(self.record_everyTime_test_result(loss, accuracy, precision, recall, AUC, f, counter, self.experiment_name, Matrix)) # 紀錄當前訓練完之後的預測結果,並輸出成csv檔 + + plot_history(history, "train" + str(counter), self.experiment_name) # 將訓練結果化成圖,並將化出來的圖丟出去儲存 + self.Grad.process_main(cnn_model, counter, self.test) + + return loss, accuracy, precision, recall, AUC, f + + def construct_model(self): + '''決定我這次訓練要用哪個model''' + xception = Xception(include_top = False, weights = "imagenet", input_shape = (512, 512, 3)) + Flatten = GlobalAveragePooling2D()(xception.output) + output = Dense(units = 1370, activation = "relu", kernel_regularizer = regularizers.L2())(Flatten) + output = Dropout(0.6)(output) + output = Dense(units = 2, activation = "softmax")(output) + + cnn_model = Model(inputs = xception.input, outputs = output) + + return cnn_model + + def record_matrix_image(self, cnn_model : Model, model_name, index): + '''劃出混淆矩陣(熱力圖)''' + result = cnn_model.predict(self.test) # 利用predict function來預測結果 + result = np.argmax(result, axis = 1) # 將預測出來的結果從one-hot encoding轉成label-encoding + y_test = np.argmax(self.test_label, axis = 1) + matrix = confusion_matrix(result, y_test, labels = [0, 1]) # 丟入confusion matrix的function中,以形成混淆矩陣 + Confusion_Matrix_of_Two_Classification(model_name, matrix, index) # 呼叫畫出confusion matrix的function + + return matrix.real + + def record_everyTime_test_result(self, loss, accuracy, precision, recall, auc, f, indexs, model_name, Matrix): + '''記錄我單次的訓練結果並將它輸出到檔案中''' + File = Process_File() + + Dataframe = pd.DataFrame( + { + "model_name" : str(model_name), + "loss" : "{:.2f}".format(loss), + "precision" : "{:.2f}%".format(precision * 100), + "recall" : "{:.2f}%".format(recall * 100), + "accuracy" : "{:.2f}%".format(accuracy * 100), + "f" : "{:.2f}%".format(f * 100), + "AUC" : "{:.2f}%".format(auc * 100) + }, index = [indexs]) + File.Save_CSV_File("train_result", Dataframe) + # File.Save_TXT_File("Matrix_Result : " + str(Matrix), model_name + "_train" + str(indexs)) + + return Dataframe + + def get_layer_name(self, model_name): + if(self.validation_obj.validation_string(model_name, "VGG19")): + return "block5_conv4" + if(self.validation_obj.validation_string(model_name, "ResNet50")): + return "conv5_block3_3_conv" + if(self.validation_obj.validation_string(model_name, "Xception")): + return "block14_sepconv2" + if(self.validation_obj.validation_string(model_name, "DenseNet121")): + return "conv5_block16_concat" + if(self.validation_obj.validation_string(model_name, "InceptionResNetV2")): + return "conv_7b" + if(self.validation_obj.validation_string(model_name, "InceptionV3")): + return "conv2d_93" + if(self.validation_obj.validation_string(model_name, "MobileNet")): + return "conv_pw_13" + if(self.validation_obj.validation_string(model_name, "MobileNetV2")): + return "Conv_1" + if(self.validation_obj.validation_string(model_name, "NASNetLarge")): + return "separable_conv_2_normal_left5_18" + if(self.validation_obj.validation_string(model_name, "ResNet101")): + return "conv5_block3_3_conv" + if(self.validation_obj.validation_string(model_name, "ResNet101V2")): + return "conv5_block3_3_conv" + if(self.validation_obj.validation_string(model_name, "ResNet152")): + return "conv5_block3_3_conv" + if(self.validation_obj.validation_string(model_name, "ResNet152V2")): + return "conv5_block3_out" + if(self.validation_obj.validation_string(model_name, "ResNet50v2")): + return "conv5_block3_out" + if(self.validation_obj.validation_string(model_name, "VGG16")): + return "block5_conv3" + diff --git a/experiments/original_image_model.py b/experiments/original_image_model.py new file mode 100644 index 0000000..2585ca7 --- /dev/null +++ b/experiments/original_image_model.py @@ -0,0 +1,82 @@ +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_Activative, add_dropout +from keras.activations import softmax, sigmoid +from keras.applications import VGG19, ResNet50, InceptionResNetV2, Xception, DenseNet169, EfficientNetV2L + +def original_VGG19_model(): + tools = model_2D_tool() + dense_tool = model_Dense_Layer() + + vgg19 = VGG19(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) + GAP = tools.add_globalAveragePooling(vgg19.output) + # flatten = tools.add_flatten(vgg19.output) + dense = dense_tool.add_dense(256, GAP) + # dense = add_Activative(dense) + dense = dense_tool.add_dense(4, dense) + dense = add_Activative(dense, softmax) + + return vgg19.input, dense + +def original_Resnet50_model(): + tools = model_2D_tool() + dense_tool = model_Dense_Layer() + + resnet50 = ResNet50(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) + GAP = tools.add_globalAveragePooling(resnet50.output) + dense = dense_tool.add_dense(256, GAP) + dense = dense_tool.add_dense(4, dense) + dense = add_Activative(dense, softmax) + + return resnet50, dense + +def original_InceptionResNetV2_model(): + tools = model_2D_tool() + dense_tool = model_Dense_Layer() + + inceptionresnetv2 = InceptionResNetV2(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) + flatten = tools.add_flatten(inceptionresnetv2.output) + dense = dense_tool.add_dense(256, flatten) + dense = add_Activative(dense) + dense = dense_tool.add_dense(4, dense) + dense = add_Activative(dense, softmax) + + return inceptionresnetv2.input, dense + +def original_Xception_model(): + tools = model_2D_tool() + dense_tool = model_Dense_Layer() + + xception = Xception(include_top = False, weights = "imagenet", input_shape = (150, 150, 3)) + GAP = tools.add_globalAveragePooling(xception.output) + dense = dense_tool.add_dense(256, GAP) + dense = dense_tool.add_dense(4, dense) + dense = add_Activative(dense, softmax) + + return xception, dense + +def original_EfficientNetV2L_model(): + tools = model_2D_tool() + dense_tool = model_Dense_Layer() + + EfficientNet_V2L = EfficientNetV2L(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) + flatten = tools.add_flatten(EfficientNet_V2L.output) + dense = dense_tool.add_dense(256, flatten) + dense = add_Activative(dense) + dense = dense_tool.add_dense(4, dense) + dense = add_Activative(dense, softmax) + + return EfficientNet_V2L.input, dense + +def original_DenseNet169_model(): + tools = model_2D_tool() + dense_tool = model_Dense_Layer() + + Densenet169 = DenseNet169(include_top = False, weights = "imagenet", input_shape = (120, 120, 3)) + flatten = tools.add_flatten(Densenet169.output) + dense = dense_tool.add_dense(256, flatten) + dense = add_Activative(dense) + dense = dense_tool.add_dense(4, dense) + dense = add_Activative(dense, softmax) + + return Densenet169.input, dense \ No newline at end of file diff --git a/experiments/pytorch_Model.py b/experiments/pytorch_Model.py new file mode 100644 index 0000000..2d67c29 --- /dev/null +++ b/experiments/pytorch_Model.py @@ -0,0 +1,31 @@ +import torch +import torch.nn as nn +import torch.optim as optim +import torchvision.transforms as transforms +import timm + + +class ModifiedXception(nn.Module): + def __init__(self): + super(ModifiedXception, self).__init__() + + # 加載 Xception 預訓練模型,去掉最後一層 (fc 層) + self.base_model = timm.create_model('xception', pretrained=True) + 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 = self.global_avg_pool(x) # 全局平均池化 + x = self.relu(self.hidden_layer(x)) # 隱藏層 + ReLU + x = self.dropout(x) # Dropout + x = self.output_layer(x) # 輸出層 + return x diff --git a/experiments/topic_model.py b/experiments/topic_model.py new file mode 100644 index 0000000..fbf7467 --- /dev/null +++ b/experiments/topic_model.py @@ -0,0 +1,298 @@ +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 new file mode 100644 index 0000000..0379c41 --- /dev/null +++ b/main.py @@ -0,0 +1,133 @@ +from experiments.experiment import experiments +from Image_Process.load_and_ImageGenerator import Load_ImageGenerator +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +from Training_Tools.Tools import Tool +from model_data_processing.processing import shuffle_data +from Load_process.LoadData import Load_Data_Prepare +from Calculate_Process.Calculate import Calculate +from merge_class.merge import merge +import tensorflow as tf +import time +import os + +if __name__ == "__main__": + # 測試GPU是否可用 + print('TensorFlow version:', tf.__version__) + physical_devices = tf.config.experimental.list_physical_devices('GPU') + print(physical_devices) + assert len(physical_devices) > 0, "Not enough GPU hardware devices available" + tf.config.experimental.set_memory_growth(physical_devices[0], True) + os.environ["CUDA_VISIBLE_DEVICES"]='0' + + Status = 2 # 決定要使用什麼資料集 + # 要換不同資料集就要改 + tool = Tool() + tool.Set_Labels() + tool.Set_Save_Roots() + + Labels = tool.Get_Data_Label() + Trainig_Root, Testing_Root, Validation_Root = tool.Get_Save_Roots(Status) # 一般的 + Generator_Root = tool.Get_Generator_Save_Roots(Status) + + # 取得One-hot encording 的資料 + tool.Set_OneHotEncording(Labels) + Encording_Label = tool.Get_OneHot_Encording_Label() + Label_Length = len(Labels) + + Gneerator_size = 0 + Prepare = Load_Data_Prepare() + loading_data = Load_ImageGenerator(Trainig_Root, Testing_Root, Validation_Root, Generator_Root, Labels) + experiment = experiments(tool, Status) + image_processing = Read_image_and_Process_image() + Merge = merge() + Calculate_Tool = Calculate() + + counter = 5 + + for i in range(0, counter, 1): # 做規定次數的訓練 + # 讀取資料 + Data_Dict_Data = loading_data.process_main(Label_Length) + + Data_Dict_Data = shuffle_data(Data_Dict_Data, Labels, 2) + tmp = [] + Train_Size = 0 + if len(Data_Dict_Data[Labels[0]]) >= len(Data_Dict_Data[Labels[1]]): + Train_Size = len(Data_Dict_Data[Labels[1]]) + for j in range(Train_Size): + tmp.append(Data_Dict_Data[Labels[0]][j]) + Data_Dict_Data[Labels[0]] = tmp + else: + Train_Size = len(Data_Dict_Data[Labels[0]]) + for j in range(Train_Size): + tmp.append(Data_Dict_Data[Labels[1]][j]) + Data_Dict_Data[Labels[1]] = tmp + + # 輸出內容 + print("Negative Data有 " + str(len(Data_Dict_Data[Labels[1]])) + " 筆資料") + print("Positive Data有 " + str(len(Data_Dict_Data[Labels[0]])) + " 筆資料") + print("總共有 " + str(len(Data_Dict_Data[Labels[0]]) + len(Data_Dict_Data[Labels[1]])) + " 筆資料") + + # 做出跟資料相同數量的Label + Negative_Num = image_processing.make_label_list(Train_Size, Encording_Label[1]) + Positive_Num = image_processing.make_label_list(Train_Size, Encording_Label[0]) + + # 將資料做成Dict的資料型態 + Prepare.Set_Final_Dict_Data(Labels, Data_Dict_Data, [Positive_Num, Negative_Num], 2) + 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 + training_label = Merge.merge_all_image_data(Final_Dict_Data[keys[2]], Final_Dict_Data[keys[3]]) #將訓練資料的label合併成一個label的list + + 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) # 轉換資料型態 + + print(len(training_data)) + training_data, train_label = image_processing.image_data_processing(training_data, train_label) # 將讀出來的檔做正規化。降label轉成numpy array 格式 + + end = time.time() + print("\n\n\n讀取訓練資料(70000)執行時間:%f 秒\n\n" % (end - start)) + + # 針對其他資料執行值方圖等化加去背 + # with ProcessPoolExecutor() as executor: ## 默认为1,多執行續 + # trains = list(executor.map(adaptive_histogram_equalization, trains_another)) + + # # 針對正常資料做值方圖等化加去背 + # train_normal = list(executor.map(image_processing.get_data, normal)) # 多執行續讀檔 + # normal = list(executor.map(Remove_Background, train_normal)) # 多執行續去背 + # normal_data = list(executor.map(adaptive_histogram_equalization, normal)) + + # # 針對猴痘水痘進行讀檔 + # Chickenpox = list(executor.map(image_processing.get_data, chickenpox)) # 多執行續讀檔 + # train_chickenpox = list(executor.map(shapen, Chickenpox)) + + # Monkeypox = list(executor.map(image_processing.get_data, monkeypox)) # 多執行續讀檔 + # train_monkeypox = list(executor.map(shapen, Monkeypox)) # 銳化 + + + # for All_Normal_Data in normal_data: + # trains.append(All_Normal_Data) + # training_label.append([0, 0, 0, 0, 0, 1, 0]) + + # for All_Chhickenpox_Data in train_chickenpox: + # trains.append(All_Chhickenpox_Data) + # training_label.append([0, 0, 0, 1, 0, 0, 0]) + + # for All_Monkeypox_Data in train_monkeypox: + # trains.append(All_Monkeypox_Data) + # training_label.append([0, 0, 0, 0, 1, 0, 0]) + + loss, accuracy, precision, recall, AUC, f = experiment.processing_main(training_data, train_label, i) # 執行訓練方法 + Calculate_Tool.Append_numbers(loss, accuracy, precision, recall, AUC, f) + + print("實驗結果") + print("--------------------------------------------") + print("平均值: ") + print(Calculate_Tool.Calculate_Mean()) + print("標準差: ") + print(Calculate_Tool.Calculate_Std()) + print("結果: ") + print(Calculate_Tool.Output_Style()) + \ No newline at end of file diff --git a/merge_class/__pycache__/merge.cpython-310.pyc b/merge_class/__pycache__/merge.cpython-310.pyc new file mode 100644 index 0000000..3f5bba0 Binary files /dev/null and b/merge_class/__pycache__/merge.cpython-310.pyc differ diff --git a/merge_class/__pycache__/merge.cpython-311.pyc b/merge_class/__pycache__/merge.cpython-311.pyc new file mode 100644 index 0000000..83892d8 Binary files /dev/null and b/merge_class/__pycache__/merge.cpython-311.pyc differ diff --git a/merge_class/__pycache__/merge.cpython-39.pyc b/merge_class/__pycache__/merge.cpython-39.pyc new file mode 100644 index 0000000..2fa469e Binary files /dev/null and b/merge_class/__pycache__/merge.cpython-39.pyc differ diff --git a/merge_class/merge.py b/merge_class/merge.py new file mode 100644 index 0000000..66a0173 --- /dev/null +++ b/merge_class/merge.py @@ -0,0 +1,79 @@ +from _validation.ValidationTheEnterData import validation_the_enter_data + +class merge: + def __init__(self) -> None: + self.validation = validation_the_enter_data() + pass + + def set_merge_data(self, merge_data): + self.__merge_data = merge_data + pass + + def set_merge_keys(self, dict_key): + self.__keys = dict_key + + def set_judge_status(self, judge): + self.__judge = judge + + def get_judge_status(self): + return self.__judge + + def merge_all_image_data(self, Classify1, Classify2): + merged_data = [Classify1, Classify2] + + return self.merge_data_main(merged_data, 0, 2) + + def merge_data_main(self, merge_data, merge_start_index, total_merge_number = 3): + ''' + 將各類別資料合併在一起 + ## Parameter: + * merge_data: 要被合併的資料 + * merge_start_index: 合併資料的起始位置 + * total_merge_numbers: 總共要合併的數量 + ''' + if self.validation.validation_type(merge_data, dict): + self.set_merge_data(merge_data) + return self.merge_dict_to_list_data(merge_start_index, total_merge_number) + + elif self.validation.validation_type(merge_data, list): + self.set_merge_data(merge_data) + return self.merge_list_to_list_data(merge_start_index, total_merge_number) + + def merge_dict_to_list_data(self, merge_start_index, total_merge_number = 3): + self.set_merge_keys(list(self.__merge_data.keys())) + + self.set_judge_status(1) + result = list(self.__merge_data[self.__keys[merge_start_index]]) + result = self.merge_loop(result, merge_start_index, total_merge_number) + + return result + + def merge_dict_to_dict(self, original : dict, myself): + keys = list(original.keys()) + data = { + keys[0]: [], + keys[1]: [], + } + + for key in keys: + tempData = [original[key], myself[key]] + end = 2 + + self.set_merge_data(tempData) + data[key] = self.merge_list_to_list_data(0, end) + + return data + + def merge_list_to_list_data(self, merge_start_index, total_merge_number = 3): + self.set_judge_status(2) + result = list(self.__merge_data[merge_start_index]) + return self.merge_loop(result, merge_start_index, total_merge_number) + + def merge_loop(self, result, merge_start_index, total_merge_number = 3): + for i in range(merge_start_index + 1, merge_start_index + total_merge_number, 1): + if self.get_judge_status() == 1: + result += list(self.__merge_data[self.__keys[i]]) + else: + result += list(self.__merge_data[i]) + + return result \ No newline at end of file diff --git a/model_data_processing/__init__.py b/model_data_processing/__init__.py new file mode 100644 index 0000000..a2963c6 --- /dev/null +++ b/model_data_processing/__init__.py @@ -0,0 +1,9 @@ +''' +processing 這個檔案是我處理資料用的套件,以下為套件說明 + +get_data(data_dir, label, index): + 取得檔案中的資料。 + data_dir:檔案路徑 + label : 標籤名稱 + index : 標籤名稱轉成數字 +''' \ No newline at end of file diff --git a/model_data_processing/__pycache__/LoadData.cpython-39.pyc b/model_data_processing/__pycache__/LoadData.cpython-39.pyc new file mode 100644 index 0000000..bb73e93 Binary files /dev/null and b/model_data_processing/__pycache__/LoadData.cpython-39.pyc differ diff --git a/model_data_processing/__pycache__/__init__.cpython-310.pyc b/model_data_processing/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..d70d231 Binary files /dev/null and b/model_data_processing/__pycache__/__init__.cpython-310.pyc differ diff --git a/model_data_processing/__pycache__/__init__.cpython-311.pyc b/model_data_processing/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..ae4bbc7 Binary files /dev/null and b/model_data_processing/__pycache__/__init__.cpython-311.pyc differ diff --git a/model_data_processing/__pycache__/__init__.cpython-39.pyc b/model_data_processing/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..5e2c376 Binary files /dev/null and b/model_data_processing/__pycache__/__init__.cpython-39.pyc differ diff --git a/model_data_processing/__pycache__/make_ImageGenerator.cpython-39.pyc b/model_data_processing/__pycache__/make_ImageGenerator.cpython-39.pyc new file mode 100644 index 0000000..63587e0 Binary files /dev/null and b/model_data_processing/__pycache__/make_ImageGenerator.cpython-39.pyc differ diff --git a/model_data_processing/__pycache__/processing.cpython-310.pyc b/model_data_processing/__pycache__/processing.cpython-310.pyc new file mode 100644 index 0000000..7648c6f Binary files /dev/null and b/model_data_processing/__pycache__/processing.cpython-310.pyc differ diff --git a/model_data_processing/__pycache__/processing.cpython-311.pyc b/model_data_processing/__pycache__/processing.cpython-311.pyc new file mode 100644 index 0000000..9da029d Binary files /dev/null and b/model_data_processing/__pycache__/processing.cpython-311.pyc differ diff --git a/model_data_processing/__pycache__/processing.cpython-39.pyc b/model_data_processing/__pycache__/processing.cpython-39.pyc new file mode 100644 index 0000000..e4c381f Binary files /dev/null and b/model_data_processing/__pycache__/processing.cpython-39.pyc differ diff --git a/model_data_processing/__pycache__/processing_for_cut_image.cpython-310.pyc b/model_data_processing/__pycache__/processing_for_cut_image.cpython-310.pyc new file mode 100644 index 0000000..be25659 Binary files /dev/null and b/model_data_processing/__pycache__/processing_for_cut_image.cpython-310.pyc differ diff --git a/model_data_processing/__pycache__/processing_for_cut_image.cpython-311.pyc b/model_data_processing/__pycache__/processing_for_cut_image.cpython-311.pyc new file mode 100644 index 0000000..4d50677 Binary files /dev/null and b/model_data_processing/__pycache__/processing_for_cut_image.cpython-311.pyc differ diff --git a/model_data_processing/__pycache__/processing_for_cut_image.cpython-39.pyc b/model_data_processing/__pycache__/processing_for_cut_image.cpython-39.pyc new file mode 100644 index 0000000..803986a Binary files /dev/null and b/model_data_processing/__pycache__/processing_for_cut_image.cpython-39.pyc differ diff --git a/model_data_processing/processing.py b/model_data_processing/processing.py new file mode 100644 index 0000000..77d8099 --- /dev/null +++ b/model_data_processing/processing.py @@ -0,0 +1,39 @@ +import random + + +def calculate_confusion_matrix(predict, result): + '''計算並畫出混淆矩陣''' + tp, fp, tn, fn = 0 + for i in range(len(predict)): + if predict[i] == [1., 0., 0.] and result[i] == [1., 0., 0.]: + pass + + +def shuffle_data(image, label, mode = 1): + ''' + ## 被用來做資料打亂的用途 + ### 有兩種不同的需求 + 1. 打亂影像資料(讀完檔後的影像) => 回傳Label與Image Root兩個List + 2. 打亂路徑資料(影像的路徑資料,還沒讀檔前) => 回傳打亂後的Dict + ''' + if mode == 1: + shuffle_image, shuffle_label = [], [] + + total = list(zip(image, label)) + random.shuffle(total) + + for total_data in total: + shuffle_image.append(total_data[0]) + shuffle_label.append(total_data[1]) + + return shuffle_image, shuffle_label + else: + shuffle_image = { + label[0] : [], + label[1] : [], + } + for Label in label: + shuffle_image[Label] = image[Label] + random.shuffle(shuffle_image[Label]) + + return shuffle_image \ No newline at end of file diff --git a/model_data_processing/processing_for_cut_image.py b/model_data_processing/processing_for_cut_image.py new file mode 100644 index 0000000..4e1a984 --- /dev/null +++ b/model_data_processing/processing_for_cut_image.py @@ -0,0 +1,60 @@ +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +from sklearn.model_selection import train_test_split +from model_data_processing.processing import shuffle_data +from merge_class.merge import merge +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +from Load_process.LoadData import Load_Data_Prepare, Process_File, Load_Data_Tools +import shutil + +class Cut_Indepentend_Data(): + def __init__(self, Training_Root, Labels) -> None: + self.Training_Root = Training_Root + self.Labels = Labels + pass + def IndependentData_main(self, Indepentend_Data_Root, Test_Size): # 製作獨立資料 + Prepare = Load_Data_Prepare() + Load_Tool = Load_Data_Tools() + Prepare.Set_Data_Content([], len(self.Labels)) + Prepare.Set_Data_Dictionary(self.Labels, Prepare.Get_Data_Content(), 2) + Get_Data_Dict_Content = Prepare.Get_Data_Dict() + get_all_image_data = Load_Tool.get_data_root(self.Training_Root, Get_Data_Dict_Content, self.Labels) + + self.Cut_Of_Independent_Data(get_all_image_data, Indepentend_Data_Root, Test_Size) + + def Balance_Cut_Of_Independent_Data(self, Independent_Dict_Data_Content, Test_Size): + image_processing = Read_image_and_Process_image() + Prepare = Load_Data_Prepare() + Prepare.Set_Data_Content([], len(self.Labels)) + Prepare.Set_Data_Dictionary(self.Labels, Prepare.Get_Data_Content(), 2) + Indepentend_Content = Prepare.Get_Data_Dictionary() + + for cut_TotalTestData_roots_label in self.Labels: # 將資料的label一個一個讀出來 + label = image_processing.make_label_list(len(Independent_Dict_Data_Content[cut_TotalTestData_roots_label]), 0) # 製作假的label + tmp = list(Cut_Data(Independent_Dict_Data_Content[cut_TotalTestData_roots_label], label, Test_Size)) # 切割出特定數量的資料 + Indepentend_Content[cut_TotalTestData_roots_label] = [tmp[0], tmp[1]] + + return Indepentend_Content + + def Cut_Of_Independent_Data(self, Independent_Dict_Data_Content, IndependentDataRoot, Test_Size): + '''切割獨立資料(e.g. Validation、training)''' + image_processing = Read_image_and_Process_image() + Prepaer = Load_Data_Prepare() + File = Process_File() + i = 0 + + if not File.Judge_File_Exist(IndependentDataRoot): #若要儲存的資料夾不存在 + for cut_TotalTestData_roots_label in self.Labels: # 將資料的label一個一個讀出來 + root = File.Make_Save_Root(cut_TotalTestData_roots_label, IndependentDataRoot) # 合併成一個路徑 + File.Make_Dir(root) # 建檔 + + label = image_processing.make_label_list(len(Independent_Dict_Data_Content[cut_TotalTestData_roots_label]), 0) # 製作假的label + cut_data = Cut_Data(Independent_Dict_Data_Content[cut_TotalTestData_roots_label], label, Test_Size) # 切割出特定數量的資料 + + for data in cut_data[1]: + shutil.move(data, root) # 移動資料進新的資料夾 + i += 1 + +def Cut_Data(data, label, TestSize = 0.2, random = 2022): + '''切割資料集''' + train, test, train_label, test_label = train_test_split(data, label, test_size = TestSize, random_state = random) + return (train, test, train_label, test_label) \ No newline at end of file diff --git a/process_csv_file/process_csv_file.py b/process_csv_file/process_csv_file.py new file mode 100644 index 0000000..c05be65 --- /dev/null +++ b/process_csv_file/process_csv_file.py @@ -0,0 +1,8 @@ +import csv + +def get_csv_file_data(read_filename): + with open("../../Model_training_result/save_the_train_result(" + read_filename + ")/train_result.csv", newline = '') as csvfile: + rows = csv.reader(csvfile) + + row = list(rows) + return row \ No newline at end of file diff --git a/testing.py b/testing.py new file mode 100644 index 0000000..2ddcba4 --- /dev/null +++ b/testing.py @@ -0,0 +1,35 @@ +import paramiko +from scp import SCPClient +import os +import pexpect + +# def createSSHClient(server, port, user, password): +# client = paramiko.SSHClient() +# client.load_system_host_keys() +# client.set_missing_host_key_policy(paramiko.AutoAddPolicy) +# client.connect(server, port, user, password) + +# return client + +# ssh = createSSHClient("10.1.29.28", 31931, "root", "whitekirin") + +# # os.mkdir("Original_ResNet101V2_with_NPC_Augmentation_Image") +# # with open("Original_ResNet101V2_with_NPC_Augmentation_Image_train3.txt", "w") as file: +# # pass + +# with SCPClient(ssh.get_transport()) as scp: +# scp.get("/mnt/c/張晉嘉/stomach_cancer/Original_ResNet101V2_with_NPC_Augmentation_Image_train3.txt", "/raid/whitekirin/stomach_cancer/Model_result/save_the_train_result(2024-10-05)/Original_ResNet101V2_with_NPC_Augmentation_Image_train3.txt") + +def upload(port, filename, user, ip, dst_path): + cmdline = "scp %s -r %s %s@%s:%s" % (port, filename, user, ip, dst_path) + + try: + child = pexpect.spawn(cmdline) + child.expect("whitekirin109316118") + child.sendline() + child.expect(pexpect.EOF) + print("file upload Finish") + except Exception as e: + print("upload faild: ", e) + +upload(2222, "/raid/whitekirin/stomach_cancer/Model_result/save_the_train_result(2024-10-05)", "whitekirin", "203.64.84.39", "/mnt/c/張晉嘉/stomach_cancer") \ No newline at end of file diff --git a/testing_Labels_Accuracy.py b/testing_Labels_Accuracy.py new file mode 100644 index 0000000..b98e2fe --- /dev/null +++ b/testing_Labels_Accuracy.py @@ -0,0 +1,103 @@ +from experiments.experiment import experiments +from concurrent.futures import ProcessPoolExecutor +from loadData_and_MakeImageGenerator.load_and_ImageGenerator import Load_ImageGenerator +from Read_and_process_image.ReadAndProcess import Read_image_and_Process_image +import tensorflow as tf +import numpy as np +from sklearn.metrics import confusion_matrix, accuracy_score +from draw_tools.draw import draw_heatmap +from Load_process.LoadData import Loding_Data_Root +import os +import seaborn as sns +import datetime +from Load_process.file_processing import judge_file_exist, make_dir, make_save_root +from matplotlib import pyplot as plt +from Load_process.Load_Indepentend import Load_Indepentend_Data + +def draw(matrix, model_name, index): + # Using Seaborn heatmap to create the plot + + fx = sns.heatmap(matrix, annot=True, cmap='turbo') + # labels the title and x, y axis of plot + fx.set_title('Plotting Confusion Matrix using Seaborn\n\n') + fx.set_xlabel('Predicted Values') + fx.set_ylabel('answer Values ') + # labels the boxes + fx.xaxis.set_ticklabels(['False','True']) + fx.yaxis.set_ticklabels(['False','True']) + + model_dir = '../../Model_Confusion_matrix/model_matrix_image ( ' + str(datetime.date.today()) + " )/" + model_name + if not judge_file_exist(model_dir): + make_dir(model_dir) + modelfiles = make_save_root(str(model_name) + "-" + str(index) + ".png", model_dir) + plt.savefig(modelfiles) + plt.close("all") # 關閉圖表 + +if __name__ == "__main__": + with ProcessPoolExecutor() as executor: ## 默认为1 + print('TensorFlow version:', tf.__version__) + physical_devices = tf.config.experimental.list_physical_devices('GPU') + print(physical_devices) + assert len(physical_devices) > 0, "Not enough GPU hardware devices available" + tf.config.experimental.set_memory_growth(physical_devices[0], True) + os.environ["CUDA_VISIBLE_DEVICES"]='0' + + load = Loding_Data_Root() + experiment = experiments() + image_processing = Read_image_and_Process_image() + cut_image = Load_Indepentend_Data() + + model = experiment.construct_model() + model_dir = '../../best_model( 2023-10-17 )-2.h5' # 這是一個儲存模型權重的路徑,每一個模型都有一個自己權重儲存的檔 + if os.path.exists(model_dir): # 如果這個檔案存在 + model.load_weights(model_dir) # 將模型權重讀出來 + print("讀出權重\n") + + for times in range(5): + name = ["BP", "PF", "PV", "Chickenpox", "Monkeypox", "Normal", "Another"] + cut_image.process_main() # 呼叫處理test Data與Validation Data的function + test, test_label = cut_image.test, cut_image.test_label + + total_data = [[], [], [], [], [], [], []] + total_labels = [[], [], [], [], [], [], []] + start = 0 + end = 22 + for k in range(7): + for i in range(start, end): + total_data[k].append(test[i]) + total_labels[k].append(test_label[i]) + + total_data[k], total_labels[k] = image_processing.image_data_processing(total_data[k], total_labels[k]) + total_data[k] = image_processing.normalization(total_data[k]) + + start = end + end += 22 + + + j = 0 + for total_label in range(7): + result = model.predict(total_data[j]) # 利用predict function來預測結果 + result = np.argmax(result, axis = 1) # 將預測出來的結果從one-hot encoding轉成label-encoding + y_test = np.argmax(total_labels[j], axis = 1) + + print(name[j] + str(result), "\n") + + y_pre = [] + for i in range(len(result)): + if result[i] != j: + result[i] = 0 + else: + result[i] = 1 + + y_test[i] = 1 + + matrix = confusion_matrix(y_test, result, labels = [0, 1]) # 丟入confusion matrix的function中,以形成混淆矩陣 + draw(matrix, name[j], times) # 呼叫畫出confusion matrix的function + tn, fp, fn, tp = matrix.ravel() + + accuracy = (tn + tp) / (tn + fp + fn + tp) + print(name[j] + " 權重為: ", accuracy) + + experiment.record_everyTime_test_result(0, accuracy, 0, 0, 0, 0, times, name[j]) + + j += 1