Ë
    z§jh  ã                  óÞ   — d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	Z	ddl
Z
ddlZddlZddlmZmZ ddlmZ  G d	„ d
e«      Zddd„Zdd„Ze G d„ d«      «       Zddd„Zdd„Zddd„Zdd„Zy)zKShared safe training utilities. Real training is gated by dataset metadata.é    )Úannotations)Ú	dataclass)ÚPath)ÚAnyN)ÚTensorÚnn)ÚGroupShuffleSplitc                  ó   — e Zd Zy)ÚDatasetContractErrorN)Ú__name__Ú
__module__Ú__qualname__© ó    úmodels/training.pyr   r      s   … r   r   c                ó  — t        j                  | «       t        j                   j                  | «       t        j                  | «       t        j
                  j                  «       r t        j
                  j                  | «       y y )N)ÚrandomÚseedÚnpÚtorchÚmanual_seedÚcudaÚis_availableÚmanual_seed_all)r   s    r   Úseed_everythingr      sN   € Ü
‡K�K�Ô”r—y‘y—~‘~ dÔ+¬U×->Ñ->¸tÔ-DÜ‡z�z×ÑÔ ¤%§*¡*×"<Ñ"<¸TÕ"BÐ r   c           
     óŠ  — |j                  «       }|j                  «       dk(  s|j                  «       st        d«      ‚| j                  |j                  k7  s|j                  |j                  k7  rMt        dt        | j                  «      › dt        |j                  «      › dt        |j                  «      › �«      ‚t        j                  | «      j                  «       st        d«      ‚| |   ||   }}t        j                  |«      j                  «       st        d«      ‚||z
  j                  «       j                  «       S )Nr   z@Refusing training: target validity mask has no validated labels.zCprediction, target, and valid mask must have identical shapes; got z, zmodel prediction is non-finitez#a target marked valid is non-finite)ÚboolÚnumelÚanyr   ÚshapeÚtupler   ÚisfiniteÚallÚsquareÚmean)ÚpredÚtargetÚvalidÚpÚys        r   Ú
masked_mser+      sM  € Ø�J‰J‹L€EØ‡{�{ƒ}˜Ò §¡¤Ô4Hð  JLó  5Mð  /MØ‡z�z�V—\‘\Ò! U§[¡[°F·L±LÒ%@Ü"Ð%hÔinÐos×oyÑoyÓizÐh{Ð{}ô  Dð  EK÷  EQñ  EQó  Rð  ~Sð  SUô  V[ð  \a÷  \gñ  \gó  Vhð  Uið  $jó  kð  	kÜ�>‰>˜$Ó×#Ñ#Ô%Ô-AÐBbÓ-cÐ'cà�‰;˜˜u™€q€AÜ�>‰>˜!Ó× Ñ Ô"Ô*>Ð?dÓ*eÐ$eØ�‰E�>‰>Ó× Ñ Ó"Ð"r   c                  ó:   — e Zd ZU dZded<   dZded<   dd„Zdd„Zy)	ÚTrainOnlyScalerNznp.ndarray | Noner%   Úscalec                óø  — |j                   |j                   k7  rt        d«      ‚t        j                  t        j                  ||   «       «      rt        d«      ‚t        j
                  |j                   d   t        j                  ¬«      | _        t        j                  |j                   d   t        j                  ¬«      | _	        t        |j                   d   «      D ]•  }||d d …|f   |f   }t        |«      sŒ|j                  «       | j                  |<   |j                  «       dk  r#t        t        |j                  «       «      d«      nt        |j                  «       «      | j                  |<   Œ— | S )Nú"feature_valid must exactly match xz$observed input feature is non-finiteé   ©Údtypeg:Œ0âŽyE>g      ð?)r    r   r   r   r"   ÚzerosÚfloat64r%   Úonesr.   ÚrangeÚlenÚstdÚmaxÚfloat)ÚselfÚxÚfeature_validÚjÚobserveds        r   ÚfitzTrainOnlyScaler.fit    s6  € Ø�7‰7�m×)Ñ)Ò)Ô1EÐFjÓ1kÐ+kÜ�6‰6”2—;‘;˜q Ñ/Ó0Ð0Ô1Ô9MÐNtÓ9uÐ3uÜ—(‘(˜1Ÿ7™7 1™:¬B¯J©JÔ7ˆŒ	ÄBÇGÁGÈAÏGÉGÐTUÉJÔ]_×]gÑ]gÔDh¸¼Ü�q—w‘w˜q‘zÖ"ˆAØ�}¢Q q SÑ)¨!Ð+Ñ,ˆHÜ�8�}¨8¯=©=«?˜dŸi™i¨™lÐks×kwÑkwÓkyÐz~Òk~Ì#ÌeÐT\×T`ÑT`ÓTbÓNcÐdfÔJgô  EJð  KS÷  KWñ  KWó  KYó  EZ¸D¿J¹JÀqºMð #ð ˆr   c                ó,  — | j                   �| j                  €t        d«      ‚|j                  |j                  k7  rt	        d«      ‚t        j                  ||| j                   z
  | j                  z  d«      j                  t
        j                  «      S )Nz"fit scaler on training split firstr0   g        )	r%   r.   ÚRuntimeErrorr    r   r   ÚwhereÚastypeÚfloat32)r<   r=   r>   s      r   Ú	transformzTrainOnlyScaler.transform(   st   € Ø�9‰9Ð §
