
    Ąi                          d dl Z G d d      Zy)    Nc                   .    e Zd ZdZddZd ZddZd	dZy)
StabilityAnalyzera  
    Measures prediction stability across perturbations.
    
    Core principle: What doesn't break is an emergent truth.
    If a classifier gives consistent predictions on perturbed versions
    of the same input, that prediction is "stable" and likely correct.
    c                 .    || _         || _        || _        y)z
        Args:
            classifier: MLPClassifier instance with predict() and forward()
            n_perturbations: Number of perturbed samples per input
            noise_level: Standard deviation of Gaussian noise
        N)
classifiern_perturbationsnoise_level)selfr   r   r   s       ?/home/per/Documents/python/state to state/stability_analyzer.py__init__zStabilityAnalyzer.__init__   s     %.&    c                 *   |j                   d   }t        j                  || j                  ft              }t        j                  || j                  df      }t        | j                        D ]~  }|t        j                  j                  |j                    | j                  z  z   }| j                  j                  |      }| j                  j                  |      |dd|f<   ||dd|f<    t        j                  |t              }t        j                  |      }	t        |      D ]L  }
t        j                  ||
   d      }t        j                  |      ||
<   |||
      | j                  z  |	|
<   N t        j                  |d      }|	||fS )aW  
        Measure how stable predictions are for input X under noise.
        
        Returns:
            stability_scores: Array [batch_size] - fraction of consistent predictions
            predicted_labels: Array [batch_size] - most common prediction
            confidence: Array [batch_size, n_classes] - prediction distribution
        r   )dtype
   N)	minlength   )axis)shapenpzerosr   intrangerandomrandnr   r   forwardpredictbincountargmaxmean)r	   X
batch_sizeall_predictionsall_probabilitiesiX_perturbedprobsmode_predictionsstability_scoresjcounts
confidences                r
   measure_stabilityz#StabilityAnalyzer.measure_stability   sk    WWQZ
((J0D0D#ESQHHj$2F2F%KLt++, 	,Abiiooqww7$:J:JJJKOO++K8E$(OO$;$;K$HOAqD!&+ad#		, 88Jc:88J/z" 	UA[[!3rBF"$))F"3Q"()9!)<"=@T@T"TQ	U WW.Q7
!1:==r   c                 ^    | j                  |      \  }}}||k\  }|||   ||   ||   ||   dS )z
        Find samples where predictions are highly stable.
        
        Returns:
            stable_mask: Boolean mask of stable samples
            stable_X: Stable input samples
            stable_labels: Their emergent truth labels
        )maskr   labels	stabilityr*   )r+   )r	   r   	thresholdr'   predictionsr*   stable_masks          r
   find_stable_samplesz%StabilityAnalyzer.find_stable_samples9   sT     594J4J14M1+z&)3  ;!+.)+6$[1
 	
r   c                 6   |j                   d   dk  ryg }t        t        t        |      dz
  d            D ]  }||   ||dz      }}t	        j
                  dd|      ddt        j                  f   }|t        j                  ddf   d|z
  z  |t        j                  ddf   |z  z   }| j                  j                  |      }	t	        j                  |	dd |	dd k7        }
d|
|dz
  z  z
  }|j                  |        |rt	        j                  |      S dS )	z
        Analyze decision boundary stability by interpolating between samples.
        
        Returns:
            boundary_stability: How stable predictions are near boundaries
        r      g        r   r   Ng      ?)r   r   minlenr   linspacenewaxisr   r   sumappendr   )r	   r   n_stepsstabilitiesr#   x1x2interpolationX_interppredstransitionsr/   s               r
   analyze_decision_boundariesz-StabilityAnalyzer.analyze_decision_boundariesM   s    771:>s3q6A:r*+ 
	*AqT1QU8BKK1g6q"**}EM"**a-(A,=>BJJPQMARUbAbbHOO++H5E&&suQRy!89K{gk:;Iy)
	* (3rww{#;;r   N)   g?)g?)2   )__name__
__module____qualname____doc__r   r+   r3   rE    r   r
   r   r      s    	'>B
(<r   r   )numpyr   r   rL   r   r
   <module>rN      s    a< a<r   