
    i                     p   d dl Z d dlmZ d dlmc mZ d dlmZ d dlm	Z	m
Z
 d dlZd dlmZ d dlmZmZ d dlmZmZmZmZmZ d dlmZ d dlZd dlZd dlmZ  ej<                  ej>                  d        ej@                  e!      Z" e jF                  e jH                  jK                         rd	nd
      Z#e"jM                  de#         G d de      Z'e G d d             Z(e G d d             Z)e G d d             Z* G d dejV                        Z, G d de,      Z- G d de,      Z. G d de,      Z/ G d de,      Z0 G d de,      Z1 G d  d!e,      Z2 G d" d#e,      Z3 G d$ d%e,      Z4 G d& d'e,      Z5 G d( d)e,      Z6 G d* d+e,      Z7 G d, d-e,      Z8 G d. d/ejV                        Z9 G d0 d1e,      Z: G d2 d3e,      Z; G d4 d5e,      Z< G d6 d7      Z= G d8 d9ejV                        Z> G d: d;ejV                        Z? G d< d=ejV                        Z@	 	 	 dd@e@dAe	dBe	dCeAdDeBdEeBfdFZCd@e@dGe	dHeBfdIZD	 dd@e@dJejV                  dAe	dCeAfdKZEe!dLk(  re"jM                  dM        ej                   ej                          ej                  dNdN      g      ZIej                  j                  dOdPdPeIQ      ZLej                  j                  dOdRdPeIQ      ZM e	eLdSdPdTU      ZN e	eMdSdRdTU      ZOe"jM                  dV ePeL              e"jM                  dW ePeM               e@dXdYdZdR[      j                  e#      ZReRj                  j                  j                  e#      ZTe"jM                  d\ eUd] eRj                         D              d^       e"jM                  d_ eUd` eTj                         D              d^        eWda        eWdb        eWdc        eCeReNeOdZd>d?d      ZX eWda        eWde        eWdc        eDeReO      ZYe"jM                  dfeYdg        eWdh        eZ e[eXdi   eXdj               D ]  \  Z\\  Z]Z^ eWdke\ dle]dgdme^dg         eWda        eWdn        eWdc        eWda        eWdo        eWdc       eRj                           e` eaeO            \  ZbZcebj                  e#      Zb e j                         5   eReb      Zeebj                  ebj                  d       dpdqdq      ZheRj                  j                  eh      Zj eWdr        ekejj                         ds dPt      D ]Z  \  ZmZnenj                  j                         dukD  s$ eWdvemdwdxenj                  j                         dgdyenj                  dzd{       \ 	 ddd        e j                  eRj                         eTj                          eteX      d|d}       e"jM                  d~        e j                  d}      ZveRj                  evd           eDeReO      Zxe"jM                  dexdg       yy# 1 sw Y   xY w)    N)
DataLoaderDataset)	dataclassfield)DictListTupleOptionalCallable)Enum)defaultdictz)%(asctime)s - %(levelname)s - %(message)s)levelformatcudacpuzUsing device: c                   (    e Zd ZdZdZdZdZdZdZdZ	y)	LossCategoryspatialspectralstatistical	componentpatternadversarialregularizationN)
__name__
__module____qualname__SPATIALSPECTRALSTATISTICAL	COMPONENTPATTERNADVERSARIALREGULARIZATION     err04.pyr   r      s%    GHKIGK%Nr&   r   c                   >    e Zd ZU eed<   eed<   dZeed<   dZe	ed<   y)
LossConfignamecategory      ?weightTenabledN)
r   r   r   str__annotations__r   r-   floatr.   boolr%   r&   r'   r)   r)   )   s!    
IFEGTr&   r)   c                   |    e Zd ZU eed<   ej                  ed<   ej                  ed<   eed<   eed<   e	ed<   e	ed<   y)	
LossResultr*   valuegradientdiagnosticsr+   r-   normalized_valueN)
r   r   r   r/   r0   torchTensorr   r   r1   r%   r&   r'   r4   r4   1   s2    
I<<llMr&   r4   c                       e Zd ZU eeef   ed<   ej                  ed<   eee	f   ed<   eed<   eee	f   ed<   e
e   ed<   y)MultiLossStatelosses
total_lossweighted_contributionsdominant_lossgradient_normsoptimization_adviceN)r   r   r   r   r/   r4   r0   r9   r:   r1   r   r%   r&   r'   r<   r<   <   sI    j!! e,,e$$c"r&   r<   c            	            e Zd ZdZdef fdZ	 	 d	dej                  dej                  dej                  defdZ	 xZ
S )
BaseLossFunctionz-Base class for all diagnostic loss functions.configc                 0    t         |           || _        y N)super__init__rE   selfrE   	__class__s     r'   rI   zBaseLossFunction.__init__M   s    r&   errorX	referencereturnc                     t         rG   )NotImplementedError)rK   rM   rN   rO   s       r'   forwardzBaseLossFunction.forwardQ   s    !!r&   NNr   r   r   __doc__r)   rI   r9   r:   r4   rS   __classcell__rL   s   @r'   rD   rD   J   sJ    7z  >B*."U\\ "ell " <<"3="r&   rD   c            	            e Zd ZdZdef fdZ	 	 d	dej                  dej                  dej                  defdZ	 xZ
S )
SpatialConcentrationLossz%Penalizes spatially clustered errors.rE   c                 $    t         |   |       y rG   rH   rI   rJ   s     r'   rI   z!SpatialConcentrationLoss.__init__]        r&   rM   rN   rO   rP   c                    |j                         dk(  r|j                  d      }|j                  d   }g }t        |      D ]  }||   }g }	d}
|j                  \  }}t        d||
z
  |
      D ]L  }t        d||
z
  |
      D ]7  }||||
z   |||
z   f   }|	j	                  t        j                  |             9 N |	r(t        j                  t        j                  |	            nt        j                  d      }t        j                  |      dz   }|j	                  ||z          t        j                  t        j                  |            }t        j                  |d      d   }t        j                  |d      d   }|dz  |dz  z   j                         j                  d      }n|}g }	d}
|j                  \  }}t        d||
z
  |
      D ]L  }t        d||
z
  |
      D ]7  }||||
z   |||
z   f   }|	j	                  t        j                  |             9 N |	r(t        j                  t        j                  |	            nt        j                  d      }t        j                  |      dz   }||z  }t        j                  |d      t        j                  |d      }}|dz  |dz  z   j                         }t        j                  |d	z
        }t        | j                  j                  ||d
