
    tiT                         d Z ddlZddlmZmZmZmZ ddlm	Z	m
Z
mZ ddlmZmZ ddlmZ ddlmZ ddlmZmZmZ ddlZd	d
lmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z# d	dl$m%Z%m&Z&m'Z'  G d de	e
      Z( G d de	e      Z)y)zX
ConvMLP Models
==============
Conv2D-integrated MLPClassifier compatible with sklearn.
    N)ListTupleOptionalUnion)BaseEstimatorClassifierMixinRegressorMixin)MLPClassifierMLPRegressor)LabelEncoder)unique_labels)	check_X_ycheck_arraycheck_is_fitted   )Conv2D	MaxPool2D	AvgPool2DFlatten	Dropout2DBatchNorm2DGlobalAvgPool2DReLUSigmoidTanhSoftmax)im2colcol2imcalculate_receptive_fieldc                       e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 d'deee      deee      dededede	d	e	d
e	de
de
de	dee   de
deeedf      fdZdeedf   fdZdej                  dej                  fdZdedefdZd(dej                  de
dej                  fdZd(dej                  de
fdZdej                  dej                  fdZdej                  dej                  fd Zd)dej                  dej                  fd!Zdej                  dej                  fd"Zdej                  dej                  fd#Zdej                  dej                  de	fd$Zdefd%Zd& Zy)*ConvMLPClassifieraN  
    Convolutional MLP Classifier with sklearn compatibility.
    
    Combines Conv2D layers with MLPClassifier backend for end-to-end training.
    
    Parameters
    ----------
    conv_layers : list, optional
        List of convolutional layer configurations.
        Each config is a dict with keys: type, filters, kernel_size, etc.
    mlp_layers : list, optional
        Hidden layer sizes for the MLP backend.
    conv_method : str, default='im2col'
        Convolution method: 'im2col', 'fft', 'winograd', 'direct'.
    max_iter : int, default=100
        Maximum number of iterations.
    batch_size : int, default=32
        Mini-batch size.
    learning_rate : float, default=0.001
        Initial learning rate.
    momentum : float, default=0.9
        Momentum for SGD.
    random_state : int, optional
        Random seed.
    verbose : bool, default=False
        Print training progress.
    
    Example
    -------
    >>> model = ConvMLPClassifier(
    ...     conv_layers=[
    ...         {'type': 'conv2d', 'filters': 32, 'kernel_size': 3},
    ...         {'type': 'maxpool2d', 'pool_size': 2},
    ...         {'type': 'conv2d', 'filters': 64, 'kernel_size': 3},
    ...     ],
    ...     mlp_layers=[128, 64],
    ...     max_iter=50
    ... )
    >>> model.fit(X_train, y_train)
    >>> predictions = model.predict(X_test)
    Nconv_layers
mlp_layersconv_methodmax_iter
batch_sizelearning_ratelearning_rate_initmomentumnesterov_momentumearly_stoppingvalidation_fractionrandom_stateverboseinput_shape.c                 N   |xs ddddddddd	dd
ddddddd	g| _         |xs dd
g| _        || _        || _        || _        || _        || _        || _        |	| _        |
| _	        || _
        || _        || _        || _        d | _        d | _        d | _        d | _        d| _        y Nconv2d       samerelu)typefilterskernel_sizepadding
