From 4f589f1a6deecf6d7c00fe669ba340aba66e6dcc Mon Sep 17 00:00:00 2001 From: Luis Roberto Mercado Diaz Date: Tue, 2 Apr 2024 17:08:08 -0400 Subject: [PATCH 1/3] Changes on minimal errors on plotting --- .../active_learning/ss_active_learning.py | 2 +- BML_project/main_checkpoints_updated.py | 64 ++++++++++++++++++ BML_project/models/ss_gp_model_checkpoint.py | 51 ++++++++++---- BML_project/ss_main.py | 4 +- .../__pycache__/data_loader.cpython-311.pyc | Bin 17950 -> 19704 bytes BML_project/utils_gp/data_loader.py | 28 +++----- 6 files changed, 114 insertions(+), 35 deletions(-) create mode 100644 BML_project/main_checkpoints_updated.py diff --git a/BML_project/active_learning/ss_active_learning.py b/BML_project/active_learning/ss_active_learning.py index 4c44836..d75b67f 100644 --- a/BML_project/active_learning/ss_active_learning.py +++ b/BML_project/active_learning/ss_active_learning.py @@ -80,7 +80,7 @@ def stochastic_compare_kmeans_gp_predictions(kmeans_model, gp_model, data_loader kmeans_predictions = kmeans_model.predict(data.cpu().numpy()) all_labels.append(labels.cpu().numpy()) all_data.append((gp_predictions, kmeans_predictions)) - + print(f"Processed batch size: {len(current_batch_labels)}, Cumulative original_labels size: {len(original_labels)}, Cumulative gp_predictions size: {len(gp_predictions)}") return all_data, np.concatenate(all_labels) import random diff --git a/BML_project/main_checkpoints_updated.py b/BML_project/main_checkpoints_updated.py new file mode 100644 index 0000000..234291c --- /dev/null +++ b/BML_project/main_checkpoints_updated.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Feb 7 15:34:31 2024 + +@author: lrm22005 +""" +import os +import tqdm +import torch +from utils.data_loader import preprocess_data, split_uids, update_train_loader_with_uncertain_samples +from models.ss_gp_model import MultitaskGPModel, train_gp_model +from utils_gp.ss_evaluation import stochastic_evaluation, evaluate_model_on_all_data +from active_learning.ss_active_learning import stochastic_uncertainty_sampling, run_minibatch_kmeans, stochastic_compare_kmeans_gp_predictions, label_samples +from utils.visualization import plot_comparative_results, plot_training_performance, plot_results + +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + +def main(): + n_classes = 4 + batch_size = 1024 + clinical_trial_train, clinical_trial_test, clinical_trial_unlabeled = split_uids() + data_format = 'pt' + + train_loader, val_loader, test_loader = preprocess_data(data_format, clinical_trial_train, clinical_trial_test, clinical_trial_unlabeled, batch_size) + + # Initialize result storage + results = { + 'train_loss': [], + 'validation_metrics': {'precision': [], 'recall': [], 'f1': [], 'auc_roc': []}, + 'active_learning': {'validation_metrics': []}, # Store validation metrics for each active learning iteration + 'test_metrics': None + } + + # Initial model training + model, likelihood, training_metrics = train_gp_model(train_loader, val_loader, num_iterations=50, n_classes=n_classes, patience=10, checkpoint_path='model_checkpoint_full.pt') + + # Save initial training metrics + results['train_loss'].extend(training_metrics['train_loss']) + for metric in ['precision', 'recall', 'f1_score']: + results['validation_metrics'][metric].extend(training_metrics[metric]) + + active_learning_iterations = 10 + for iteration in tqdm.tqdm(range(active_learning_iterations), desc='Active Learning', unit='iteration'): + uncertain_sample_indices = stochastic_uncertainty_sampling(model, likelihood, val_loader, n_samples=batch_size, device=device) + train_loader = update_train_loader_with_uncertain_samples(train_loader, uncertain_sample_indices, batch_size) + + # Re-train the model with updated training data + model, likelihood, val_metrics = train_gp_model(train_loader, val_loader, num_iterations=10, n_classes=n_classes, patience=10, checkpoint_path='model_checkpoint_last.pt') + + # Store validation metrics for each active learning iteration + results['active_learning']['validation_metrics'].append(val_metrics) + + # Final evaluations + test_metrics = evaluate_model_on_all_data(model, likelihood, test_loader, device, n_classes) + results['test_metrics'] = test_metrics + + # Visualization of results + plot_training_performance(results['train_loss'], results['validation_metrics']) + plot_results(results['test_metrics']) # Adjust this function to handle the structure of test_metrics + + print("Final Test Metrics:", results['test_metrics']) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/BML_project/models/ss_gp_model_checkpoint.py b/BML_project/models/ss_gp_model_checkpoint.py index 282c73d..c11f8cb 100644 --- a/BML_project/models/ss_gp_model_checkpoint.py +++ b/BML_project/models/ss_gp_model_checkpoint.py @@ -69,30 +69,40 @@ def forward(self, x): return latent_pred -def train_gp_model(train_loader, val_loader, num_iterations=50, n_classes=4, patience=10, checkpoint_path='model_checkpoint_full.pt', resume_training=False, batch_size=1024): +def train_gp_model(train_loader, val_loader, num_iterations=50, n_classes=4, patience=10, checkpoint_path='model_checkpoint_full.pt', resume_checkpoint_path=None): + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = MultitaskGPModel().to(device) likelihood = gpytorch.likelihoods.SoftmaxLikelihood(num_features=4, num_classes=4).to(device) optimizer = torch.optim.Adam(model.parameters(), lr=0.1) mll = gpytorch.mlls.VariationalELBO(likelihood, model, num_data=len(train_loader.dataset)) + best_val_loss = float('inf') + epochs_no_improve = 0 - # Load checkpoint if resuming training start_epoch = 0 - current_batch_index = 0 # Default value in case it's not found in the checkpoint - if resume_training and os.path.exists(checkpoint_path): - checkpoint = torch.load(checkpoint_path) + start_batch = 0 + + # Resume from checkpoint if specified + if resume_checkpoint_path is not None and os.path.exists(resume_checkpoint_path): + checkpoint = torch.load(resume_checkpoint_path) model.load_state_dict(checkpoint['model_state_dict']) likelihood.load_state_dict(checkpoint['likelihood_state_dict']) optimizer.load_state_dict(checkpoint['optimizer_state_dict']) - start_epoch = checkpoint.get('epoch', 0) + 1 # Resume from the next epoch - current_batch_index = checkpoint.get('current_batch_index', 0) # Retrieve the last batch index if it exists - print(f"Resuming training from epoch {start_epoch}, batch index {current_batch_index}") - - best_val_loss = float('inf') - epochs_no_improve = 0 - metrics = {'precision': [], 'recall': [], 'f1_score': [], 'auc_roc': [], 'train_loss': []} - - for epoch in range(start_epoch, num_iterations): + start_epoch = checkpoint.get('epoch', 0) + start_batch = checkpoint.get('batch', 0) + print(f"Resuming training from epoch {start_epoch}, batch {start_batch}") + + metrics = { + 'precision': [], + 'recall': [], + 'f1_score': [], + 'train_loss': [] + } + + for epoch in tqdm.tqdm(range(start_epoch, num_iterations), desc='Training', unit='epoch', leave=False): for batch_index, train_batch in enumerate(train_loader): + if epoch == start_epoch and batch_index < start_batch: + continue # Skip batches until the saved batch index + model.train() likelihood.train() optimizer.zero_grad() @@ -104,6 +114,17 @@ def train_gp_model(train_loader, val_loader, num_iterations=50, n_classes=4, pat loss.backward() optimizer.step() + # Save checkpoint at intervals or based on other conditions + if (batch_index + 1) % 100 == 0: # Example condition + torch.save({ + 'epoch': epoch, + 'batch': batch_index, + 'model_state_dict': model.state_dict(), + 'likelihood_state_dict': likelihood.state_dict(), + 'optimizer_state_dict': optimizer.state_dict() + }, checkpoint_path) + print(f"Checkpoint saved at epoch {epoch}, batch {batch_index}") + # Stochastic validation model.eval() likelihood.eval() @@ -160,7 +181,7 @@ def train_gp_model(train_loader, val_loader, num_iterations=50, n_classes=4, pat print(f"Early stopping triggered at epoch {epoch+1}") break - # Optionally, load the best model at the end of training + # Ensure to load the latest model state after the loop in case of early stopping if os.path.exists(checkpoint_path): checkpoint = torch.load(checkpoint_path) model.load_state_dict(checkpoint['model_state_dict']) diff --git a/BML_project/ss_main.py b/BML_project/ss_main.py index a610684..1b9cfce 100644 --- a/BML_project/ss_main.py +++ b/BML_project/ss_main.py @@ -6,7 +6,7 @@ """ import tqdm import torch -from utils.data_loader import preprocess_data, split_uids, update_train_loader_with_uncertain_samples +from utils_gp.data_loader import preprocess_data, split_uids, update_train_loader_with_uncertain_samples from models.ss_gp_model import MultitaskGPModel, train_gp_model from utils_gp.ss_evaluation import stochastic_evaluation, evaluate_model_on_all_data from active_learning.ss_active_learning import stochastic_uncertainty_sampling, run_minibatch_kmeans, stochastic_compare_kmeans_gp_predictions @@ -71,6 +71,8 @@ def main(): results['test_metrics'] = test_metrics test_gp_vs_kmeans_data, test_original_labels = stochastic_compare_kmeans_gp_predictions(test_kmeans_model, model, test_loader, n_batches=5, device=device) + # Before calling confusion_matrix in plot_comparative_results function + print(f"Length of original_labels: {len(original_labels)}, Length of gp_predictions: {len(gp_predictions)}") plot_comparative_results(test_gp_vs_kmeans_data, test_original_labels) # Visualization of results diff --git a/BML_project/utils_gp/__pycache__/data_loader.cpython-311.pyc b/BML_project/utils_gp/__pycache__/data_loader.cpython-311.pyc index 0b1a7ebdb4b25cf36cb492dfb1b7d20074e1bb08..ed2626e5a52ed6bc28cce7621bfb3c6c869cfc69 100644 GIT binary patch delta 3792 zcmb7GeQZt$lM?=dt~tl85Csm5pK{VTL48_0yN83K#Obxlw>=gRdxW{WGA3qb^$tMH=t84 z0(8m6fNpsiV3E9hD;F-&oE!Hhl(CWSs1i-Yl>tqNCH4h+DGw`%Nw~Vjh8+T2w{NnW zB@@LKm5b!mDmQIqPu6&TY;yStCv%|FUkqJkZYy_z^oQ+C@qW9_noy!ti44p8H8+iK zr}4y4L^h_@mdEx|8Xr|6Pe+y5P-J*ij_(gk>@VJ0J3R~|C2+nfX7jBgGVAoMU*WHr zG#zuzNsd2A6}O~{j1^qB(GTSJ#*X+98qs7uafiN zbt&hGR6`8;{;-MaYj`0Amh>3}BrI%R>|WBViOLv_4QZxCbYJ`eyd7vYcWfvg+qrve z80g;}RfaU%{f-1Kud2%6O>?7L3OqVU8-$@Jlo~%0VM6(U@}n{Itjp)t6M8WN|6+FtRyk#Z6ll z_kLk(&$j&*BI% zfC+BCr0m4tv^!JMnk{Law9N$?X587pTFjENId9c;Y1Z2a*<_#d1W)eEdg?*8e&`SV zBzP(~W54=j#=j=(UxVq!u9OAYp7N3gFAxtqoaFEEahOZVQOn`}XMd{q?HUKVAUyfI zJ}(?e0W>);H7^`VQ+_U}oLrCrv|i;4<`dbU>%A*>!a{&T7Yv-2K= zF06L+9QvO{<055vBp!j%wPP%U?P+;BDXyNMwBBU z84arr#k{^iC~mO}y#CS@Yh408@4bi*PL#+)s`_|cUd_Ogfo7=(tN$q+um}L&JCtA1 z=_crm#65Y$Q z?uJ>Z!C2k@OXoJ7&%?OLH*nB=BAv)k?&usZe~`YMavFV|0I(o`5HofXeypRdoV^kF zV*P8NflYdUJAVs0=nDwv5p=z1#PbYxoCVO#qw(*-Hm2v;N5Ln^ne?j4zw_iQ^ViIi zU$VP3%#NFWF+JEzq1EOYd_KoAp%8hF-3hHCKTC&eFN)+%mJN?o-$E@yxQzY=<#!N% zi=ZOB&7N*-5cNvQj-&J{^s+Y_`^@@0=a{4E5pt2WH-&?*gJ#^fl#g6CzMDSOe$W>(kLWv^5SzdWL11{bZi~qd7$W%G@n6 zw`qVL00ZOmC|u0cmb$JVK!;JV8A>l9oJN>NxP zIFb7;@D6ds0=E<@i1>A~z~!M?5GxnB9N381fcix+OJeH+mjjOljdQTfCO!qDEn*u! zloBzF{)=EHxP~0SBlzb4YG>;pv9W9GJY*YtyER}^t(OT~*BJAAW<{WJ~Fz4QjFS-GXvVZ=QNUB>6j0!sSV%mhk@5I#Y;jc}N~veM7) zwtLxoEB#G(q3a{K5?cV^q;r*@?3+G#wflP0TL)(cVzXoWXI%#}t^--ufwZ-4KrH?p z*lE^*-mQ_{yT+6R&9c!oj~5ke#6PlMtvM>1psxHg-Me-Nsk4CBy=DVJuQu<10M*8< zn#M&q;wHS;rFcGlJ*Cz`Tt?`=d+(PcK?|0UjU9cJtNnh#gufub#&H>EG0gJjd4n_6Ehxl`0D=i}I-(9{c-LQb?WoY{&oWn!dqZ_-# zQt0Sl>c*$mn|qDI(o6eMkF`I{_x8eN$bz9C2$yP>NJJisMIuJ!97OZqGi!G_nPPR_ zv9%aLBb3NH)z^nFKyfm<0kxYDdH_C`9vc~x_wI^!(n|JL_mx#WJgHgW9*)O1eXMIf N&DZyv*mTb`{{h2_kKq6S delta 2120 zcmZvdYfMx}6vyxE-Fx@Rf`}|GRo?2Q5k*i*s^}uDyhJOsq1a}#;VuD-Jm#*o)w_z3 zR@yYx_S6DuTa78Dh}CABrcIw}n)<=EU^Wd|OGBDy3nvk+;Mw(O$(yUsM7S)Eds&=GJjjI)u_(^LV|3Vn!>bO{ro8!2-c>xMX& zn{n9aDlzZFfFkm4=yz?%?V!|Z#4XHqRgFCO3@$=*)KwLBRrSPA%7P^h9I1Qd9?ax# zz@gOVVaq&=c?`R~f-b;YrOESy23^=nYl$}9F!zBe1jT>^7t_*27BE5Hf@HWVJM1q; z!`y*`jBv0tNeUX<=IGG5AjN4Iz-dlSO%*iiMqShm(3GD4tjwcpcpXPaOwB&c7YJ}( zi9LRZT$a{$pBfcUkvORn5nI%kc^@V8Qa2&cvd!;BjXS*of1B3MH3{8tFMXMJ7aH1j zM3*q;Obt7g!K|<|ug5-?ko2ytuR5Hd^hj51i3bb&T%)$^uq}I1kSwbPXP?r}6n?&X zbcs8>#C=I|k0|bmw5+4S!P;&gcOpOTyL&^&I z2=)8ms*=U_gEhB+^@fUbha@%t*OqL{_?n^w#l=4*`!wMUK_?8sj-?At5h>8l8=K+8 z(uH!wNczIBODphJU`8Lz&tJ@rLUq0}|1dgsI;RzX-qdNF4ne+CWT)U{p{wXTW=15f z+1KIcXK9*q2r5akX}1wsYxK4Hxh7&KJ^g-hUx2%XS?mI2EN`@mb^H~Kc@#Uq@*L$= z8cBuC-zEUzeZq0VegZ9zUx0s?XEY6<*){buX)sG^lfrZ)8Kli@Qh0=BnX;ykz@&wf z!W3kiRFCS5K&d8Gp~7CC-nEocc)?0(ZNx~MYUq?=X4 zus9>rs$21)G1hqaFbu5RRBnr%RuISX-Gs}8J%ld8Ucxxx4@AUt|7nR>$)FQLp=}s} z(xTj)KhgLZzZ%`CE@9k}+E;OG*O}5UpZsChNL}NoLk&CBP=8UKH0vA8h*;`8wcd`_ z_JGE}h5uHsPMA?hKS5RTYtlcMdMWf<@m7{PwPSRVI#ETwK%-Xx|JsZVa?lhsPt!t1 z9hh!JJp^4EHVoifc#_`3Xq%xMI9S45urn z7&xt-lQ4=srf4TQ0t9+4VtPkaj$WJSLHvz@h&{l4Ezs@Ggf&IU@SS^B!cBBv$FKGk zqD!~}*W88iNu37tAu)=Cf|9KG#5VFF(T9Xq^vw>C4~afx=%bQ2Ljv7)TyzQkim(jrc5;1wbYI~#C8+)4?XsYiK5xK+HrusC#kvih0ifT?Z z#LvRL%0?F*Q|!P Date: Tue, 2 Apr 2024 17:13:12 -0400 Subject: [PATCH 2/3] Resolving minimal errors --- BML_project/active_learning/ss_active_learning.py | 2 ++ BML_project/ss_main.py | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/BML_project/active_learning/ss_active_learning.py b/BML_project/active_learning/ss_active_learning.py index d75b67f..98b9425 100644 --- a/BML_project/active_learning/ss_active_learning.py +++ b/BML_project/active_learning/ss_active_learning.py @@ -81,6 +81,8 @@ def stochastic_compare_kmeans_gp_predictions(kmeans_model, gp_model, data_loader all_labels.append(labels.cpu().numpy()) all_data.append((gp_predictions, kmeans_predictions)) print(f"Processed batch size: {len(current_batch_labels)}, Cumulative original_labels size: {len(original_labels)}, Cumulative gp_predictions size: {len(gp_predictions)}") + if len(current_batch_labels) < expected_batch_size: + print(f"Last batch processed with size: {len(current_batch_labels)}") return all_data, np.concatenate(all_labels) import random diff --git a/BML_project/ss_main.py b/BML_project/ss_main.py index 1b9cfce..b784ce4 100644 --- a/BML_project/ss_main.py +++ b/BML_project/ss_main.py @@ -10,7 +10,7 @@ from models.ss_gp_model import MultitaskGPModel, train_gp_model from utils_gp.ss_evaluation import stochastic_evaluation, evaluate_model_on_all_data from active_learning.ss_active_learning import stochastic_uncertainty_sampling, run_minibatch_kmeans, stochastic_compare_kmeans_gp_predictions -from utils.visualization import plot_comparative_results, plot_training_performance, plot_results +from utils_gp.visualization import plot_comparative_results, plot_training_performance, plot_results device = torch.device("cuda" if torch.cuda.is_available() else "cpu") @@ -50,6 +50,7 @@ def main(): # Update the training loader with uncertain samples train_loader = update_train_loader_with_uncertain_samples(train_loader, uncertain_sample_indices, batch_size) + print(f"Updated training data size: {len(train_loader.dataset)}") # Re-train the model with the updated training data model, likelihood, val_metrics = train_gp_model(train_loader, val_loader, num_iterations=10, n_classes=n_classes, patience=10, checkpoint_path='model_checkpoint_last.pt') @@ -71,7 +72,7 @@ def main(): results['test_metrics'] = test_metrics test_gp_vs_kmeans_data, test_original_labels = stochastic_compare_kmeans_gp_predictions(test_kmeans_model, model, test_loader, n_batches=5, device=device) - # Before calling confusion_matrix in plot_comparative_results function + print(f"Length of original_labels: {len(original_labels)}, Length of gp_predictions: {len(gp_predictions)}") plot_comparative_results(test_gp_vs_kmeans_data, test_original_labels) From f8fcd3ec8596bd78dca3fb7511814c9d0dcac5d2 Mon Sep 17 00:00:00 2001 From: Luis Roberto Mercado Diaz Date: Tue, 2 Apr 2024 18:08:27 -0400 Subject: [PATCH 3/3] Evaluation and edition of modules --- .../ss_active_learning.cpython-311.pyc | Bin 6942 -> 7556 bytes .../active_learning/ss_active_learning.py | 24 ++++++++++++++++++ .../__pycache__/ss_gp_model.cpython-311.pyc | Bin 12179 -> 12179 bytes .../__pycache__/ss_evaluation.cpython-311.pyc | Bin 9772 -> 9775 bytes .../__pycache__/visualization.cpython-311.pyc | Bin 5734 -> 5702 bytes 5 files changed, 24 insertions(+) diff --git a/BML_project/active_learning/__pycache__/ss_active_learning.cpython-311.pyc b/BML_project/active_learning/__pycache__/ss_active_learning.cpython-311.pyc index 45c9875deaf1bad595378c59b1e08a1296ac1ec3..8d691baff795b1e885f3e6530af61db78d1be1e9 100644 GIT binary patch literal 7556 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 delta 3289 zcmZ`*eQX<#BP_iao4Vi)1+x=(j-;8Xfz@i$9HL+I(E3b zX6raB0SXFIB^q9!0V)*GRMM?dBS0cZNOXUU6$HrV-Eed;X+oP&H3_-e5Y_&H=RL=1 zQpRiF?|t5{=e_rNpXd4A^%s5|b^grZun|yNKX;qAc$S^@}f2bz;KBk(?n-O;B7F=Y(E2XShIws+T|g8rg<&WRNCg!!-H{SyNAg!Wwu!4g-9T zyhU6hWMa~tLw_cHJ#3#eN=kLMt$9^v=XN)8QLQGEz6!?C!oOK4N8a;5;qYvmvtA0OtP0qecvAv>4wy!c+(ek%lK|67WgqMM*TsT6e zzF~N}WsZ?e=z+&$kQuaY41UM!S-$B+e{eZzlDP2>3fFfon4Vn&w?&U?G`(iX+qPzUEmCYbQfN7{KE4tCybIbUcw z|L%p0O3Q@WGLdH*H`)Cwku}SjCEs~UX&X@61{M_dw91}d8s4l9sMY(H`rl(4Z%5W@ z?)zT%-3{CetT`3-sLCGQux&JK*i^P3W-`Gd(@|hL)`stoy*{RdyVY=aG2CAW_bcH6 zH9Vj&r&Z>3UjLU|`pZ*KPgFkFWBrVu5DU)^>^%HV`N@+fJDa=YT7n6#4y|5X9a8NF z^YlRx+xX3H5xL5kBDDi@*F=hXbi&8@3HQQ7|N?wj*KNdW&v)}~?nFajz!X6Bb z7@9C(w-xpQfEy+RDV0dar&ChMtl4oW#nagY#|y&2qj*{~hGTfHdp4Cxm3O%^%O^6T za1f8-%|x7j(58Lw(QXh900o~>OhGw7&~-W zGH#+1OgrkWVLFSh;eu;eagC_1k)rED!F54#jjOKlC3@3RU$g`Zmf-4(iltq(wCD9d z`YltBa#pLMWI%ssULueF;<#hRP2rLF4hTWFaXnb(Z1Q}sA@yZT6nzzCkeZk%^8ggh%*+TKzEXSvX{aDir z7&rPz_BqTRm+%3&IdQ;tBL#b=Yn)_BjM5G@ zGuy!++3|7%IQ38KV%Eu=O}1eMLA}mBMqNb5T#abR=*G-J+OVfngyhl5qu$d&8Oqc^ z5wac9eh_m0A$QIpGc&Hr+pN0rB0IrR_vkWrpbbwLlY>omT+st;wQ5Um5bHJNoUp#8 zGV5HR0AiMMmL)y z#pbR;bJzNngiiQYILv|9VtXdl<1fm9aEamsmf2iOeQv7FC|JnSxse*s1=$k3{X5PJ$QG8j|mt8sw zdVC?3?JTlg1-7e9tVOoFu)uaJY)oZiOT%E3=Dn|3*1{WAh4$kcU&)V56=G9LD5*4Y zY7>{|r`4uQc_y$;!ufEw!t|(2PoC)kq2vQ|m8gmpbyGgZ_WT5c-uz!!*c#C}_A{n6 zeI~!g23iIWP;Vcg2M?Lw?jiw0q)-b^099AH8o^bSW{$_XY%(6#IZAi%a$5Gou;!Ms z=-7F#m<<#S&Y3_0{~_U2IK$$ delta 27 hcmbOnKRKRzIWI340}#~DoVk&ki=EMVvlx4=1^{Q&2J!#^ diff --git a/BML_project/utils_gp/__pycache__/ss_evaluation.cpython-311.pyc b/BML_project/utils_gp/__pycache__/ss_evaluation.cpython-311.pyc index 14c7dfa31576c8ee01e847158a5109e4899ef798..46b1836aaad2f31bb6d73e4624ae96f7df14eb6f 100644 GIT binary patch delta 36 qcmZ4Ev)+e$IWI340}$kg@7>7l&CXPnJUN0rl{r4WVDnz~d^rHWRtnAl delta 32 mcmZ4Qv&M&eIWI340}#YZPT$Dw&CXQrJUN0rb@KuCd^rG*EeQbt diff --git a/BML_project/utils_gp/__pycache__/visualization.cpython-311.pyc b/BML_project/utils_gp/__pycache__/visualization.cpython-311.pyc index a8c3afd30ad9aefea43425eec7756a9d74ec4254..f53ef75de607c198841c7434a3ccddd3431a532d 100644 GIT binary patch delta 83 zcmaE+b4-VOIWI340}$kg@7>5fft9H$dGcIVGb5M$sR}-+iA8ytdFe3$Mfq8&$tCf|F=?53i8=8F5PnQ) NNoG#*W>z*w0RU@$Cfxu4