
    h:                        S r SSKrSSKJr  SSKJr  SSKJr   " S S\R                  5      r	 " S S\R                  5      r
SS jr\S	:X  a9  \" S
5        \" S5        \" S5        \" S5        \" S5        \" S5        \" S5        gg)z
Progressive Neural Networks - Add new columns for each task
Paper: "Progressive Neural Networks" (DeepMind, 2016)
Each task gets its own network column with lateral connections to previous columns
    N)Listc                   L   ^  \ rS rSrSrS\S\\   S\4U 4S jjrS	S jrSr	U =r
$ )
ProgressiveColumn   z$Single column in progressive network
input_sizehidden_sizesoutput_sizec                   > [         TU ]  5         [        R                  " 5       U l        UnU H4  nU R                  R                  [        R                  " XE5      5        UnM6     [        R                  " XC5      U l        g N)super__init__nn
ModuleListlayersappendLinearoutput_layer)selfr   r   r	   	prev_sizehidden_size	__class__s         \/home/james-whalen/eden-agi-project/real_capabilities/learning/continual/progressive_nets.pyr   ProgressiveColumn.__init__   s]    mmo	'KKKryy@A#I ( IIi=    c                    / n[        U R                  5       H^  u  pEU" U5      nU(       a#  U[        U5      :  a  X$    H  nUc  M  X-   nM     [        R                  " U5      nUR                  U5        M`     U R                  U5      nX4$ )zj
Forward pass with optional lateral connections
lateral_inputs: list of activations from previous columns
)	enumerater   lentorchrelur   r   )r   xlateral_inputsactivationsilayerlaterals          r   forwardProgressiveColumn.forward   s    
 !$++.HAaA !c.&9"9-0G*K  1 