activation	maxpool2d   )r7   	pool_size@      F)r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   	_conv_net_mlp_label_encoder_input_size_built)selfr"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   s                  </home/per/Documents/sklearn ConvMLP module/convmlp/models.py__init__zConvMLPClassifier.__init__B   s    " ' 
"Q6agh q1"Q6agh q1	+
 %1b	& $*"4 !2,#6 (& 	"    c                    g | _         |}| j                  D ]  }|j                  dd      }|dk(  rqt        |d   |j                  dd      |j                  dd      |j                  dd	      |j                  d
d      |j                  dd      | j                        }n|dk(  r>t        |j                  dd      |j                  d      |j                  dd            }n|dk(  r>t        |j                  dd      |j                  d      |j                  dd            }n|dk(  rt               }n|dk(  rt               }no|dk(  rt        |j                  dd            }nM|dk(  r.t        |j                  dd      |j                  dd             }nt        j                  d!|        |j                  s|j                  |      }nt        |d"|      }| j                   j!                  |        |S )#z3Build the convolutional network from configuration.r7   r2   r8   r9   r4   stridesr   r:   r5   r;   r6   use_biasTr8   r9   rK   r:   r;   rL   methodr<   r>   r=   r   r>   rK   r:   	avgpool2dglobal_avgpoolflattendropoutrate      ?rT   	batchnormr)   ?epsilongh㈵>)r)   rY   zUnknown layer type: output_shape)rA   r"   getr   r$   r   r   r   r   r   r   warningswarnbuiltbuildgetattrappendrF   r/   current_shapelayer_config
layer_typelayers         rG   _build_conv_layersz$ConvMLPClassifier._build_conv_layersn   s   # ,, -	)L%))&(;JX%(3 , 0 0 B(,,Y:(,,Y?+//fE)--j$?++ {*!*..{A>(,,Y7(,,Y:
 {*!*..{A>(,,Y7(,,Y:
 //')y(	y(!|'7'7'DE{*#)--j#>(,,Y=
  4ZLAB;; %M : '~} MNN!!%([-	)^ rI   Xreturnc                     |j                   d   }| j                  rp|f| j                  z   }|j                   |k(  r!|j                  t        j                  d      S |j                  |      j                  t        j                  d      S |j                   d   }dd|fdd|dz  f|ddfg}|D ]F  \  }}}||z  |z  |k(  s|j                  ||||      j                  t        j                  d      c S  t        t        j                  |            }	|	|	z  |k(  r3|j                  |d|	|	      j                  t        j                  d      S |j                  ||j                   d   dd      j                  t        j                  d      S )2Reshape input to (batch, channels, height, width).r   Fcopyr   r4   shaper/   astypenpfloat32reshapeintsqrt)
rF   rh   	n_samplesexpected
total_size
candidateschwsizes
             rG   _reshape_inputz ConvMLPClassifier._reshape_input   sy   GGAJ	!|d&6&66Hww("xx

x77yy*11"**51II WWQZ
 ::?#A

 " 	TGAq!1uqyJ&yyAq!4;;BJJU;SS	T
 277:&'$;*$99Y46==bjju=UU yyAGGAJ26==bjju=UUrI   rw   c                     | j                   dv rt        d|      S t        dt        t        | j                         |            S )z7Return the batch size used for conv feature extraction.Nautor3   r   r&   minmaxru   rF   rw   s     rG   _feature_batch_sizez%ConvMLPClassifier._feature_batch_size   s8    ??n,r9%%1c#doo.	:;;rI   X_batchtrainingc                     |}| j                   D ]  }|j                  ||      } t        |j                        dkD  r|j	                  |j                  d   d      S |S )zARun a single batch through the conv stack and flatten the result.r   r=   r   rn   )rA   forwardlenrp   rt   rF   r   r   X_convrf   s        rG   _transform_conv_batchz'ConvMLPClassifier._transform_conv_batch   s[    ^^ 	>E]]6H]=F	>v||q >>&,,q/266rI   c              #      K   | j                  |j                  d         }t        d|j                  d   |      D ]6  }t        ||z   |j                  d         }| j	                  ||| |       8 yw)z-Yield flattened conv features batch by batch.r   r   Nr   rp   ranger   r   rF   rh   r   r&   startstops         rG   _iter_conv_featuresz%ConvMLPClassifier._iter_conv_features   su     --aggaj9
1aggaj*5 	OEuz)1771:6D,,QuT]X,NN	O   A3A5classesc                    t               | _        | j                  j                  |       |j                  dd | _        | j                  | j                        }t        |      dkD  rt        j                  |dd       | _	        n
|d   | _	        | j                  r0t        d|j                          t        d| j                          t        t        | j                        ddd	| j                  | j                   dd
| j"                  | j$                  | j&                  | j(                  | j                        | _        y)zIInitialize encoder, conv stack, and MLP backend for incremental training.r   Nr=   rn   zInput shape: zMLP input size: r6   adamg-C6?T)hidden_layer_sizesr;   solveralphar&   r(   r%   shuffler-   r+   r,   nesterovs_momentumr.   )r   rC   fitrp   rD   rg   r   rr   prod_mlp_input_sizer.   printr
   listr#   r&   r(   r-   r+   r,   r*   rB   )rF   rh   r   conv_output_shapes       rG   _initialize_classifierz(ConvMLPClassifier._initialize_classifier   s   *n(7712; 33D4D4DE !A%#%77+<QR+@#AD #4R#8D <<M!''+,$T%9%9$:;<!#DOO4#66**.. $ 8 8#55LL
	rI   yc                    | j                   )t        j                  j                  | j                          t	        ||d      \  }}|j
                  d   }| j                  |      }t        |      }| j                  ||       | j                  j                  |      }| j                  |j
                  d         }| j                  rt        d|        t        | j                        D ]  }t        d|j
                  d   |      D ]q  }t!        ||z   |j
                  d         }	| j#                  |||	 d      }