|j                         i| j                  j                   | j                  j"                  t%        |j                         d      dz        S )N      dimr              :0yE>   r,   concentration       @r*   r5   r6   r7   r+   r-   r8   )rb   meanshaperangeappendr9   varstacktensorr6   sqrtrelur4   rE   r*   itemr+   r-   min)rK   rM   rN   rO   error_2dBconcentrationsbelocal_windowswindow_sizeHWyxwindow	local_var
global_varrg   grad_ygrad_xgradient_magnitude
loss_values                          r'   rS   z SpatialConcentrationLoss.forward`   s!    99;!zzaz(Hq!A  N1X >QK "ww1q!k/;? @A"1a+o{C @!"1Q{]?AamO#C!D%,,UYYv->?@@
 GTEJJu{{='ABY^YeYefiYj	"YYq\D0
%%i*&<=> "JJu{{>'BCM ^^H!4Q7F^^H!4Q7F"(!)fai"7!=!=!?!D!D!D!K AMK77DAq1a+o{; <q!k/;? <Aq;!K-?@F!((6):;<<
 CP

5;;}#=>UZUaUabeUfI1,J%
2M"^^A15u~~aQ7OFF"(!)fai"7!=!=!?ZZ 34
!!'(-*<*<*>?[[));;%% !3!3!5s;cA
 	
r&   rT   rU   rX   s   @r'   rZ   rZ   Z   sJ    /!z ! >B*.;
U\\ ;
ell ;
 <<;
3=;
r&   rZ   c            	            e Zd ZdZdef fdZ	 	 d	dej                  dej                  dej                  defdZ	 xZ
S )
SpatialEntropyLossz5Encourages uniform error distribution (high entropy).rE   c                 $    t         |   |       y rG   r\   rJ   s     r'   rI   zSpatialEntropyLoss.__init__   r]   r&   rM   rN   rO   rP   c                    |j                         dk(  rq|j                         j                  d      j                  d      }|j                  d   }g }g }t        |      D ]  }||   }	|	j                         dz   }
|	|
z  }|t        j                  |dz         z  j                          }t        j                  t        j                  |	j                         t        j                              }||dz   z  }|j                  |       |j                  |j                         |   d|z
  z          dt        j                  t        j                  |            z
  }t        j                  |      j                  d      }n|j                         j                         }||j                         dz   z  }|t        j                  |dz         z  j                          }t        j                  t        j                  |j                         t        j                              }||dz   z  }d|z
  }|j                         d|z
  z  }t        | j                  j                   ||d|j                         dk(  rj#                         ni| j                  j$                  | j                  j&                  t)        |t        j*                        r|j#                         	      S |	      S )
Nr_   r`   ra   r   re   )dtyper,   entropyri   )rb   absrj   flattenrk   rl   sumr9   logrp   numelfloat32rm   ro   r4   rE   r*   rs   r+   r-   
isinstancer:   )rK   rM   rN   rO   	error_magrv   	entropiesgradsrx   emem_sumpr   max_entropynormalized_entropyr   r6   s                    r'   rS   zSpatialEntropyLoss.forward   sd   99;!		((Q(/77:I"AIE1X 
Hq\DK		!d( 3388::#iiRXXZu}}(UV%,d0B%C"  !34UYY[^q3E/EFG
H uzz%++i*@AAJ{{5)..1.5H 		++-IY]]_t34AEIIa$h//4466G))ELL1B%--$XYK!(K$,>!?11Jyy{a*<&<=H!!"eiikQ6FGLLNGT[[));;%%2<Z2VZ__.
 	
 ]g
 	
r&   rT   rU   rX   s   @r'   r   r      sJ    ?!z ! >B*.)
U\\ )
ell )
 <<)
3=)
r&   r   c            	            e Zd ZdZddededef fdZ	 	 ddej                  dej                  dej                  d	e
fd
Z xZS )HotspotPenaltyLossz&Penalizes top-k highest error regions.rE   
n_hotspotspenalty_scalec                 @    t         |   |       || _        || _        y rG   )rH   rI   r   r   )rK   rE   r   r   rL   s       r'   rI   zHotspotPenaltyLoss.__init__   s     $*r&   rM   rN   rO   rP   c                    |j                         dk(  r|j                         j                  d      }|j                  d   }g }g }t	        |      D ]F  }||   j                         }	|	j                         }
t        | j                  |
dz        }t        j                  |	t        d|
|z
              d   }|	|k\  }|	|   }|j                         dkD  ry|| j                  z  j                         }t        j                  |	      }|| j                  z  ||<   |j                  |       |j                  |j                  ||                |j                  t        j                   d             |j                  t        j                  ||                I t        j                  t        j"                  |            }t        j"                  |      j                  d      }n|j                         j                         }|j                         }
t        | j                  |
dz        }t        j                  |t        d|
|z
              d   }||k\  }||   }|j                         dkD  r|| j                  z  j                         nt        j                   d      }t        j                  |      }|j                         dkD  r || j                  z  |j                         |<   t%        | j&                  j(                  ||di| j&                  j*                  | j&                  j,                  t        t/        |t        j0                        r|j3                         n|d      	      S )
Nr_   r`   ra   r   
   rd   r   r,   ri   )rb   r   rj   rk   rl   r   r   rt   r   r9   kthvaluemaxr   
zeros_likerm   
reshape_asrp   ro   r4   rE   r*   r+   r-   r   r:   rs   )rK   rM   rN   rO   r   rv   loss_values	gradientsrx   r   
total_sizek	thresholdhotspot_maskhotspot_errorsloss_valgradr   r6   s                      r'   rS   zHotspotPenaltyLoss.forward   s   99;!		((Q(/I"AKI1X Eq\))+XXZ
 r)9:!NN2s1j1n/EFqI	!Y!#L!1!'')A- .$2D2D DJJLH ++B/D)7$:L:L)LD&&&x0$$T__Yq\%BC&&u||C'89$$U%5%5il%CD'E* EKK$<=J{{9-22q29H 		++-I"*JDOOZ2%56Ay#aa2HI!LI$	1L&|4NJXJ^J^J`cdJd.D,>,>>DDFjojvjvwzj{J''.H##%)3ADDVDV3V  "<0!!%q)[[));;%% jU\\6Z!2`jlop
 	
r&   )rc   rh   rT   )r   r   r   rV   r)   intr1   rI   r9   r:   r4   rS   rW   rX   s   @r'   r   r      sX    0+z +s +u +
 >B*.8
U\\ 8
ell 8
 <<8
3=8
r&   r   c            	            e Zd ZdZddededef fdZ	 	 ddej                  dej                  dej                  d	e
fd
Z xZS )SpectralBandLossz8Loss based on error energy in different frequency bands.rE   bandtarget_ratioc                 @    t         |   |       || _        || _        y rG   )rH   rI   r   r   )rK   rE   r   r   rL   s       r'   rI   zSpectralBandLoss.__init__  s     	(r&   rM   rN   rO   rP   c                    |j                         dk(  r|j                  d      }|j                  d   }g }g }t        |      D ]  }||   }	|	j                  \  }
}t        j
                  j                  |	      }t        j
                  j                  |      }t	        j                  |      }|
dz  |dz  }}t	        j                  |
t        j                  |	j                        j                  d      j                  |
|      }t	        j                  |t        j                  |	j                        j                  d      j                  |
|      }||z
  dz  ||z
  dz  z   j                         }t	        j                  t	        j                  |dz  |dz  z   t        j                  |	j                              }| j                   dk(  r	||dz  k  }n)| j                   d	k(  r||dz  k\  ||d
z  k  z  }n||d
z  k\  }||   dz  j#                         }|dz  j#                         dz   }||z  }|j%                  |       |j%                  ||z          t	        j                  t	        j&                  |D cg c]C  }t	        j                  |t	        j                  | j(                  |j                        z
        E c}            }t	        j&                  |      j                  d      }n|}	|	j                  \  }
}t        j
                  j                  |	      }t        j
                  j                  |      }t	        j                  |      }|
