
    i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
Jr  SSKr " S S\R                  5      r0 rS&S\S\4S	 jjr\S
:X  Ga  \" S5        \" S5        \" S5        \" S5        \" SSS/SS9r\" S5        \" \R*                  5        \" S\" S \R/                  5        5       5       35        \" S5       H  r\" \SS9u  rr\" \SS9u  rr\R<                  R>                  RA                  \\5      r!\R<                  R>                  RA                  \\5      r"\R<                  R>                  RG                  \!SSS9r$\R<                  R>                  RG                  \"SS9r%\%\\'   \RM                  \$\%\SS9  M     \" S5        \" S5        \" S5        \" S 5        \" S!5        \" S"5        \" S#5        \" S$5        \" S%5        gg)'z
REAL Continual Learning - Neural networks that learn without forgetting
Uses Elastic Weight Consolidation (EWC) to prevent catastrophic forgetting
    N)ListTupleDictc                      ^  \ rS rSrSrS\S\\   S\4U 4S jjrS rS r	S	 r
S
 rSS\S\4S jjrS\\\4   S\4S jrSrU =r$ )ContinualLearner   z
A neural network that can learn multiple tasks sequentially without forgetting.
Uses EWC (Elastic Weight Consolidation) to maintain knowledge.

input_sizehidden_sizesoutput_sizec                   > [         TU ]  5         / nUnU HN  nUR                  [        R                  " XV5      5        UR                  [        R
                  " 5       5        UnMP     UR                  [        R                  " XS5      5        [        R                  " U6 U l        0 U l        0 U l	        SU l
        SU l        / U l        g )N  r   )super__init__appendnnLinearReLU
Sequentialnetworkfisher_informationoptimal_params
ewc_lambdatasks_learnedtask_performance)selfr	   r
   r   layers	prev_sizehidden_size	__class__s          ]/home/james-whalen/eden-agi-project/real_capabilities/learning/continual/continual_learner.pyr   ContinualLearner.__init__   s     	'KMM"))I;<MM"'')$#I (
 	bii	78}}f- #%   "    c                 $    U R                  U5      $ N)r   )r   xs     r    forwardContinualLearner.forward*   s    ||Ar"   c                 8   U R                  5         U R                  5        VVs0 s H  u  p4U[        R                  " U5      _M     nnnU H  u  pgU R	                  5         U " U5      n[
        R                  R                  X5      n	U	R                  5         U R                  5        H9  u  p4UR                  c  M  XS==   UR                  R                  S5      -  ss'   M;     M     U H  nXS==   [        U5      -  ss'   M     XPR                  U'   gs  snnf )zK