| j$                  j'                  |
|||	 t        j(                  t+        |                   s  d| _        || _        | S )	ag  
        Fit the model to data matrices X and target y.
        
        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Training data.
        y : array-like of shape (n_samples,)
            Target values.
        
        Returns
        -------
        self : object
            Fitted estimator.
        Fmulti_outputr   r   zFeature batch size: Tr   r   )r-   rr   randomseedr   rp   r   r   r   rC   	transformr   r.   r   r   r%   r   r   rB   partial_fitaranger   rE   _n_features_in_)rF   rh   r   n_input_featuresr   	y_encodedr&   _r   r   X_flats              rG   r   zConvMLPClassifier.fit   so   " (IINN4,,- AE21771: ""##Aw/''11!4	--aggaj9
<<(56t}}% 	fAq!''!*j9 f5:-qwwqz:33AeDMD3Q		%%fid.CRYYWZ[bWcMd%ef	f /rI   c                    | j                   5| j                  s)t        j                  j	                  | j                          t        ||d      \  }}|j                  d   }| j                  |      }| j                  s<|t        |      }t        j                  |      }| j                  ||       d| _        n|Jt        j                  |      }t        j                  || j                  j                        s]t        d      t        j                  t        j                   t        |      | j                  j                               rt        d      | j                  j#                  |      }t        j$                  t'        | j                  j                              }| j)                  |d      D ]9  }|j                  d	   }|d| }	||d }| j*                  j-                  ||	|
       ; || _        | S )z2Incrementally fit the model on a batch of samples.NFr   r   TzA`classes` must match the classes from the first partial_fit call.zINew classes found in `y`. Pass all classes in the first partial_fit call.r   r   r   )r-   rE   rr   r   r   r   rp   r   r   asarrayr   array_equalrC   classes_
ValueErroranyisinr   r   r   r   rB   r   r   )
rF   rh   r   r   r   r   encoded_classesr   	batch_leny_batchs
             rG   r   zConvMLPClassifier.partial_fit+  s   (IINN4,,-AE21771:"{{'*jj)G''73DK"**W-~~gt/B/B/K/KL$%hiiq!143F3F3O3OPPQ !lmm''11!4	))C(;(;(D(D$EF..q4.@ 	LFQI
+G!)*-III!!&'?!K		L  0rI   c                 *   t        |        t        |      }| j                  |      }t        j                  | j                  |d      D cg c]  }| j                  j                  |       c}      }| j                  j                  |      S c c}w )a2  
        Predict class labels for samples in X.
        
        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Samples.
        
        Returns
        -------
        y : ndarray of shape (n_samples,)
            Class labels for samples in X.
        Fr   )
r   r   r   rr   concatenater   rB   predictrC   inverse_transform)rF   rh   r   y_preds       rG   r   zConvMLPClassifier.predictN  s     	N " 221u2E!
 IIf%!
  ""44V<<!
s   "Bc                     t        |        t        |      }| j                  |      }t        j                  | j                  |d      D cg c]  }| j                  j                  |       c}      S c c}w )z)Return probability estimates for samples.Fr   )r   r   r   rr   vstackr   rB   predict_proba)rF   rh   r   s      rG   r   zConvMLPClassifier.predict_probak  sr    N " yy221u2E
 II##F+
  	 
s   "A5c                 >    ddl m}  ||| j                  |            S )z;Return the mean accuracy on the given test data and labels.r   )accuracy_score)sklearn.metricsr   r   )rF   rh   r   r   s       rG   scorezConvMLPClassifier.scorey  s    2aa11rI   c                     | j                   S )z(Return the list of convolutional layers.)rA   )rF   s    rG   get_conv_layersz!ConvMLPClassifier.get_conv_layers~  s    ~~rI   c                       fd}|S )z>Return a function that extracts features from the conv layers.c                     j                  |       } j                  D ]  }|j                  | d      }  | j                  | j                  d   d      S )NFr   r   rn   )r   rA   r   rt   rp   )rh   rf   rF   s     rG   	extractorz:ConvMLPClassifier.get_feature_extractor.<locals>.extractor  sQ    ##A&A 5MM!eM4599QWWQZ,,rI    )rF   r   s   ` rG   get_feature_extractorz'ConvMLPClassifier.get_feature_extractor  s    	-
 rI   )NNr   d   r3   MbP?r   rX   TFg?NFNF)N)__name__