dz  |dz  }}t	        j                  |
t        j                  |	j                        j                  d      j                  |
|      }t	        j                  |t        j                  |	j                        j                  d      j                  |
|      }||z
  dz  ||z
  dz  z   j                         }t	        j                  t	        j                  |dz  |dz  z   t        j                  |	j                              }| j                   dk(  r	||dz  k  }n)| j                   d	k(  r||dz  k\  ||d
z  k  z  }n||d
z  k\  }||   dz  j#                         }|dz  j#                         dz   }||z  }t	        j                  || j(                  z
        }||z  }t+        | j,                  j.                  ||| j                   t1        t        j2                        r|j5                         n|d| j,                  j6                  | j,                  j8                  t;        t1        |t        j2                        r|j5                         n|d            S c c}w )Nr_   r`   ra   r   rf   )r   devicelowg      ?mid      ?re   r   )r   ratior,   ri   )rb   rj   rk   rl   r9   fftfft2fftshiftr   aranger   r   	unsqueezeexpandrq   rp   r   r   rm   ro   r   r4   rE   r*   r   r:   rs   r+   r-   rt   )rK   rM   rN   rO   ru   rv   band_energiesr   rx   ry   r|   r}   r   	fft_shift	magnitudecenter_ycenter_xy_coordsx_coordsdistancemax_distmaskband_energytotal_energyr   rr   r6   s                               r'   rS   zSpectralBandLoss.forward  s   99;!zzaz(Hq!AMI1X 4QKww1 iinnQ'!II..s3	!IIi0	 &'!VQ!V( <<qxxPZZ[\]ddefhij <<qxxPZZ[\]ddefhij%01488Ka7OOUUW ::ell8Q;13LTYTaTajkjrjr&st99%#ho5DYY%'$47HxRV<VWD#x$6D(!388: )Q335<#l2$$U+  U!23;4> EKK&1 		!ell4+<+<QXXNNO1 % J {{9-22q29H A77DAq))..#C		**3/I		),I!"aahH||AU]]188LVVWXY``abdefH||AU]]188LVVWXY``abdefH!H,q0Hx4G!3KKQQSHzz%,,x{Xq[/HPUP]P]fgfnfn"opHyyE!(T/1e# HtO38d?8RS8d?2$T?a/446K%N//1D8L,.E54+<+<#<=J :-H!!!%ZPUW\WcWcEdUZZ\jop[[));;%% jU\\6Z!2`jlop
 	
E1s   ?AW)high皙?rT   )r   r   r   rV   r)   r/   r1   rI   r9   r:   r4   rS   rW   rX   s   @r'   r   r     s]    B)z ) )U )
 >B*.R
U\\ R
ell R
 <<R
3=R
r&   r   c            	            e Zd ZdZd
dedef fdZ	 	 ddej                  dej                  dej                  de	fd	Z
 xZS )SpectralSkewnessLossz-Penalizes asymmetric frequency distributions.rE   target_skewnessc                 2    t         |   |       || _        y rG   )rH   rI   r   )rK   rE   r   rL   s      r'   rI   zSpectralSkewnessLoss.__init__w       .r&   rM   rN   rO   rP   c                    |j                         dk(  rt|j                  d      }|j                  d   }g }t        |      D ]  }||   }t        j
                  j                  |      }	t        j
                  j                  |	      }
t	        j                  |
      }|j                  d      }||j                         z
  |j                         dz   dz  z  j                         }|j                  d      }||j                         z
  |j                         dz   dz  z  j                         }|j                  t        |      t        |      z   dz          t	        j                  t	        j                  |            }nt        j
                  j                  |      }	t        j
                  j                  |	      }
t	        j                  |
      }|j                  d      }||j                         z
  |j                         dz   dz  z  j                         }|j                  d      }||j                         z
  |j                         dz   dz  z  j                         }t        |      t        |      z   dz  }t	        j                  || j                  z
        }|t	        j                  || j                  z
        z  }t        | j                  j                   ||dt#        |t        j$                        r|j'                         n|i| j                  j(                  | j                  j*                  t-        t#        |t        j$                        r|j'                         n|d	      d	z  
      S )Nr_   r`   ra   r   re      rf   skewnessrh   ri   )rb   rj   rk   rl   r9   r   r   r   r   stdrm   ro   r   signr4   rE   r*   r   r:   rs   r+   r-   rt   )rK   rM   rN   rO   ru   rv   
skewnessesrx   ry   r   r   r   h_meanh_skewv_meanv_skewr   r   r6   s                      r'   rS   zSpectralSkewnessLoss.forward{  s   99;!zzaz(Hq!AJ1X CQKiinnQ'!II..s3	!IIi0	"A.!FKKM1fjjlT6Ia5OOUUW"A.!FKKM1fjjlT6Ia5OOUUW!!3v;V#<"ABC zz%++j"9:H))..'C		**3/I		),I^^^*F-&**,2E!1KKQQSF^^^*F-&**,2E!1KKQQSFFc&k1Q6HYYx$*>*>>?
5::h1E1E&EFF!!#
8U\\8ZX]]_`hi[[));;%% Jx4V\dfijmpp
 	
r&   rd   rT   r   r   r   rV   r)   r1   rI   r9   r:   r4   rS   rW   rX   s   @r'   r   r   t  sQ    7/z /E / >B*.,
U\\ ,
ell ,
 <<,
3=,
r&   r   c            	            e Zd ZdZdef fdZ	 	 d	dej                  dej                  dej                  defdZ	 xZ
S )
MeanErrorLossz0Penalizes non-zero mean error (bias correction).rE   c                 $    t         |   |       y rG   r\   rJ   s     r'   rI   zMeanErrorLoss.__init__  r]   r&   rM   rN   rO   rP   c                    |j                         }t        j                  |      }t        j                  |      t        j                  |      z  }t        | j                  j                  ||d|j                         i| j                  j                  | j                  j                  t        t        |j                               dz  d            S )Nrj   r   r,   ri   )rj   r9   r   r   	ones_liker4   rE   r*   rs   r+   r-   rt   )rK   rM   rN   rO   
mean_errorr   r6   s          r'   rS   zMeanErrorLoss.forward  s    ZZ\
YYz*
::j)EOOE,BB!!!23[[));;%% Z__%6!7"!<cB
 	
r&   rT   rU   rX   s   @r'   r   r     sJ    :!z ! >B*.
U\\ 
ell 
 <<
3=
r&   r   c            	            e Zd ZdZd
dedef fdZ	 	 ddej                  dej                  dej                  de	fd	Z
 xZS )SkewnessLossz(Encourages symmetric error distribution.rE   target_skewc                 2    t         |   |       || _        y rG   )rH   rI   r   )rK   rE   r   rL   s      r'   rI   zSkewnessLoss.__init__  s     &r&   rM   rN   rO   rP   c                    |j                         }|j                         }|j                         dz   }||z
  |dz  z  j                  d      j                         }t	        j
                  || j                  z
        }||z
  |z  }	|	j                  d      t	        j                  || j                  z
        z  }
|
j                  |      }
t        | j                  j                  ||
d|j                         i| j                  j                  | j                  j                  t        t        |j                               d      dz        S )Nre   r   rf   r         @ri   )r   rj   r   powr9   r   r   r   r   r4   rE   r*   rs   r+   r-   rt   )rK   rM   rN   rO   
error_flatrj   r   r   r   standardizedr6   s              r'   rS   zSkewnessLoss.forward  s   ]]_
 nn%$&#(277:??AYYx$*:*::;
"T)S0##A&Ht?O?O4O)PP&&u-!!#X]]_5[[));;%% X]]_!5s;cA
 	
r&   r   rT   r   rX   s   @r'   r   r     sQ    2'z ' ' >B*.
U\\ 
ell 
 <<
