
     h              	          S r SSKrSSKJr  SSKJr  SSKrSSKJ	r	J
r
   " S S\R                  5      r " S S\R                  5      rS&S
 jr  S'S jrS(S jr\S:X  Ga  \" S5        \" S5        \" S5        \" SSS/SS9r\" S\R(                  R*                   35        \" \SSSS9  \" S5        \" S5        \" S5        \" SSSS9u  rr\" \\\SSSS9  \" SS	SS9u  rr\R5                  5         \R6                  " 5          \" \5      r\R;                  S S!9r\\:H  R?                  5       RA                  5       RC                  5       S-  r"SSS5        \" S"\"S# S$35        \" S%5        gg! , (       d  f       N%= f))zv
Transfer Learning - Reuse learned features for new tasks
Core idea: Features learned on Task A are useful for Task B
    N)ListTuplec                   D   ^  \ rS rSrSrS\S\\   4U 4S jjrS rSr	U =r
$ )FeatureExtractor   zS
Pre-trainable feature extractor
Learn general features that transfer across tasks

input_sizefeature_sizesc                 X  > [         TU ]  5         / nUnU Hs  nUR                  [        R                  " XE5      5        UR                  [        R
                  " 5       5        UR                  [        R                  " U5      5        UnMu     [        R                  " U6 U l        X@l	        g N)
super__init__appendnnLinearReLUBatchNorm1d
Sequentialfeaturesfeature_dim)selfr   r	   layers	prev_sizefeature_size	__class__s         [/home/james-whalen/eden-agi-project/real_capabilities/learning/transfer/transfer_learner.pyr   FeatureExtractor.__init__   s{    	)LMM"))I<=MM"'')$MM"..67$I	 * v.$    c                 $    U R                  U5      $ r   )r   r   xs     r   forwardFeatureExtractor.forward    s    }}Qr   )r   r   )__name__
__module____qualname____firstlineno____doc__intr   r   r!   __static_attributes____classcell__r   s   @r   r   r      s)    
%3 %tCy %   r   r   c                   t   ^  \ rS rSrSrSS/S4S\S\\   S\4U 4S	 jjjrS
 rS r	S r
S\4S jrS rSrU =r$ )TransferLearner#   zD
Transfer learning model with frozen/fine-tunable feature extractor
   @   
   r   r	   	n_classesc                    > [         TU ]  5         [        X5      U l        [        R
                  " U R                  R                  U5      U l        g r   )r   r   r   feature_extractorr   r   r   
classifier)r   r   r	   r2   r   s       r   r   TransferLearner.__init__(   s;     	!1*!L))D$:$:$F$F	Rr   c                 F    U R                  U5      nU R                  U5      $ r   )r4   r5   )r   r    r   s      r   r!   TransferLearner.forward3   s!    ))!,x((r   c                 T    U R                   R                  5        H
  nSUl        M     g)z.Freeze feature extractor for transfer learningFNr4   
parametersrequires_gradr   params     r   freeze_featuresTransferLearner.freeze_features7   s#    ++668E"'E 9r   c                 T    U R                   R                  5        H
  nSUl        M     g)zUnfreeze for fine-tuningTNr:   r=   s     r   unfreeze_features!TransferLearner.unfreeze_features<   s#    ++668E"&E 9r   c                 d    [         R                  " U R                  R                  U5      U l        g)z$Replace classifier head for new taskN)r   r   r4   r   r5   )r   r2   s     r   replace_classifier"TransferLearner.replace_classifierA   s     ))D$:$:$F$F	Rr   c                     [         R                  " 5          U R                  U5      sSSS5        $ ! , (       d  f       g= f)zGet feature representationsN)torchno_gradr4   r   s     r   extract_features TransferLearner.extract_featuresE   s#    ]]_))!, __s   1