Compute Fisher Information Matrix - measures importance of each parameter
N   )evalnamed_parameterstorch
zeros_like	zero_gradr   
functionalcross_entropybackwardgradpowlenr   )
r   
dataloadertask_idnameparamfisherinputstargetsoutputslosss
             r    compute_fisher_information+ContinualLearner.compute_fisher_information-   s     			CGCXCXCZ[CZKD$((//CZ[)OFNN6lG==..w@DMMO  $446::)LEJJNN1$55L  7  * DLC
O+L  ,2(# \s   #Dc                     U R                  5        VVs0 s H#  u  p#X#R                  5       R                  5       _M%     snnU R                  U'   gs  snnf )z0Save current parameters as optimal for this taskN)r+   clonedetachr   )r   r6   r7   r8   s       r    save_optimal_params$ContinualLearner.save_optimal_paramsE   sN      $446(
6 ++-&&((6(
G$ (
s   *Ac                 J   Sn[        U R                  5       Hz  nU R                  5        Hc  u  p4X0R                  U   ;   d  M  U R                  U   U   nU R                  U   U   nXXF-
  R                  S5      -  R                  5       -  nMe     M|     U R                  U-  $ )z>
Compute EWC penalty - prevents changing important parameters
r   r)   )ranger   r+   r   r   r3   sumr   )r   r=   r6   r7   r8   r9   optimals          r    ewc_lossContinualLearner.ewc_lossL   s     T//0G#446227;;!44W=dCF"11':4@Gu&;&;A&>>CCEED	  7 1 %%r"   r6   epochsc                    [        SS 35        [        SU 35        [        S 5        [        R                  " U R                  5       SS9n[	        U5       GH<  nU R                  5         SnSnSn	U H  u  pUR                  5         U " U
5      n[        R                  R                  X5      nU R                  S:  a  U R                  5       OSnX-   nUR                  5         UR                  5         XR                  5       -  nUR                  S5      u  nnXR!                  S5      -  n	UUR#                  U5      R%                  5       R                  5       -  nM     SU-  U	-  n[        S	US-    S
U SU['        U5      -  S SUS S3	5        GM?     U R)                  X5        U R+                  U5        U R-                  [.        U5        U =R                  S-  sl
        g)zB
Train on a new task while preserving knowledge of previous tasks

<============================================================zTraining on Task gMbP?)lrr            Y@zEpoch /z	 - Loss: z.4fz - Acc: .2f%N)printoptimAdam
parametersrF   trainr.   r   r/   r0   r   rI   r1   stepitemmaxsizeeqrG   r4   r>   rC   evaluate_all_taskstest_loaders_history)r   train_loadertest_loaderr6   rK   	optimizerepoch
total_losscorrecttotalr:   r;   r<   	task_lossewc_penaltyr=   _	predictedaccuracys                      r    
train_taskContinualLearner.train_taskZ   s    	6(m!'+,JJt0U;	6]EJJLJGE#/##% v, MM77I	 261C1Ca1GdmmoQ !.  iik)
&{{1~9a(9<<0446;;==- $00 g~-HF57)1VHIj\AR6RSV5WW_`hil_mmnop? #D 	''>  ) 	 4g>ar"   test_loaderscurrent_taskc           	         [        SS 35        [        SU 35        [        S 5        U R                  5         0 n[        R                  " 5          [	        US-   5       H  nXA;   d  M
  SnSnX    Hb  u  pxU " U5      n	U	R                  S5      u  pXhR                  S5      -  nX[R                  U5      R                  5       R                  5       -  nMd     SU-  U-  nXU'   [        SU SUS	 S
35        M     SSS5        U R                  R                  U5        US:  a  [        UR                  5       5      [        U5      -  n[        SUS	 S
35        [        U R                  5      S:  ae  / n[	        U5       H-  nU R                  U   U   nX4   nUR                  UU-
  5        M/     [        U5      [        U5      -  n[        SUS	 S
35        [        S S35        U$ ! , (       d  f       N= f)zU
Evaluate performance on all tasks learned so far
Shows if the network is forgetting
rM   rN   z Performance After Learning Task rP   r   rQ   zTask z: rS   rT   Nz
Average Accuracy: zAverage Forgetting: )rU   r*   r,   no_gradrF   r\   r]   r^   rG   r[   r   r   valuesr4   )r   ro   rp   task_accuraciesr6   rf   rg   r:   r;   r<   rj   rk   rl   avg_accuracy
forgettingold_accnew_accavg_forgettings                     r    r_   #ContinualLearner.evaluate_all_tasks   s   
 	6(m0?@		]]_ !12*GE+7+@"&v,'.{{1~a0<<#8#<#<#>#C#C#EE	 ,A  $g~5H/7G,E'"XcN!<= 3   	$$_5 !55783;OOL(c(:!<= 4(()A-
$\2G"33G<WEG-6G%%g&78  3
 "%Z3z?!B,^C,@BCmI _s   G&)BG&&
G4)r   r   r   r   r   r   )
   )__name__
__module____qualname____firstlineno____doc__intr   r   r&   r>   rC   rI   rm   r   anyr_   __static_attributes____classcell__)r   s   @r    r   r      sn    
#3 #d3i #c #020
&2 S 2 # 2 h0tCH~ 0S 0 0r"   r   r   r6   	n_samplesc                    [         R                  R                  U S-  5        U S:X  aJ  [         R                  R                  US5      nUSS2S4   USS2S4   -   S:  R	                  [
        5      nOU S:X  aJ  [         R                  R                  US5      nUSS2S4   USS2S4   -
  S:  R	                  [
        5      nOU S:X  aM  [         R                  R                  US5      nUSS2S4   S:  USS2S4   S:  :g  R	                  [
        5      nOB[         R                  R                  US5      nUSS2U S-  4   S:  R	                  [
        5      n[        R                  " U5      [        R                  " U5      4$ )zF
Create synthetic task data - different tasks have different patterns
d   r   r{   NrP   r)      )	nprandomseedrandnastyper   r,   FloatTensor
LongTensor)r6   r   Xys       r    create_task_datar      sC    IINN7S=!!|IIOOIr*q!tWqAw"**3/	AIIOOIr*q!tWqAw"**3/	AIIOOIr*1gkqAw{+33C8 IIOOIr*q'B,!#++C0Q!1!1!!444r"   __main__z=
============================================================zREAL CONTINUAL LEARNING TESTzTraining on 3 sequential tasksrN   r{   @       r)   )r	   r
   r   z
Network Architecture:zTotal Parameters: c              #   @   #    U  H  oR                  5       v   M     g 7fr$   )numel).0ps     r    	<genexpr>r      s     "K6J77996Js   r   )r      T)
batch_sizeshuffle)r      )rK   zCONTINUAL LEARNING COMPLETEu   
✅ This is REAL learning:z(   - Neural network with backpropagationz1   - Learns without catastrophic forgetting (EWC)z(   - Measurable performance on each taskz%   - Preserves knowledge across tasksz
NOT just appending to a list!)r   )'r   r,   torch.nnr   torch.optimrV   numpyr   typingr   r   r   copyModuler   r`   r   r   r|   rU   learnerr   rG   rX   rF   r6   X_trainy_trainX_testy_testutilsdataTensorDatasettrain_datasettest_dataset
DataLoaderra   rb   rm    r"   r    <module>r      s       $ $ rryy rl  5c 5c 5: z	-	
()	
*+	&M "XG 
#%	'//	s"Kg6H6H6J"KKL
MN 8+GtD)'SA((66wH{{''55ffE{{''22=RY]2^kk&&11,21N(3W% 	<gbI   
-	
'(	&M	
()	
45	
=>	
45	
12	
+,U r"   