3=
r&   r   c            	            e Zd ZdZd
dedef fdZ	 	 ddej                  dej                  dej                  de	fd	Z
 xZS )KurtosisLossu'   Encourages normal-like kurtosis (≈3).rE   target_kurtosisc                 2    t         |   |       || _        y rG   )rH   rI   r   )rK   rE   r   rL   s      r'   rI   zKurtosisLoss.__init__  r   r&   rM   rN   rO   rP   c                    |j                         }|j                         }|j                         dz   }||z
  |dz  z  j                  d      j                         }t	        j
                  || j                  z
        }||z
  |z  }	|	j                  d      t	        j                  || j                  z
        z  }
|
j                  |      }
t        | j                  j                  ||
d|j                         i| j                  j                  | j                  j                  t        t        |j                         dz
        dz  d            S )Nre   r_   r   kurtosisrc   r,   ri   )r   rj   r   r   r9   r   r   r   r   r4   rE   r*   rs   r+   r-   rt   )rK   rM   rN   rO   r   rj   r   r   r   r   r6   s              r'   rS   zKurtosisLoss.forward  s   ]]_
 nn%$&#(277:??AYYx$*>*>>?
"T)S0##A&Ht?S?S4S)TT&&u-!!#X]]_5[[));;%% X]]_q%8!9A!=sC
 	
r&   )r   rT   r   rX   s   @r'   r   r     sQ    1/z /E / >B*.
U\\ 
ell 
 <<
3=
r&   r   c            	            e Zd ZdZd
dedef fdZ	 	 ddej                  dej                  dej                  de	fd	Z
 xZS )BimodalityLossz2Detects and penalizes bimodal error distributions.rE   n_binsc                 2    t         |   |       || _        y rG   )rH   rI   r   )rK   rE   r   rL   s      r'   rI   zBimodalityLoss.__init__  s     r&   rM   rN   rO   rP   c           	         |j                         }|j                         |j                         }}t        j                  ||| j
                  dz   |j                        }t        j                  || j
                  |j                         |j                               }||j                         dz   z  }g }	t        dt        |      dz
        D ]D  }
||
   ||
dz
     kD  s||
   ||
dz      kD  s!|	j                  |
||
   j                         f       F t        |	      dk\  r|	j                  d d       |	d	   |	d   }}t        |d	   |d	         }t        |d	   |d	         }t        |||dz    j                         j                         |j                         j                               }|d   |d   z   dz  }t        d	d
||dz   z  z
        }nd}t        j                  t        d	|dz
        |j                        }t        j                  |      }t!        | j"                  j$                  |||t        |	      d| j"                  j&                  | j"                  j(                  |      S )Nr`   r   )binsrt   r   re   rf   c                     | d   S Nr`   r%   r   s    r'   <lambda>z(BimodalityLoss.forward.<locals>.<lambda>  s
    QqT r&   Tkeyreverser   r,   rd   333333?)bimodality_scoren_peaksri   )r   rt   r   r9   linspacer   r   histcrs   r   rl   lenrm   sortrp   r   r4   rE   r*   r+   r-   )rK   rM   rN   rO   r   min_valmax_val	bin_edgeshistpeaksipeak1peak2valley_start
valley_endvalley_heightpeak_heightsr  r   r6   s                       r'   rS   zBimodalityLoss.forward
  s+   ]]_
 &>>+Z^^-=NN7GT[[1_U\\Z	{{:DKKW\\^QXQ]Q]Q_`txxzD() q#d)a-( 	2AAwac"tAwac':aa01	2 u:?JJ>4J8 8U1X5EuQxq2LU1XuQx0J\*Q, ? C C E J J LdhhjooN_`M!!HuQx/14L"1cM\D=P,Q&QR"\\#a)9C)?"@V
 ##E*!!-=#e*U[[));;%%-
 	
r&      rT   )r   r   r   rV   r)   r   rI   r9   r:   r4   rS   rW   rX   s   @r'   r   r     sQ    <z 3  >B*.+
U\\ +
ell +
 <<+
3=+
r&   r   c            	            e Zd ZdZd
dedef fdZ	 	 ddej                  dej                  dej                  de	fd	Z
 xZS )ChannelErrorLossz(Penalizes unequal error across channels.rE   target_equalc                 2    t         |   |       || _        y rG   )rH   rI   r  )rK   rE   r  rL   s      r'   rI   zChannelErrorLoss.__init__?  s     (r&   rM   rN   rO   rP   c                    |j                         dk(  rB|j                         j                  d      }|j                  \  }}|j                  d      }nF|j	                  d      dz  }|j                  |d      j                         j                  d      }|}| j                  rk|j                         }	||	z
  dz  j                         }
||	z
  j                  d      j                  d      j                  d      j                  |      dz  }n%|j                         }
t        j                  |      }t        | j                  j                  |
|d	|j                         j                         i| j                  j                  | j                  j                   t#        t%        |
t        j&                        r|
j                         n|
d
            S )Nr_   )rf   r   ra   r     r`   rf   mean_errorsr,   ri   )rb   r   rj   rk   sizereshaper  r   	expand_asr9   r   r4   rE   r*   rs   r+   r-   rt   r   r:   )rK   rM   rN   rO   channel_errorsrv   Cr!  
n_channelstargetr   r6   s               r'   rS   zChannelErrorLoss.forwardC  s   99;!"YY[--&-9N!''DAq(--!-4KA#-J"]]:s;??AFF1FMN(K %%'F&/A5;;=J#f,77:DDRHRRSUV``afgjkkH$))+Jzz%(H!!&(8(8(:(?(?(AB[[));;%% jU\\6Z!2`jlop
 	
r&   TrT   )r   r   r   rV   r)   r2   rI   r9   r:   r4   rS   rW   rX   s   @r'   r  r  <  sQ    2)z ) ) >B*.
U\\ 
ell 
 <<
3=
r&   r  c            	            e Zd ZdZd
dedef fdZ	 	 ddej                  dej                  dej                  de	fd	Z
 xZS )CorrelationLossz.Penalizes correlated errors across dimensions.rE   target_correlationc                 2    t         |   |       || _        y rG   )rH   rI   r,  )rK   rE   r,  rL   s      r'   rI   zCorrelationLoss.__init__f  s     "4r&   rM   rN   rO   rP   c                 \   |j                         dk(  r|n |j                  |j                  d      d      }|j                  d      dkD  rt        j                  |dz         }|j
                  d   }g }t        |      D ]:  }t        |dz   |      D ]&  }	|j                  |||	f   j                                ( < |r(t        j                  t        j                  |            nt        j                  d      }
nt        j                  d      }
t        j                  |
| j                  z
        }||
z  }t        | j                  j                  ||d|
j!                         i| j                  j"                  | j                  j$                  t'        |
j!                         d      	      S )
Nrf   r   r   r`   re   rd   mean_correlationr,   ri   )rb   r#  r"  r9   corrcoefrk   rl   rm   r   rj   ro   rp   r,  r4   rE   r*   rs   r+   r-   rt   )rK   rM   rN   rO   ru   corr_matrixnoff_diagonalr  j	mean_corrr   r6   s                r'   rS   zCorrelationLoss.forwardj  sj    "IIK1,5%--

1r2R==a..D9K!!!$AL1X AqsA AA ''AqD(9(=(=(?@AA BN

5;;|#<=SXS_S_`cSdIS)IYYy4+B+BBC
9$!!+Y^^-=>[[));;%% !137
 	
r&   r   rT   r   rX   s   @r'   r+  r+  c  sQ    85z 5u 5 >B*.
U\\ 
ell 
 <<