¡
Ð 2¼,ÐGkÓ:lÐ4lØ�7‰7�m×)Ñ)Ò)Ô1EÐFjÓ1kÐ+kÜ�x‰x˜¨¨D¯I©I©¸¿¹Ñ'CÀRÓH×OÑOÔPR×PZÑPZÓ[Ð[r   )r=   ú
np.ndarrayr>   rH   Úreturnz'TrainOnlyScaler')r=   rH   r>   rH   rI   rH   )r   r   r   r%   Ú__annotations__r.   rA   rG   r   r   r   r-   r-      s"   … à"€DÐ
Ó"¸t EÐ+<Ó$Cóô\r   r-   c           	     óâ   — t        t        j                  | «      «      dk  rt        d«      ‚t	        t        dd|¬«      j                  t        j                  t        | «      «      | ¬«      «      S )Né   zRNeed at least two independent group IDs; random point/patch splits are prohibited.r1   g      Ð?)Ún_splitsÚ	test_sizeÚrandom_state)Úgroups)r8   r   Úuniquer   Únextr	   Úsplitr4   )rP   r   s     r   Úgroup_splitrT   -   sf   € Ü
Œ2�9‰9�VÓÓ Ò!Ô)=ð  ?Só  *Tð  $TÜÔ!¨1¸È$ÔO×UÑUÔVX×V^ÑV^Ô_bÐciÓ_jÓVkÐtzÐUÓ{Ó|Ð|r   c           	     óò  — t        | j                  «      }h d£}||k  s&t        dt        |«      › dt        ||z
  «      › �«      ‚| d   | d   j	                  t
        «      | d   | d   j	                  t
        «      | d   f\  }}}}}|j                  d	k7  s}|j                  |j                  k7  sd|j                  d	k7  sU|j                  d
   |j                  d
   k7  s6|j                  |j                  k7  s|j                  |j                  d
   fk7  rt        d«      ‚|j                  «       st        d«      ‚t        j                  | d   j	                  t        «      dk(  «      st        d«      ‚|||||fS )N>   r=   r*   Úgroup_idÚlabel_statusr>   Útraining_validzTraining NPZ requires z