?)r5   r4   )r#   r$   r%   r&   r'   r(   r   r   r!   r?   rB   rE   rJ   r)   r*   r+   s   @r   r-   r-   #   sj     %(9		S	S Cy	S 		S 	S)(
'
SC S- -r   r-      2   c                    [        S5        [        S5        [        SU SU SU 35        [        S5        [        R                  " U R                  5       SS9n[	        U5       GH  nS	nS	nS	n[	        U5       H  n	[        XS
S9u  pUR                  5         U " U
5      n[        R                  R                  X5      nUR                  5         UR                  5         XmR                  5       -  nUR                  SS9nX~U:H  R                  5       R                  5       -  nU[        U5      -  nM     US-   S-  S	:X  d  M  Xa-  nSU-  U-  n[        SUS-    SU SUS SUS S3	5        GM     [        S5        [        S5        g)zY
Pre-train feature extractor on multiple source tasks
This creates transferable features
G
======================================================================z.PRE-TRAINING FEATURE EXTRACTOR ON SOURCE TASKSzTasks: z | Samples per task: z | Epochs: F======================================================================gMbP?lrr   rL   )r      dimr1         Y@Epoch /z	 - Loss: z.4f - Acc: .2f%u   
✅ Pre-training complete!z9   Feature extractor now has transferable representationsN)printoptimAdamr;   rangegenerate_task_data	zero_gradr   
functionalcross_entropybackwardstepitemargmaxsumlen)modeln_taskssamples_per_taskepochs	optimizerepoch
total_losstotal_correcttotal_samplestask_idXyoutputslosspredavg_lossaccuracys                    r   pretrain_on_source_tasksr{   J   s   
 
-	
:;	GG912B1C;vh
WX	&M

5++-%8Iv
 W~G%gBODA !AhG==..w:D MMONN ))+%J>>a>(Dai__.3355MSV#M# && AIq !+Hm+m;HF57)1VHIhs^8HUX>YZ[\9 < 

()	
EFr   Tc           
      2   [        S5        [        S5        [        SU SU 35        [        S5        U R                  U5        U(       a  U R                  5         [        S5        O[        S5        [        R                  " U R                  5        Vs/ s H  ofR                  (       d  M  UPM     snSS	9n[        R                  R                  R                  X5      n[        R                  R                  R                  US
SS9n	[        U5       H  n
SnSnSnU	 H  u  pUR                  5         U " U5      n[        R                  R!                  UU5      nUR#                  5         UR%                  5         UUR'                  5       -  nUR)                  SS9nUUU:H  R+                  5       R'                  5       -  nU[-        U5      -  nM     U
S-   S-  S:X  d  M  SU-  U-  n[        SU
S-    SU SUS S35        M     [        S5        gs  snf )z/
Transfer to new target task with few examples
rO   z TRANSFER LEARNING TO TARGET TASKzTarget classes: z | Freeze features: rP   z-   Features frozen - training classifier onlyz   Fine-tuning all parametersg{Gz?rQ       T)
batch_sizeshuffler   rS   rT      rV   rW   rX   rY   rZ   r[   u    
✅ Transfer learning complete!N)r\   rE   r?   r]   r^   r;   r<   rH   utilsdataTensorDataset
DataLoaderr_   ra   r   rb   rc   rd   re   rf   rg   rh   ri   )rj   target_Xtarget_yn_classes_targetr?   fine_tune_epochsprn   datasetloaderro   rp   correcttotalinputstargetsrv   rw   rx   rz   s                       r   transfer_to_target_taskr   w   s    
-	,.	-..B?BS
TU	&M 
-.=>-. 

$$&:&q//&:I
 kk,,X@G[[((R(NF'(
%OF!FmG==..w@DMMONN$))+%J>>a>(D,,.3355GS\!E  & AI?ag~-HF57)1%5$6hxnANO' )* 

-.9 	;s   H,Hr1   c                 @   [         R                  R                  U S-  5        [         R                  R                  X#5      n[         R                  R                  X5      nXT-  nUR	                  SS9n[
        R                  " U5      [
        R                  " U5      4$ )zGenerate synthetic task datad   rS   )axis)nprandomseedrandnrg   rH   FloatTensor
LongTensor)rs   	n_samplesr   r2   Wrt   logitsru   s           r   r`   r`      sv    IINN7S=! 			
.A 				.AUF1AQ!1!1!!444r   __main__rO   zTRANSFER LEARNING TESTrP   r/   r0   )r   r	   r2   z
Model created - Feature dim: i     )rk   rl   rm   zTESTING TRANSFER TO NEW TASKi  r   r   )r   r2   )r   r?   r   rS   rT   z
Test Accuracy: rZ   r[   u+   
✅ Transfer learning implementation ready)rL   i  rM   )TrL   )rL   r1   )#r'   rH   torch.nnr   torch.optimr]   numpyr   typingr   r   Moduler   r-   r{   r   r`   r#   r\   rj   r4   r   r   r   test_Xtest_yevalrI   rv   rg   rx   floatmeanrf   rz    r   r   <module>r      s        ryy  0%-bii %-N+Gd 7/r5 z	-	
"#	&M r#rbQE	+E,C,C,O,O+P
QR UBRP 
-	
()	&M+C3!LHhE8X[_rtu (rQGNFF	JJL	-~~!~$FN))+002779C? 

 
hs^1
-.	
89; . 
s   A
E..
E<