3=
r&   r+  c            	            e Zd ZdZddededef fdZ	 	 ddej                  dej                  dej                  d	e	fd
Z
 xZS )EdgeErrorLossz2Separately tracks error in edge vs smooth regions.rE   edge_weightsmooth_weightc                 @    t         |   |       || _        || _        y rG   )rH   rI   r8  r9  )rK   rE   r8  r9  rL   s       r'   rI   zEdgeErrorLoss.__init__  s      &*r&   rM   rN   rO   rP   c                    |j                         dk(  rN|j                  d      }|j                  d   }|(|j                         dk(  r|j                  d      n|}n|}n
|}d}||n|}|j                         dk(  rt        j                  |d      d   nt        j
                  |      }|j                         dk(  rt        j                  |d      d   nt        j
                  |      }|j                         |j                         z   }	t        j                  |	j                         t        |	j                         dz              d   }
|	|
kD  }| }|j                         dk(  r|j                         r!|j                         |   j                         nt        j                  d      }|j                         r!|j                         |   j                         nt        j                  d      }n|j                         r!|j                         |   j                         nt        j                  d      }|j                         r!|j                         |   j                         nt        j                  d      }| j                  |z  | j                  |z  z   }t        j
                  |      }|j                         dk(  rQ| j                  t        j                  ||         z  ||<   | j                  t        j                  ||         z  ||<   nP| j                  t        j                  ||         z  ||<   | j                  t        j                  ||         z  ||<   |j                         dk(  r0|j!                  d      j#                  |      j                  d      }t%        | j&                  j(                  |||j+                         |j+                         d	| j&                  j,                  | j&                  j.                  t1        t3        |t        j4                        r|j+                         n|d
            S )Nr_   r`   ra   r   rf   r   r   rd   )
edge_errorsmooth_errorr,   ri   )rb   rj   rk   r9   r6   r   r   r   r   r   r   anyrp   r8  r9  r   r   r$  r4   rE   r*   rs   r+   r-   rt   r   r:   )rK   rM   rN   rO   ru   rv   refr   r   edge_magnituder   	edge_masksmooth_maskr<  r=  r   r6   s                    r'   rS   zEdgeErrorLoss.forward  sm   99;!zzaz(Hq!A$/8}}!/Cinnn+HA(4)%C 36'')q.+A.eFVFVW_F`25'')q.+A.eFVFVW_F` **,5NN>#9#9#;SAUAUAWZ^A^=_`abc	"Y.	 j<<>Q=F]]_	2779RWR^R^_bRcJALAR8<<>+6;;=X]XdXdehXiL=F]]_	2779RWR^R^_bRcJALAR8<<>+6;;=X]XdXdehXiL%%
2T5G5G,5VV
##H-<<>Q"&"2"2UZZ@S5T"THY$($6$6H[DY9Z$ZH[!"&"2"2UZZ@S5T"THY$($6$6H[DY9Z$ZH[!99;!))!,66u=BBqBIH!!'1'8,J[J[J]^[[));;%% jU\\6Z!2`jlop
 	
r&   )      ?r,   rT   r   rX   s   @r'   r7  r7    sY    <+z + +TY +
 >B*.4
U\\ 4
ell 4
 <<4
3=4
r&   r7  c                   f     e Zd ZdZddedef fdZdej                  dej                  fdZ xZ	S )	ErrorDiscriminatorz(Discriminator that judges error quality.	input_dim
hidden_dimc           
      H   t         |           t        j                  t        j                  ||      t        j
                  d      t        j                  ||      t        j
                  d      t        j                  |d      t        j                               | _        y )Nr   r`   )rH   rI   nn
SequentialLinear	LeakyReLUSigmoidnet)rK   rF  rG  rL   s      r'   rI   zErrorDiscriminator.__init__  si    ==IIi,LLIIj*-LLIIj!$JJL
r&   rM   rP   c                 X    |j                  d      d d d df   }| j                  |      S )Nr`   r  )r   rN  )rK   rM   r   s      r'   rS   zErrorDiscriminator.forward  s,    ]]1%a#g.
xx
##r&   )r  @   )
r   r   r   rV   r   rI   r9   r:   rS   rW   rX   s   @r'   rE  rE    s4    2	
# 	
 	
$U\\ $ell $r&   rE  c            	            e Zd ZdZd
dedej                  f fdZ	 	 ddej                  dej                  dej                  de
fd	Z xZS )AdversarialLossz<Adversarial loss using discriminator to judge error quality.rE   discriminatorc                 2    t         |   |       || _        y rG   )rH   rI   rS  )rK   rE   rS  rL   s      r'   rI   zAdversarialLoss.__init__  s     *r&   rM   rN   rO   rP   c                    | j                   |dz  j                         }d|z  }n| j                  |      }d|j                         z
  }d|z
  }|j                         |j                         k  r3|j                  d      }|j                         |j                         k  r3||z  }t	        | j
                  j                  ||d| j                   rj                         j                         ndi| j
                  j                  | j
                  j                  t        |t        j                        r|j                               S |      S )Nrf   r,   r`   r   quality_score      ?ri   )rS  rj   rb   r   r4   rE   r*   rs   r+   r-   r   r9   r:   )rK   rM   rN   rO   r   r6   rV  score_scales           r'   rS   zAdversarialLoss.forward  s%   %1***,J5yH ..u5M}1133J m+K//#eiik1)33B7 //#eiik1{*H!!(I[I[-*<*<*>*C*C*Eade[[));;%%2<Z2VZ__.
 	
 ]g
 	
r&   rG   rT   )r   r   r   rV   r)   rI  ModulerI   r9   r:   r4   rS   rW   rX   s   @r'   rR  rR    sU    F+z +")) + >B*.
U\\ 
ell 
 <<
3=
r&   rR  c            	            e Zd ZdZd
dedef fdZ	 	 ddej                  dej                  dej                  de	fd	Z
 xZS )GradientPenaltyLossz1Penalizes large gradients (unstable predictions).rE   penaltyc                 2    t         |   |       || _        y rG   )rH   rI   r\  )rK   rE   r\  rL   s      r'   rI   zGradientPenaltyLoss.__init__  s     r&   rM   rN   rO   rP   c                    |j                         dk(  r|j                  d      }t        j                  |d      d   }t        j                  |d      d   }|dz  |dz  z   j	                         j                         }t        j                  |d      d   t        j                  |d      d   z   }nt        j                  |d      t        j                  |d      }}|dz  |dz  z   j	                         j                         }t        j                  |d      d   t        j                  |d      d   z   }|dz  }	t        | j                  j                  |	|d|j                         i| j                  j                  | j                  j                  t        t        |	t        j                        r|	j                         n|	d            S )	Nr_   r`   ra   r   rf   mean_gradientr,   ri   )rb   rj   r9   r6   rq   r4   rE   r*   rs   r+   r-   rt   r   r:   )
rK   rM   rN   rO   ru   r   r   grad_mag	laplacianr   s
             r'   rS   zGradientPenaltyLoss.forward  s   99;!zzaz(H^^H!4Q7F^^H!4Q7F	FAI-335::<H v15a85>>&VW;XYZ;[[I"^^Eq95>>%UV;WFF	FAI-335::<Hv15a85>>&VW;XYZ;[[I]