; missing r=   r>   r*   rX   rV   rL   r   zpcontract requires x/feature_valid [samples,features], y/training_valid [samples,targets], and group_id [samples]zQRefusing training: no externally validated real labels (training_valid is empty).rW   Úexternally_validatedzNRefusing training: label_status must be externally_validated for every sample.)ÚsetÚfilesr   ÚsortedrE   r   Úndimr    r   r   r#   Ústr)ÚdÚkeysÚrequiredr=   r>   r*   r(   rP   s           r   Ú_require_contractrb   1   sÏ  € Üˆq�w‰w‹<€DÚX€HØ�tÒÔ#7Ð:PÔQWÐX`ÓQaÐPbÐblÔmsÐt|ð  @Dñ  uDó  nEð  mFð  9Gó  $Hð  HØ)*¨3©°°?Ñ1C×1JÑ1JÌ4Ó1PÐRSÐTWÑRXÐZ[Ð\lÑZm×ZtÑZtÔuyÓZzÐ|}ð  Iñ  }Jð  *JÑ&€A€}�a˜ Ø‡v�v�‚{�m×)Ñ)¨Q¯W©WÒ4¸¿¹À!ºÀqÇwÁwÈqÁzÐUV×U\ÑU\Ð]^ÑU_ÒG_Ðch×cnÑcnÐrs×ryÑryÒcyð  ~D÷  ~Jñ  ~Jð  OP÷  OVñ  OVð  WXñ  OYð  N[ò  ~[Ü"ð  $Vó  Wð  	WØ�9‰9Œ;Ô2ð  4Gó  Hð  HÜ�6‰6�!�NÑ#×*Ñ*¬3Ó/Ð3IÑIÔJÜ"Ð#sÓtÐtØˆa�˜ Ð-Ð-r   c           	     óN  — t        |«       t        j                  |d¬«      }t        |«      \  }}}}	}
t	        |	|«      \  }}t        «       j                  ||   |
|   «      }t        j                  |j                  ||
«      |
j                  t        j                  «      gd¬«      }t        j                  ||   t        j                  ¬«      t        j                  ||   t        j                  ¬«      t        j                  ||   «      }}}t        j                  j                  | j                  «       d«      }| j!                  «        t#        |«      D ]E  }|j%                  «        t'         | |«      ||«      }|j)                  «        |j+                  «        ŒG t-        |«      }|j.                  j1                  dd¬«       t        j2                  | j5                  «       |j6                  |j8                  t        j:                  |	|   «      j=                  «       d	œ|«       | j?                  «        t        j@                  «       5   | t        j                  ||   t        j                  ¬«      «      }t'        |t        j                  ||   t        j                  ¬«      t        j                  ||   «      «      }d
d
d
«       dtC        tE        |«      «      tC        tE        |«      «      tG        jI                  «       «      tG        «      dœS # 1 sw Y   ŒUxY w)zJReference entry point for tabular/vector models with strict data contract.F©Úallow_pickler1   )Úaxisr2   gü©ñÒMbP?T)ÚparentsÚexist_ok)Ú
state_dictÚscaler_meanÚscaler_scaleÚtrain_groupsNÚtrained)ÚstatusÚtrain_samplesÚtest_samplesÚ
train_lossÚheldout_masked_mse)%r   r   Úloadrb   rT   r-   rA   ÚconcatenaterG   rE   rF   r   Ú	as_tensorÚoptimÚAdamÚ
parametersÚtrainr7   Ú	zero_gradr+   ÚbackwardÚstepr   ÚparentÚmkdirÚsaveri   r%   r.   rQ   ÚtolistÚevalÚno_gradÚintr8   r;   Údetach)ÚmodelÚdatasetÚ
checkpointÚepochsr   r_   r=   r*   r(   rP   r>   ry   ÚtestÚscalerÚxtÚytÚmtÚoptÚ_ÚlossÚpathr&   Úheldouts                          r   Úfit_validated_npzr“   =   sA  € ä�DÔœrŸw™w w¸UÔC˜1Ôj{Ð|}Ój~ÑEgÀQÈÈ5ÐRXÐZgÜ˜f dÓ+�K€Eˆ4´oÓ6G×6KÑ6KÈAÈeÉHÐVcÐdiÑVjÓ6k¨VÔqs×qÑqð  BH÷  BRñ  BRð  STð  Vcó  Bdð  fs÷  fzñ  fzô  {}÷  {Eñ  {Eó  fFð  AGð  NOô  rPÐmnÜ—/‘/ ! E¡(´%·-±-Ô@Ä%Ç/Á/ÐRSÐTYÑRZÔbg×boÑboÔBpÔrw÷  sBñ  sBð  CHð  INñ  COó  sPˆBˆ€BÜ
�+‰+×
Ñ
˜5×+Ñ+Ó-¨tÓ
4€C°e·k±k´mÜ�6Ž]ˆØ�‰Œ¤
©5°«9°b¸"Ó =˜¸t¿}¹}¼ÐPS×PXÑPXÕPZð ä�
Ó€D˜TŸ[™[×.Ñ.°tÀdÐ.ÔKÜ	‡J�J˜e×.Ñ.Ó0ÀÇÁÐ^d×^jÑ^jÔ|~÷  }Fñ  }Fð  GMð  NSñ  GTó  }U÷  }\ñ  }\ó  }^ñ  _ð  aeô  fà	‡J�J„LÜ	�‰�Ù”U—_‘_ Q t¡W´E·M±MÔBÓCˆÌzÐZ^Ô`e×`oÑ`oÐpqÐrvÑpwô  @E÷  @Mñ  @Mô  aNô  PU÷  P_ñ  P_ð  `eð  fjñ  `kó  Pló  PmÀW÷ 
à´#´c¸%³j³/ÔSVÔWZÐ[_ÓW`ÓSaÔqvÐw{÷  xCñ  xCó  xEó  rFô  ^cð  dkó  ^lñ  mð  m÷ 
ˆús   ÉA8LÌL$c                ó²   — t        j                  | d¬«      }t        |«      \  }}}}}t        |j                  d   «      t        |j                  d   «      fS )zNValidate before exposing dimensions, so malformed NPZs yield a contract error.Frd   r1   )r   rs   rb   rƒ   r    )r†   r_   r=   r*   r�   s        r   Úvalidated_contract_dimensionsr•   M   sI   € ä
�‰� eÔ,€AÜ% aÓ(�M€A€qˆ!ˆQ�Üˆq�w‰w�q‰z‹?œC §¡¨¡
›OÐ+Ð+r   )é   )r   rƒ   rI   ÚNone)r&   r   r'   r   r(   r   rI   r   )rP   rH   r   rƒ   rI   ztuple[np.ndarray, np.ndarray])r_   r   rI   zAtuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray])é   r–   )r…   z	nn.Moduler†   ú
str | Pathr‡   r™   rˆ   rƒ   r   rƒ   rI   zdict[str, Any])r†   r™   rI   ztuple[int, int])Ú__doc__Ú
__future__r   Údataclassesr   Úpathlibr   Útypingr   Újsonr   Únumpyr   r   r   r   Úsklearn.model_selectionr	   Ú
ValueErrorr   r   r+   r-   rT   rb   r“   r•   r   r   r   Ú<module>r£      sh   ðÙ QÝ "Ý !Ý Ý ß Û Û ß Ý 5ä ,˜:Ô ,ôCó	#ð ÷\ð \ó ð\ô}ó
.ômô ,r   