1Aq! / a ~r   )r   r   r   )__name__
__module____qualname____firstlineno____doc__intr   r   r&   __static_attributes____classcell__r   s   @r   r   r      s.    .
>3 
>d3i 
>c 
> r   r   c                   X   ^  \ rS rSrSrS\S\\   S\4U 4S jjrS rS r	SS	 jr
S
rU =r$ )ProgressiveNeuralNetwork0   z~
Progressive Neural Network - grows new columns for each task
Previous columns are frozen, preventing catastrophic forgetting
r   r   r	   c                    > [         TU ]  5         Xl        X l        X0l        [
        R                  " 5       U l        [
        R                  " 5       U l        SU l	        / U l
        g )Nr   )r   r   r   r   r	   r   r   columnslateral_connectionscurrent_taskfrozen_columns)r   r   r   r	   r   s       r   r   !ProgressiveNeuralNetwork.__init__6   sJ    $(&}}#%==?  r   c                    [        U R                  U R                  U R                  5      nU R                  R                  U5        [        U R                  5      S:  a  [        U R                  5      n[        R                  " 5       n[        U5       H  n[        R                  " 5       n[        [        U R                  5      S-
  5       HE  n[        R                  " U R                  U   U R                  U   5      nUR                  U5        MG     UR                  U5        M     U R                  R                  U5        gg)zAdd new column for new task   N)r   r   r   r	   r5   r   r   r   r   ranger   r6   )r   
new_columnn_layersr%   	layer_idxlayer_lateralscol_idxadapters           r   
add_column#ProgressiveNeuralNetwork.add_columnC   s    &OO

 	J' t||q 4,,-HmmoG"8_	!#$S%6%:;G ii)))4)))4G #))'2  < ~. - $$++G4! !r   c                     [        [        U R                  5      S-
  5       HI  nU R                  U   R                  5        H
  nSUl        M     U R
                  R                  U5        MK     g)z$Freeze all columns except the newestr;   FN)r<   r   r5   
parametersrequires_gradr8   r   )r   r#   params      r   freeze_previous_columns0ProgressiveNeuralNetwork.freeze_previous_columns`   sV    s4<<(1,-Aa335&+# 6&&q) .r   c                 ,   Uc  [        U R                  5      S-
  nU[        U R                  5      :  a  [        SU S35      e/ nUS:  aX  [        U5       HI  n[        R
                  " 5          U R                  U   " U5      u  pVUR                  U5        SSS5        MK     SnUS:  a  US-
  [        U R                  5      :  a  / nU R                  US-
     n[        [        U R                  5      5       Hl  n	/ n
[        U5       HG  u  pU	[        U5      :  a"  X   U   " Xi   5      nU
R                  U5        M6  U
R                  S5        MI     UR                  U
5        Mn     U R                  U   " X5      u  pU$ ! , (       d  f       GM<  = f)zf
Forward pass through appropriate column
If task_id specified, use that column. Otherwise use latest.
Nr;   Task z not yet addedr   )
r   r5   
ValueErrorr<   r   no_gradr   r6   r   r   )r   r    task_idprevious_activationsprev_col_idx_	prev_actsr!   lateralsr?   layer_lateral_inputsrA   adaptedoutputs                 r   r&    ProgressiveNeuralNetwork.forwardg   st   
 ?$,,'!+Gc$,,''uWI^<==  "Q; %g]]_#'<<#=a#@LA(//	: %_ !/ Q;7Q;T-E-E)FFN//!<H"3t'8'8#9:	')$*34H*I&G 3y>1"*"5g">y?S"T,33G<,33D9 +J %%&:; ; LL)!<	- %_s   /)F
F	)r5   r7   r8   r   r   r6   r	   r   )r(   r)   r*   r+   r,   r-   r   r   rC   rI   r&   r.   r/   r0   s   @r   r2   r2   0   s:    
!3 !d3i !c !5:*% %r   r2   c                    [        SS 35        [        SU 35        [        S[        U R                  5       35        [        S[        U R                  5       35        [        S 5        [        R
                  " U R                  5        Vs/ s H  oUR                  (       d  M  UPM     sn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 " XS	9n[        R                  R                  X5      nUR                  5         UR                  5         XR!                  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US
-   S-  S:X  d  M  [        SUS
-    SU SU[        U5      -  S SUS S3	5        GM%     [        SS 35        [        SU 35        [        S 5        U R+                  5         [,        R.                  " 5          [        US
-   5       H  nUU;   d  M  Sn	Sn
UU    Hc  u  pU " UUS	9nUR#                  S
5      u  nnXR%                  S5      -  n
U	UR'                  U5      R)                  5       R!                  5       -  n	Me     SU	-  U
-  n[        SU SUS S35        M     SSS5        [        S S35        gs  snf ! , (       d  f       N"= f)z%Train progressive network on new task
<============================================================z$Training Progressive Network - Task zTotal Columns: zFrozen Columns: gMbP?)lrr   )rO   r;   g      Y@   zEpoch /z	 - Loss: z.4fz - Acc: z.2f%zPerformance After Task rL   z: N)printr   r5   r8   optimAdamrF   rG   r<   train	zero_gradr   
functionalcross_entropybackwardstepitemmaxsizeeqsumevalr   rN   )modeltrain_loadertest_loadersrO   epochsp	optimizerepoch
total_losscorrecttotalinputstargetsoutputslossrR   	predictedaccuracytids                      r   train_progressive_networkr      s   	Bvh-	0	
:;	OC./
01	S!5!567
89	VH 

$$&:&q//&:I
 v
+OF!F4G==..w@DMMONN))+%J";;q>LAy\\!_$Ey||G,0027799G  , '>E)AI?aF57)1VHIj\AR6RSV5WW_`hil_mmnop- 2 
Bvh-	#G9
-.	VH	JJL	1%Cl"'3C'8OF#FC8G#*;;q>LAy\\!_,Ey||G488:??AAG	 (9  '>E1cU"XcN!45 & 
 
VHB-c 	;D 
s   K0%K00K5
BK55
L__main__z=
============================================================z PROGRESSIVE NEURAL NETWORKS TESTr[   u$   
✅ Progressive columns implementedu'   ✅ Lateral connections between columnsu%   ✅ Automatic freezing of old columnsz%
Ready to integrate into full system!)   )r,   r   torch.nnr   torch.optimra   typingr   Moduler   r2   r   r(   r`    r   r   <module>r      s   
    #		 #J\ryy \|;z z	-	
,-	&M	
12	
34	
12	
23 r   