simple_cd.py
1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 """ 4 Created on Wed Mar 9 20:15:48 2022 5 6 @author: aleoikon 7 """ 8 9 import sys 10 sys.path.append('/home/dvalsamis/Documents/projects/Change_detection_SSL_Siamese') 11 import time 12 13 from architectures.similarity_detection import pretext_task_one_nopool,pretext_task_one_aspp 14 15 # Now you can use pretext_task_one_nopool in your script 16 17 #from tests import change_detection_noup, change_detection_noup_1x1convs 18 #from similarity_detection import pretext_task_one_nopool 19 import tensorflow 20 from tensorflow.keras import layers, Model 21 from architectures.branch import branches_triplet 22 from tensorflow.keras.optimizers import Adam 23 from tensorflow.keras.utils import plot_model 24 from sklearn.model_selection import KFold 25 26 27 import pandas as pd 28 import numpy as np 29 import os 30 from tensorflow import keras 31 from architectures.conv_classifier import conv_classifier_two, conv_classifier_two_with_nspp,conv_classifier_two_with_aspp 32 from utils.layer_select import feature_selector, feature_selector_simple, transfer_learning_model #, feature_selector_task2 33 from utils.my_metrics import recall, accuracy, specificity, precision, f_measure, get_confusion_matrix 34 from utils.log_params import log_params_sim1 35 36 import matplotlib 37 matplotlib.use('TkAgg') 38 import matplotlib.pyplot as plt 39 import uuid 40 import random 41 from utils.weighted_cross_entropy import weighted_categorical_crossentropy 42 os.environ["CUDA_VISIBLE_DEVICES"]="1" 43 44 channel = 'rgb' 45 46 47 # Set random seed for TensorFlow 48 tensorflow.random.set_seed(1234) 49 50 # Set random seed for NumPy 51 np.random.seed(1234) 52 53 54 55 56 def create_rgb_onera(x,channel): 57 if channel == 'red': 58 r = x[:,:,2] 59 r = np.expand_dims(r, axis=2) 60 return r 61 if channel == 'green': 62 g = x[:,:,1] 63 g = np.expand_dims(g, axis=2) 64 return g 65 if channel == 'blue': 66 b = x[:,:,0] 67 b = np.expand_dims(b, axis=2) 68 return b 69 if channel == 'rgb': 70 r = x[:,:,2] 71 g = x[:,:,1] 72 b = x[:,:,0] 73 rgb = np.dstack((r,g,b)) 74 return(rgb) 75 if channel == 'rgbvnir': 76 r = x[:,:,2] 77 g = x[:,:,1] 78 b = x[:,:,0] 79 vnir = x[:,:,3] 80 rgbvnir = np.stack((r,g,b,vnir),axis=2).astype('float') 81 return(rgbvnir) 82 else: 83 return x 84 print("NOT CORRECT CHANNELS") 85 86 def generate_short_id(): 87 # Generate a UUID 88 unique_id = uuid.uuid4() 89 90 # Convert UUID to a hex string and take the first 4 characters 91 short_id = str(unique_id.hex)[:4] 92 93 return short_id 94 95 def get_layer_weights(model, layer_names): 96 layer_weights = {} 97 for layer_name in layer_names: 98 layer = model.get_layer(layer_name) 99 if layer: 100 weights = layer.get_weights() 101 if weights: 102 layer_weights[layer_name] = weights 103 else: 104 print("No weights found for layer:", layer_name) 105 else: 106 print("Layer not found:", layer_name) 107 return layer_weights 108 109 def compare_weights(before_training_weights, after_training_weights): 110 for layer_name in before_training_weights: 111 if layer_name in after_training_weights: 112 before_weights = before_training_weights[layer_name] 113 after_weights = after_training_weights[layer_name] 114 if len(before_weights) != len(after_weights): 115 print(f"Number of weight arrays different for layer {layer_name}") 116 continue 117 118 all_equal = all((before_weights[i] == after_weights[i]).all() for i in range(len(before_weights))) 119 if all_equal: 120 print(f"Weights for layer {layer_name} are the same before and after training.") 121 else: 122 print(f"Weights for layer {layer_name} are different before and after training.") 123 else: 124 print(f"Layer {layer_name} weights not found after training.") 125 126 def print_layer_weights(model, layer_names): 127 for layer_name in layer_names: 128 layer = model.get_layer(layer_name) 129 if layer: 130 weights = layer.get_weights() 131 if weights: 132 print("Weights for layer", layer_name, ":", weights) 133 else: 134 print("No weights found for layer:", layer_name) 135 else: 136 print("Layer not found:", layer_name) 137 138 139 #---------------------------------------------------------------------------------------------------------------------------------------------------------- 140 141 142 onera_train_target = '/data/valsamis_data/data/CBMI/CBMI_0.3/CBMI_0.3/NPY_dataset/aug_train_data/' 143 onera_test_target = '/data/valsamis_data/data/CBMI/CBMI_0.3/CBMI_0.3/NPY_dataset/aug_test_data/' 144 145 #Onera 146 # onera_train_target = '/home/aleoikon/Documents/data/ssl/onera_npys/patches/downstream/train/' 147 # onera_test_target = '/home/aleoikon/Documents/data/ssl/onera_npys/patches/downstream/test/' 148 149 150 #pretext_models_df = pd.read_csv('training/pretext_tasks/pretext_task_one_models.csv') 151 train = pd.read_csv(onera_train_target + "dataset_train.csv") 152 test = pd.read_csv(onera_test_target + "dataset_test.csv") 153 154 train = train.sample(frac=1, random_state=1) 155 test = test.sample(frac=1, random_state=1) 156 print("Train Data", len(train)) 157 print("Test Data", len(test)) 158 159 NORM = True 160 n_ch = 3 161 #Load everything in memory 162 X_train1 = np.ndarray(shape=(len(train),96,96,n_ch)) 163 X_train2 = np.ndarray(shape=(len(train),96,96,n_ch)) 164 y_train = np.ndarray(shape=(len(train),96,96)) 165 166 pos = 0 167 for index in train.index: 168 img1 = np.load(onera_train_target + train['pair1'][index]) 169 img2 = np.load(onera_train_target + train['pair2'][index]) 170 X1 = create_rgb_onera(img1, channel) 171 X2 = create_rgb_onera(img2, channel) 172 X1 = (X1 - X1.mean()) / X1.std() 173 X2 = (X2 - X2.mean()) / X2.std() 174 X_train1[pos] = X1 175 X_train2[pos] = X2 176 y_train[pos] = np.load(onera_train_target + train['change_mask'][index]) 177 178 pos += 1 179 180 ##### see the ration of 1 to 0s 181 train_balance = y_train.flatten() 182 (unique, counts) = np.unique(train_balance , return_counts=True) 183 frequencies = np.asarray((unique, counts)).T 184 print(frequencies[0][1]/frequencies[1][1]) 185 186 ## one hot the train 187 188 y_hot_train = keras.utils.to_categorical(y_train, num_classes=2) 189 190 X_test1 = np.ndarray(shape=(len(test),96,96,n_ch)) 191 X_test2 = np.ndarray(shape=(len(test),96,96,n_ch)) 192 y_test = np.ndarray(shape=(len(test),96,96)) 193 194 pos = 0 195 for index in test.index: 196 img1 = np.load(onera_test_target + test['pair1'][index]) 197 img2 = np.load(onera_test_target + test['pair2'][index]) 198 X1 = create_rgb_onera(img1, channel) 199 X2 = create_rgb_onera(img2, channel) 200 X1 = (X1 - X1.mean()) / X1.std() 201 X2 = (X2 - X2.mean()) / X2.std() 202 X_test1[pos] = X1 203 X_test2[pos] = X2 204 y_test[pos] = np.load(onera_test_target + test['change_mask'][index]) 205 pos += 1 206 207 ## one hot the test 208 y_hot_test = keras.utils.to_categorical(y_test, num_classes=2) 209 ######### 210 ind = random.randint(0, 1000) 211 plt.imshow(y_test[ind]) 212 ############### 213 214 depth = 2 215 dropout = 0.1 216 decay = 0.0001 217 LEARNING_RATE = 0.001 218 EPOCHS = 55 219 220 model_id = generate_short_id() 221 222 # #------------------------------------------------------------------------------------ 223 224 cd_model = conv_classifier_two_with_aspp(depth, dropout, decay, 96, 96, n_ch) 225 cd_model.summary() 226 #plot_model(cd_model, to_file='/home/dvalsamis/Documents/projects/Change_detection_SSL_Siamese/graphs/'+model_id+'_model_plot.png', show_shapes=True, show_layer_names=True) 227 228 229 #task1 230 sim_model = pretext_task_one_nopool( dropout, decay, 96, 96, n_ch) 231 232 233 #Load either a task1 or a task2 model 234 pretext_model_name = '/home/dvalsamis/Documents/projects/Change_detection_SSL_Siamese/saved_models/model_pretext1_unclouded_results.h5' 235 pretext_model = 'model_pretext1_unclouded_results' 236 #plot_model(sim_model, to_file='/home/dvalsamis/Documents/projects/Change_detection_SSL_Siamese/graphs/'+model_id+'_Pretext_model_plot.png', show_shapes=True, show_layer_names=True) 237 238 239 240 #task1 241 sim_model.load_weights(pretext_model_name) 242 243 244 # Feature selection(task1) 245 cd_model = feature_selector_simple(depth, sim_model, cd_model) 246 247 248 249 wx = 0.1 250 wy = 0.2 251 weights = np.array([wx, wy]) #!!!!!!!!!!!!!!!!!!!!!!!! -> change 252 #weights = np.array([0.1,0.2]) 253 254 255 LEARNING_RATE = 0.001 256 EPOCHS = 55 257 optimizer= Adam(learning_rate=LEARNING_RATE) 258 #loss='categorical_crossentropy' #weighted_bincrossentropy 'categorical_crossentropy' 'binary_crossentropy' 259 cd_model.compile(optimizer=optimizer, loss=weighted_categorical_crossentropy(weights), metrics=['accuracy']) 260 261 BATCH_SIZE=5 262 263 264 265 266 # Before training 267 print("Before Training:") 268 # before_training_weights = get_layer_weights(cd_model, ["norm_1", "conv1_1", "norm1_1", "relu1_1", "dropout1_1", "conv2_1", "norm2_1", "relu2_1", "dropout2_1","conv3_1","norm3_1","relu3_1","dropout3_1"]) 269 270 271 272 # Record start time 273 start_time = time.time() 274 275 history = cd_model.fit( 276 [X_train1 , X_train2], 277 y_hot_train, 278 validation_data=([X_test1, X_test2], y_hot_test), 279 batch_size=BATCH_SIZE, 280 epochs=EPOCHS 281 ) 282 283 284 285 286 # # Record end time 287 # end_time = time.time() 288 289 # # Calculate elapsed time 290 # elapsed_time = end_time - start_time 291 # elapsed_time_minutes = elapsed_time / 60 292 293 294 295 296 297 cd_model_path = '/home/dvalsamis/Documents/projects/Change_detection_SSL_Siamese/saved_models/CD_Simple_Levir_8192.h5' 298 cd_model.load_weights(cd_model_path) 299 300 301 ###predictions 302 predictions = cd_model.predict([X_test1, X_test2]) 303 y_pred = np.argmax(predictions, axis=3) 304 305 306 307 308 y_true = y_test 309 310 311 get_confusion_matrix(y_true, y_pred) 312 acc = accuracy(y_true,y_pred) 313 spec = specificity(y_true,y_pred) 314 rec = recall(y_true, y_pred) 315 prec = precision(y_true, y_pred) 316 f_m = f_measure(y_true, y_pred) 317 318 319 ####see some predictions 320 def scaleMinMax(x): 321 return ((x - np.nanpercentile(x,2)) / (np.nanpercentile(x,98) - np.nanpercentile(x,2))) 322 323 324 def create_rgb(x, channel): 325 if channel == 'rgb': 326 r = x[:,:,2] 327 r = scaleMinMax(r) 328 g = x[:,:,1] 329 g = scaleMinMax(g) 330 b = x[:,:,0] 331 b = scaleMinMax(b) 332 rgb = np.dstack((r,g,b)) 333 return(rgb) 334 else: 335 one = x[:,:,0] 336 one = scaleMinMax(one) 337 return one 338 339 340 341 342 # ''' 343 # Log Params 344 # ''' 345 import csv 346 347 348 349 predictions = cd_model.predict([X_test1, X_test2]) 350 y_pred = np.argmax(predictions, axis=3) 351 y_true = y_test 352 353 cd_model_name = "CD_Simple_"+"CBMI_"+model_id+".h5" 354 355 model_path = '/home/dvalsamis/Documents/projects/Change_detection_SSL_Siamese/saved_models/' 356 cd_model.save_weights(model_path+cd_model_name) 357 print("Saved model to disk") 358 359 weight_par = '[' + str(wx) + ',' + str(wy) + ']' 360 log_params_sim1("Task 1 (T)", "Linear", 'ASPP', weight_par, depth, "Softmax", LEARNING_RATE, 'Adam', EPOCHS, 'weighted_categorical_crossentropy', BATCH_SIZE, rec, spec, prec, f_m, acc, "CBMI Set", 96, NORM, pretext_model,"CD_Simple_Sysu_d8d2") 361 362 print("Done") 363