!!((--/:[[));;%% jU\\6Z!2`jlop
 	
r&   r,   rT   r   rX   s   @r'   r[  r[  	  sQ    ;z E  >B*.
U\\ 
ell 
 <<
3=
r&   r[  c            	            e Zd ZdZd
dedef fdZ	 	 ddej                  dej                  dej                  de	fd	Z
 xZS )LipschitzPenaltyLossz/Ensures smooth function behavior (K-Lipschitz).rE   Kc                 2    t         |   |       || _        y rG   )rH   rI   re  )rK   rE   re  rL   s      r'   rI   zLipschitzPenaltyLoss.__init__0  s     r&   rM   rN   rO   rP   c                    |j                         dk(  r|j                  d      }n|}|j                  dd  \  }}|dd d dd f   |dd d d df   z
  }|ddd d d f   |dd dd d f   z
  }t        |j	                         dkD  r1t        j                  |      j                         j                         nd|j	                         dkD  r1t        j                  |      j                         j                         nd      }	t        j                  t        j                  |	| j                  z
  |j                              }
t        j                  |      }t        | j                  j                  |
||	| j                  d	| j                  j                   | j                  j"                  t%        t'        |
t
        j(                        r|
j                         n|
d
            S )Nr_   r`   ra   .r   r   r   )max_diffre  r,   ri   )rb   rj   rk   r   r   r9   r   rs   rr   rp   re  r   r   r4   rE   r*   r+   r-   rt   r   r:   )rK   rM   rN   rO   ru   r|   r}   h_diffv_diffri  r   r6   s               r'   rS   zLipschitzPenaltyLoss.forward4  s   99;!zzaz(HH~~bc"1#q!"*%a"(==#qr1*%crc1(==.4llnq.@EIIf!!#((*a.4llnq.@EIIf!!#((*a

 ZZX->u|| TU
##E*!!%-DFF;[[));;%% jU\\6Z!2`jlop
 	
r&   rb  rT   r   rX   s   @r'   rd  rd  -  sQ    9z e  >B*.
U\\ 
ell 
 <<
3=
r&   rd  c                      e Zd ZdZddeedf   fdZd Z	 	 ddej                  dej                  d	ej                  d
e
eef   fdZ	 dde
eef   ded
eej                  ej                  ef   fdZde
eef   ded
ee   fdZy)MultiLossOptimizerz3Optimizer that combines multiple diagnostic losses.rk   .c                     || _         t        j                         | _        t	        d      | _        t        j                  | j
                  j                         d      | _	        | j                          y )Nr  )rF  MbP?lr)rk   rI  
ModuleDictloss_functionsrE  rS  optimAdam
parametersoptimizer_disc_initialize_loss_functions)rK   rk   s     r'   rI   zMultiLossOptimizer.__init__Z  sR    
 mmo/#>#jj););)F)F)HUS'')r&   c                    t        t        dt        j                  d            | j                  d<   t        t        dt        j                  d            | j                  d<   t        t        dt        j                  d      dd	      | j                  d<   t        t        d
t        j                  d      dd      | j                  d
<   t        t        dt        j                  d      dd      | j                  d<   t        t        dt        j                  d      dd      | j                  d<   t        t        dt        j                  d            | j                  d<   t        t        dt        j                  d            | j                  d<   t        t        dt        j                  d            | j                  d<   t        t        dt        j                  d      d      | j                  d<   t        t        dt        j                  d            | j                  d<   t        t        dt        j                   d            | j                  d<   t#        t        dt        j                   d            | j                  d<   t%        t        dt        j&                  d      dd      | j                  d<   t)        t        d t        j*                  d      | j,                  !      | j                  d <   t/        t        d"t        j0                  d            | j                  d"<   t3        t        d#t        j0                  d            | j                  d#<   y$)%zInitialize all loss functions.spatial_concentrationrW  )r-   spatial_entropyr  hotspot_penaltyrc   rh   )r   r   spectral_highr   r   )r   r   spectral_midr   spectral_lowr   spectral_skewnessr   r   r   r   )r   
bimodalityg?channel_errorcorrelationr<  rC  r,   )r8  r9  r   )rS  gradient_penaltylipschitz_penaltyN)rZ   r)   r   r   rs  r   r   r   r   r   r   r    r   r   r   r  r!   r+  r7  r"   rR  r#   rS  r[  r$   rd  rK   s    r'   rx  z-MultiLossOptimizer._initialize_loss_functionsb  s    8P.0D0DSQ8
34 2D(,*>*>sK2
-. 2D(,*>*>sK2
-. 0@(=(=cJc0
O, /?~|'<'<SIS/
N+ /?~|'<'<SIS/
N+ 4H*L,A,A#N4
/0
 -:|\%=%=cJ-
L) +7z<#;#;CH+
J' +7z<#;#;CH+
J' -;|\%=%=cJ-
L)
 0@(>(>sK0
O, .=}l&<&<SI.
M*
 -:|\%9%9#F3-
L) .=}l&>&>sK,,.
M* 3F)<+F+FsS3
./ 4H*L,G,GPST4
/0r&   NrM   rN   rO   rP   c                 4   i }| j                   j                         D ];  \  }}	 t        j                         5  |j	                  |||      }ddd       ||<   = |S # 1 sw Y   xY w# t
        $ r%}t        j                  d| d|        Y d}~ud}~ww xY w)zCompute all enabled losses.NzLoss z	 failed: )rs  itemsr9   no_gradrS   	Exceptionloggerwarning)	rK   rM   rN   rO   resultsr*   loss_fnresultry   s	            r'   compute_all_lossesz%MultiLossOptimizer.compute_all_losses  s     !00668 	;MD';]]_ B$__UAyAFB &		; B B  ;tfIaS9::;s.   A)AA)A&	"A))	B2BBr=   dynamic_weightingc                    t        j                  dt              }t        j                  t	        |j                               d   j                        }i }i }|r|j                         D cg c]  }|j                  dkD  s|j                    }}|rst        |      }	t        |      }
|j                         D ]J  \  }}|j                  dkD  s|	|
kD  s|j                  |
z
  |	|
z
  dz   z  }|j                  d|z   z  |_        L |j                         D ]  \  }}|j                  dkD  s|j                  |j                  z  }||z   }|j                         ||<   |j                  j                         dz   }|j                  |z  }|||j                  z  z   }|j                         ||<    |rt        ||j                        nd}t!        |||||| j#                  ||            }|||fS c c}w )	z3Aggregate all losses into single loss and gradient.rd   r   r   re   r`   )r  mse)r=   r>   r?   r@   rA   rB   )r9   rp   r   r   listvaluesr6   r-   r8   r   rt   r  r5   rs   normgetr<   _generate_advice)rK   r=   r  r>   combined_gradientr?   rA   lr   max_lossmin_lossr*   loss
normalizedweighted_loss	grad_normnormalized_gradientr@   states                      r'   aggregate_lossesz#MultiLossOptimizer.aggregate_losses  s    \\#f5
!,,T&--/-B1-E-N-NO!# 7=}}W!!((UV,1--WKW{+{+"(,,. EJD${{Q8h+>&*&;&;h&F8V^K^aeKe%f
&*kkQ^&DE !,,. 		8JD${{Q $

T[[ 8'-7
/</A/A/C&t, MM..047	&*mmi&?#$58Kdkk8Y$Y!'0~~'7t$		8 Xn28N8R8RSsx!#9') $ 5 5fm L
 ,e33E Xs   -G2G2r@   c                 z   g }|j                         D cg c]"  }|j                  t        j                  k(  s!|$ }}|rCt	        j
                  |D cg c]  }|j                   c}      }|dkD  r|j                  d       |dk(  r|j                  d       |S |dk(  r|j                  d       |S c c}w c c}w )zGenerate optimization advice.rW  z>Focus on reducing spatial concentration - errors are clusteredr|  z/Focus training on identified high-error regionsr<  zImprove edge rendering accuracy)r  r+   r   r   nprj   r8   rm   )rK   r=   r@   advicer  spatial_lossesavg_spatials          r'   r  z#MultiLossOptimizer._generate_advice  s    %+]]_[