__module____qualname____doc__r   r   dictru   strfloatboolr   rH   rg   rr   ndarrayr   r   r   r   r   r   r   r   r   r   r   r   r   rI   rG   r!   r!      s*   (X -1*.#$$)"&$%(&*15*d4j)* T#Y'* 	*
 * * * "* *  * * #* sm* * eCHo.*X4eCHo 4l V

  Vrzz  VD<S <S <RZZ 4 TVT^T^ ORZZ O4 O


 
RZZ 
B,RZZ ,BJJ ,\!RZZ !BJJ !F= =

 =:rzz bjj 2rzz 2bjj 2U 2
 rI   r!   c                      e Zd ZdZ	 	 	 	 	 	 	 	 	 	 ddeee      deee      dededede	d	e	d
ee   de
deeedf      fdZdej                  dej                  fdZdedefdZddej                  de
dej                  fdZddej                  de
fdZdeedf   fdZdej                  dej                  fdZdej                  dej                  fdZdej                  dej                  de	fdZy)ConvMLPRegressorz
    Convolutional MLP Regressor with sklearn compatibility.
    
    Combines Conv2D layers with MLPRegressor backend.
    
    Parameters
    ----------
    (Same as ConvMLPClassifier, with target type regression instead of classification)
    Nr"   r#   r$   r%   r&   r(   r)   r-   r.   r/   .c                     |xs ddddddddd	dd
ddddg| _         |xs dd
g| _        || _        || _        || _        || _        || _        || _        |	| _        |
| _	        d | _
        d | _        d| _        y r1   )r"   r#   r$   r%   r&   r(   r)   r-   r.   r/   rA   rB   rE   )rF   r"   r#   r$   r%   r&   r(   r)   r-   r.   r/   s              rG   rH   zConvMLPRegressor.__init__  s     ' 
"Q6agh q1"Q6agh+

 %1b	& $"4 (&	rI   rh   ri   c                 h   |j                   d   }| j                  rp|f| j                  z   }|j                   |k(  r!|j                  t        j                  d      S |j                  |      j                  t        j                  d      S |j                   d   }t        t        j                  |            }||z  |k(  r3|j                  |d||      j                  t        j                  d      S |j                  ||j                   d   dd      j                  t        j                  d      S )rk   r   Frl   r   rn   ro   )rF   rh   rw   rx   ry   r~   s         rG   r   zConvMLPRegressor._reshape_input  s    GGAJ	!|d&6&66Hww("xx

