@@ -770,18 +770,25 @@ def explain(
770770
771771 expr_df = expr_df .loc [sample_id , :]
772772 background = addToTensor (randomTrainingSample (expr_df , 10 ), device )
773- foreground = addToTensor (
774- splitExprandSample (condition = condition , sample_size = 10 , expr = expr_df ),
775- device ,
776- )
773+ foreground_df = splitExprandSample (condition = condition , sample_size = 10 , expr = expr_df )
774+ foreground = addToTensor (foreground_df , device )
777775
776+ class_idx = int (self .label_encoder .transform ([subtype ])[0 ])
778777 explainer = shap .DeepExplainer (ModelWrapper (self , source = source ), background )
779778 shap_values = explainer .shap_values (foreground , ranked_outputs = None )
780779
781- tumour_expr = expr_df .head (10 )
780+ # SHAP ≥0.46 stacks class outputs into (n_samples, n_features, n_classes);
781+ # older versions return a list indexed [class][sample, feature].
782+ import numpy as np
783+
784+ if isinstance (shap_values , np .ndarray ) and shap_values .ndim == 3 :
785+ sv = shap_values [..., class_idx ]
786+ else :
787+ sv = shap_values [class_idx ]
788+
782789 shap .summary_plot (
783- shap_values [ 0 ] ,
784- features = tumour_expr ,
790+ sv ,
791+ features = foreground_df ,
785792 feature_names = list (expr_df .columns ),
786793 show = False ,
787794 plot_type = "violin" ,
@@ -793,6 +800,12 @@ def explain(
793800 plt .show ()
794801 plt .clf ()
795802
803+ # SHAP registers forward/backward hook tensors as nn.Parameter on each
804+ # module. Remove them so state_dict() stays clean for save/load.
805+ for module in self .modules ():
806+ module ._parameters .pop ("x" , None )
807+ module ._parameters .pop ("y" , None )
808+
796809 # ------------------------------------------------------------------ #
797810 # Utilities
798811 # ------------------------------------------------------------------ #
0 commit comments