lFZFZ8Z![[''~"N!1#5#5"NOKS ^_--MMKL  l*MM;< \"Ns   "B3B3B8)r`      r  rT   r)  )r   r   r   rV   r	   r   rI   rx  r9   r:   r   r/   r4   r  r2   r<   r  r   r  r%   r&   r'   rm  rm  W  s    =*eCHo *I
\ "&	|| << <<	
 
c:o	, #'/4S*_%/4  /4 
u||U\\>9	:	/4btCO'< S UYZ]U^ r&   rm  c                   H    e Zd ZdZdej
                  dej
                  fdZy)SPDERActivationz2SPDER: sin(x) * sqrt(|x|) - Periodic with damping.r   rP   c                     t        j                  |      t        j                  t        j                  |      dz         z  S )Nre   )r9   sinrq   r   rK   r   s     r'   rS   zSPDERActivation.forward
  s+    yy|ejj1)<===r&   Nr   r   r   rV   r9   r:   rS   r%   r&   r'   r  r    s     <> >%,, >r&   r  c                   H    e Zd ZdZdej
                  dej
                  fdZy)SPDERDerivativez(Derivative of SPDER for backpropagation.r   rP   c                 N   t        j                  |      dz   }t        j                  |      }t        j                  |      }t        j                  |dk(  t        j
                  |      |      }|t        j                  |      z  |d|z  z  t        j                  |      z  z   S )Nre   r   rf   )r9   r   rq   r   wherer   cosr  )rK   r   abs_x
sqrt_abs_xsign_xs        r'   rS   zSPDERDerivative.forward  s}    		!t#ZZ&
AVq[%//&*A6JEIIaL(Fa*n,EST+UUUr&   Nr  r%   r&   r'   r  r    s#    2V V%,, Vr&   r  c            	       t    e Zd ZdZ	 	 ddedededef fdZd Zdej                  d	ej                  fd
Z
dej                  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 xZS )MultiLossMLPz3MLP Classifier with Multi-Loss Diagnostic Learning.
input_sizehidden_sizeoutput_size	use_spderc                    t         |           || _        || _        || _        || _        t        j                  ||      | _        t        j                  ||      | _	        |rt               | _        t               | _        n t        j                         | _        d | _        t        d      | _        | j#                          y )Nr  )rk   )rH   rI   r  r  r  r  rI  rK  fc1fc2r  
activationr  activation_derivReLUrm  multi_loss_optimizerregister_hook)rK   r  r  r  r  rL   s        r'   rI   zMultiLossMLP.__init__  s    $&&" 99Z599[+6 -/DO$3$5D! ggiDO$(D! %7[$I! 	r&   c                      y)z%Register hooks for gradient analysis.Nr%   r  s    r'   r  zMultiLossMLP.register_hook7  s    r&   r   rP   c                    |j                  |j                  d      d      }| j                  |      | _        | j	                  | j                        | _        | j                  | j
                        | _        | j                  S )Nr   r   )viewr"  r  z1r  a1r  z2r  s     r'   rS   zMultiLossMLP.forward;  sZ    FF166!9b!((1+//$''*((477#wwr&   rN   y_predc                     |j                  |j                  d      ddd      }| j                  j                  ||d      }| j                  j	                  |      \  }}}||fS )z3Compute gradient from multi-loss diagnostic system.r   r`   r  N)rN   rO   )r  r"  r  r  r  )rK   rN   r  error_for_analysisr=   _r  r  s           r'   compute_multi_loss_gradientz(MultiLossMLP.compute_multi_loss_gradientC  sq     VVAFF1Iq"b9**== > 
 '+&?&?&P&PQW&X#e %''r&   upstream_gradc                 v    | j                   r,| j                   | j                  | j                        }||z  S |S )z&Get gradient through SPDER activation.)r  r  r  )rK   r  spder_derivs      r'   get_spder_gradientzMultiLossMLP.get_spder_gradientR  s9    >>d33?//8K ;..r&   c                     t        j                         5  t        j                  | j                  |      d      cd d d        S # 1 sw Y   y xY w)Nr`   ra   )r9   r  argmaxrS   r  s     r'   predictzMultiLossMLP.predictY  s6    ]]_ 	8<<QQ7	8 	8 	8s   &AAr~   c                 ~    | j                  |      |k(  j                         j                         j                         S rG   )r  r1   rj   rs   )rK   r   r~   s      r'   accuracyzMultiLossMLP.accuracy]  s0    Q1$++-22499;;r&   )r     r   T)r   r   r   rV   r   r2   rI   r  r9   r:   rS   r  r  r  r1   r  rW   rX   s   @r'   r  r    s    =AD:>3 3 !376 %,, (U\\ (5<< (TYT`T` (  8 8%,, 8<%,, <5<< <E <r&   r  ro  皙?modeltrain_loadertest_loaderepochsrq  multi_loss_weightc                    t        j                  | j                         |      }t        j                         }t        t              }t        |      D ]  }	| j                          t        t              }
d}d}t        |      D ]  \  }\  }}|j                  t              |j                  t              }}|j                           | |      } |||      }| j                  ||      \  }}|}|j                          t         j                  j"                  j%                  | j                         d       |j'                          |
dxx   |j)                         z  cc<   |
dxx   |j)                         z  cc<   |
dxx   |j*                  j)                         z  cc<   |j-                  d	      }||j/                  |      j1                         j)                         z  }||j3                  d      z  }|d
z  dk(  st4        j7                  d|	 d| dt9        |       d|j)                         dd|j*                  j)                         d
        ||z  }t4        j7                  d|	 d       t4        j7                  d|d       t4        j7                  d|
d   t9        |      z  dd|
d   t9        |      z  d       t;        j<                  j?                         d d      dd }t4        j7                  d|        |j@                  r%t4        j7                  d|j@                  d           tC        | |      }t4        j7                  d|dd       |d   jE                  |       |d    jE                  |       |d!   jE                  |
d   t9        |      z         |d"   jE                  |
d   t9        |      z          |S )#z0Train model with multi-loss diagnostic learning.rp  r   r,   )max_normcetotalmultir`   ra   d   Epoch  [/z] CE: .4fz Multi(diag): z
=== Epoch z Summary ===zTraining Accuracy: zLosses - CE: z, Multi(diag): c                     | d   S r   r%   r   s    r'   r  z'train_with_multi_loss.<locals>.<lambda>  s
    !A$ r&   Tr  Nr   zTop contributors: zAdvice: zTest Accuracy: 
	train_acctest_accce_loss