x77yy*11"**51IIWWQZ
277:&'$;*$99Y46==bjju=UUyyAGGAJ26==bjju=UUrI   rw   c                     | j                   dv rt        d|      S t        dt        t        | j                         |            S )Nr   r3   r   r   r   s     rG   r   z$ConvMLPRegressor._feature_batch_size  s8    ??n,r9%%1c#doo.	:;;rI   r   r   c                     |}| j                   D ]  }|j                  ||      } |j                  |j                  d   d      S )Nr   r   rn   )rA   r   rt   rp   r   s        rG   r   z&ConvMLPRegressor._transform_conv_batch  sE    ^^ 	>E]]6H]=F	>~~fll1or22rI   c              #      K   | j                  |j                  d         }t        d|j                  d   |      D ]6  }t        ||z   |j                  d         }| j	                  ||| |       8 y w)Nr   r   r   r   s         rG   r   z$ConvMLPRegressor._iter_conv_features  su     --aggaj9
1aggaj*5 	OEuz)1771:6D,,QuT]X,NN	Or   c                 L   g | _         |}| j                  D ]  }|j                  dd      }|dk(  rpt        |d   |j                  dd      |j                  dd      |j                  dd	      |j                  d
d      |j                  dd      | j                        }n|dk(  r>t        |j                  dd      |j                  d      |j                  dd            }nw|dk(  r>t        |j                  dd      |j                  d      |j                  dd            }n4|dk(  rt               }n$|dk(  rt        |j                  dd            }nE|j                  s|j                  |      }nt        |d|      }| j                   j                  |        |S )z Build the convolutional network.r7   r2   r8   r9   r4   rK   r   r:   r5   r;   r6   rL   TrM   r<   r>   r=   r   rO   rP   rR   rS   rT   rU   rV   rZ   )rA   r"   r[   r   r$   r   r   r   r   r^   r_   r`   ra   rb   s         rG   rg   z#ConvMLPRegressor._build_conv_layers  s   # ,, $	)L%))&(;JX%(3 , 0 0 B(,,Y:(,,Y?+//fE)--j$?++ {*!*..{A>(,,Y7(,,Y:
 {*!*..{A>(,,Y7(,,Y:
 y(	y(!|'7'7'DE;; %M : '~} MNN!!%(I$	)L rI   r   c           
         | j                   )t        j                  j                  | j                          t	        ||      \  }}|j
                  d   }| j                  |      }|j
                  dd | _        | j                  | j                        }t        |      dkD  rt        j                  |dd       | _        n
|d   | _        t        | j                        }t        |ddd| j                  | j                   | j                   | j"                        | _        | j'                  |j
                  d         }t)        | j*                        D ]r  }t)        d|j
                  d   |      D ]S  }t-        ||z   |j
                  d         }	| j/                  |||	 d	
      }
| j$                  j1                  |
|||	        U t d	| _        || _        | S )zFit the model.Nr   r=   rn   r6   r   )r   r;   r   r%   r&   r(   r-   r.   r   Tr   )r-   rr   r   r   r   rp   r   rD   rg   r   r   r   r   r#   r   r&   r(   r.   rB   r   r   r%   r   r   r   rE   r   )rF   rh   r   r   r   r#   r&   r   r   r   r   s              rG   r   zConvMLPRegressor.fit  s   (IINN4,,-A1771:"7712; 33D4D4DE !A%#%77+<QR+@#AD #4R#8D $//*
 )#66**LL	
	 --aggaj9
t}}% 	=Aq!''!*j9 =5:-qwwqz:33AeDMD3Q		%%fadm<=	= /rI   c                    t        |        t        |      }| j                  |      }| j                  |d      D cg c]  }| j                  j                  |       }}t        j                  |      j                         S c c}w )zPredict target values.Fr   )	r   r   r   r   rB   r   rr   r   rR   )rF   rh   r   predictionss       rG   r   zConvMLPRegressor.predict0  s    N" 221u2E
 IIf%
 
 ~~k*2244	
s   "Bc                 >    ddl m}  ||| j                  |            S )u   Return R² score.r   )r2_score)r   r   r   )rF   rh   r   r   s       rG   r   zConvMLPRegressor.score=  s    ,4<<?++rI   )
NNr   r   r3   r   rX   NFNr   )r   r   r   r   r   r   r   ru   r   r   r   r   rH   rr   r   r   r   r   r   rg   r   r   r   r   rI   rG   r   r     s    -1*.#$)&*15d4j) T#Y' 	
   "  sm  eCHo.@V

 Vrzz V$<S <S <
3RZZ 34 3TVT^T^ 3ORZZ O4 O+eCHo +Z'RZZ 'BJJ 'R5 5

 5,rzz ,bjj ,U ,rI   r   )*r   numpyrr   typingr   r   r   r   sklearn.baser   r   r	   sklearn.neural_networkr
   r   sklearn.preprocessingr   sklearn.utils.multiclassr   sklearn.utils.validationr   r   r   r\   layersr   r   r   r   r   r   r   r   r   r   r   utilsr   r   r   r!   r   r   rI   rG   <module>r      sj     / / G G > . 2 L L     = <r rjt,}n t,rI   