multi_loss)#rt  ru  rv  rI  CrossEntropyLossr   r  rl   trainr1   	enumeratetor   	zero_gradr  backwardr9   utilsclip_grad_norm_steprs   r>   r  eqr   r"  r  infor
  sortedr?   r  rB   evaluaterm   )r  r  r  r  rq  r  	optimizerr  loss_historyepochepoch_lossesepoch_correctepoch_total	batch_idxdatar(  logitsloss_cer  
loss_stater>   predaccsorted_lossesr  s                            r'   train_with_multi_lossr  e  s    

5++-"5I !!#Gt$Lv NU"5))2<)@ *	%I~f776?FIIf,=&D! 4[F ff-G
 "==dFKMAz !J ! HHNN**5+;+;+=*LNN ',,.0!Z__%66!!Z%:%:%?%?%AA! ==Q='DTWWV_0027799M6;;q>)K 3!#UG2i[#l2C1D E"<<>#.nZ=R=R=W=W=YZ]<^`O*	Z k)l5'67)#c34L.s</@@E F(1#l2CCCHJ	
 --335
 1	
 	(89))KK(:#A#A!#D"EFG E;/ohs^267 	[!((-Z ''1Y&&|D'9C<M'MN\")),w*?#lBS*ST]NU` r&   data_loaderrP   c                    | j                          d}d}t        j                         5  |D ]  \  }}|j                  t              |j                  t              }} | |      }|j                  d      }||j                  |      j                         j                         z  }||j                  d      z  } 	 ddd       ||z  S # 1 sw Y   ||z  S xY w)z$Evaluate model on given data loader.r   r`   ra   N)
evalr9   r  r  r   r  r  r   rs   r"  )r  r  correctr  r  r(  outputr
  s           r'   r  r    s    	JJLGE	 $' 	$LD&776?FIIf,=&D4[F==Q='Dtwwv**,1133GV[[^#E	$$ U?$ U?s   BC

CrS  c                 P   t        j                  | j                         d      }t        j                  |j                         d      }t        j                         }t        |      D ]  }| j                          |j                          t        |      D ]_  \  }\  }	}
|	j                  t              |
j                  t              }
}	|	j                  d      }|j                           | |	      }|j                  d      }|j                         |
j                         z
  j                         j                  |ddd      }|d| j                   z  z
  } ||      } ||j#                  |d      d	d	d	d
f   j%                  d      j'                  dddd            }t)        j*                  |dz         t)        j*                  d|z
  dz         z   j-                          }|j/                          |j1                          |j                           |||
      }t)        j*                   ||j#                  |d      d	d	d	d
f   j%                  d      j'                  dddd            dz         j-                          }|d|z  z   }|j/                          |j1                          |dz  dk(  s!t2        j5                  d| d| d|j7                         dd|j7                         d       b t9        | |      }t2        j5                  d| d|d        y	)z:Adversarial training with discriminator for error quality.ro  rp  r   r`   ra   r  r,   r   Nr  re   r     r  r  z
] D_loss: r  z	 G_loss: z: Train Accuracy = )rt  ru  rv  rI  r  rl   r  r  r  r   r"  r  r  r1   r   r#  r  r  r   r   r9   r   rj   r  r  r  r  rs   r  )r  rS  r  r  optimizer_Goptimizer_Dr  r  r  r  r(  
batch_sizer  r
  errorsfake_errors
real_score
fake_scored_lossr  g_losstotal_g_lossr  s                          r'   train_adversarialr    s    **U--/E:K**]557EBK!!#Gv /H)2<)@ '	:%I~f776?FIIf,=&D1J !!# 4[F==Q='DjjlV\\^388:BB:qRTVXYF !3):):#::K 'v.J&{'7'7
B'G4C4'P'Z'Z[\']'d'degijlnpr'stJ yyd!23eiiJQU@U6VV\\^^FOO !!# ff-G iik.>.>z2.NqRVSVRVw.W.a.abc.d.k.klnpqsuwy.z {  C  !C  D  I  I  K  KF"S6\1L!!#3!#fUG2i[
6;;=QTBU V%%+[[]3$79 :M'	:T UL1	fUG#6yoFG_/Hr&   __main__z:=== PyTorch Multi-Loss Diagnostic Learning with MNIST ===
)rW  z./dataT)rootr  download	transformF   rf   )r  shufflenum_workerszTraining samples: zTest samples: r  r  r   )r  r  r  r  zModel parameters: c              #   <   K   | ]  }|j                           y wrG   r   .0r   s     r'   	<genexpr>r+  O  s     (Oq(O   ,zDiscriminator parameters: c              #   <   K   | ]  }|j                           y wrG   r(  r)  s     r'   r+  r+  P  s     0_q0_r,  z=
============================================================z-TRAINING MODE 1: Standard Multi-Loss Trainingz=============================================================
)r  r  r  r  rq  r  zFINAL EVALUATIONzFinal Test Accuracy: r  z
--- Training History ---r  r  r  z: Train=z, Test=z0TRAINING MODE 2: Adversarial Training (Optional)zMULTI-LOSS DIAGNOSTIC ANALYSISr`   r  z"Loss breakdown for a sample batch:c                 <    | d   j                   j                         S r   )r5   rs   r   s    r'   r  r    s    qtzz?P r&   r  g{Gz?z  25sz: z
 (weight: z.2f))model_state_dictdiscriminator_state_dictr   zmulti_loss_mlp_mnist.pthz*
Model saved to 'multi_loss_mlp_mnist.pth'r2  zLoaded model test accuracy: )r  ro  r  r  )yr9   torch.nnrI  torch.nn.functional
functionalFtorch.optimrt  torch.utils.datar   r   torchvisiontorchvision.transforms
transformsdataclassesr   r   typingr   r   r	   r
   r   enumr   numpyr  loggingcollectionsr   basicConfigINFO	getLoggerr   r  r   r   is_availabler  r   r)   r4   r<   rY  rD   rZ   r   r   r   r   r   r   r   r   r  r+  r7  rE  rR  r[  rd  rm  r  r  r  r   r1   r  r  r  ComposeToTensor	Normalizer#  datasetsMNISTtrain_datasettest_datasetr  r  r
  r  r  r  rS  r   rv  printr   final_test_accr  zipr  r  r  r  nextitersample_datasample_targetsr  r  r  r"  r  r  r=   r  r  r*   r  r5   rs   r-   save
state_dictdictload
checkpointload_state_dict	final_accr%   r&   r'   <module>r\     s        0  + ( 8 8    #   ',,/Z [			8	$ 


 7 7 9fu	E nVH% &&4 &       # # #	"ryy 	" A
/ A
H/
) /
d@
) @
NZ
' Z
z3
+ 3
t
$ 
.
# 
>
# 
>2
% 2
r$
' $
N$
& $
V<
$ <
F$ $&
& 
J!
* !
H#
+ #
Ti i`>bii >Vbii VE<299 E<` "aaa a 	a
 	a aHL z e 2 	<H<H99<H <H 	<HF z
KKMN #
""

VV,$ I  ((..	 / M ''--	 . L mTWXYL\c5VWXK
KK$S%7$89:
KK.\!2 345 	
 	bj 
 ..<<??GM
KK$S(OE<L<L<N(O%OPQ$RST
KK,S0_MD\D\D^0_-_`a,bcd 
-	
9:	-(!L 
-	
	-e[1N
KK's';<= 

&'$-c,{2K\ZdMe.f$g H  Ixqc)C~FGH 
-	
<=	- 
-	
*+	-	JJL #'tK'8"9K..(K	 \{# )--k.>.>q.A1b"M ++>>?QR23 5PZ^_ 	\JD$zz 4'4*Btzz'8&=ZTWGXXYZ[	\\$ EJJ!,,.$1$<$<$>\* "	# KK=> 67J	*%789,I
KK.yo>?U V\ \s   BX,9X,,X5