U
    Õ¹j¡;  ã                   @   sŠ   d Z ddlZddlZddlmZ ddlmZ G dd„ dejƒZG dd„ dejƒZ	G dd	„ d	ejƒZ
G d
d„ dejƒZG dd„ dejƒZdS )u†  
MDD(ìš°ìš¸ì¦�) ë”¥ëŸ¬ë‹� ë¶„ë¥˜ê¸° - ëª¨ë�¸ êµ¬ì¡° ì •ì�˜

ëª¨ë�¸ ì œê³µì‚¬ì�˜ model.py ë¥¼ ê·¸ëŒ€ë¡œ ì�´ì‹� (BHITransformer ë°� í•˜ìœ„ ëª¨ë“ˆë§Œ ì‚¬ìš©,
í•™ìŠµ ì‹¤í—˜ìš©ì�´ì—ˆë�˜ ShallowNet ì�€ ì œì™¸).
ê°€ì¤‘ì¹˜(model/mdd/BHITransformer/models/bestModel_foldNN.pt)ëŠ” ì�´ êµ¬ì¡°ë¥¼ ë°”ê¾¸ì§€
ì•Šê³  ê·¸ëŒ€ë¡œ ë¡œë“œí•´ì„œ ì“´ë‹¤ - ì�´ íŒŒì�¼ ë‚´ìš©ì�„ ìž„ì�˜ë¡œ ìˆ˜ì •í•˜ë©´ ì•ˆ ë�œë‹¤.
é    N)ÚDropPathc                       s4   e Zd ZdZd‡ fdd	„	Zdejdœdd„Z‡  ZS )ÚPositionalEncodingu…  
    mode:
      - 'sinusoidal'     : ê³ ì •ì‹� ìœ„ì¹˜(í† í�° index ê¸°ë°˜) ì�¸ì½”ë”©
      - 'learnable'      : í•™ìŠµí˜• ìœ„ì¹˜(í† í�° index ê¸°ë°˜) ì�¸ì½”ë”©
      - 'time_fourier'   : ì ˆëŒ€ ì‹œê°„(ì´ˆ) -> Fourier features -> Linear -> D
      - 'time_learnable' : ì ˆëŒ€ ì‹œê°„(ì´ˆ) -> ìž‘ì�€ MLP -> D  (ì‹œê°„ ë²”ìœ„ ì •ê·œí™” í•„ìš”)
      - 'none'           : ì�¸ì½”ë”© ì—†ì�Œ
    Útime_learnableé   é   é   ç        ç       @c                    sü  t ƒ  ¡  || _|| _|| _|  dd ¡ d | _|  dd ¡ d | _d | _|| _	|| _
d| _|dk�r<t ||¡}tjd|tjd� d¡}	t tjd|dtjd�t d	¡ |  ¡}
t |	|
 ¡|d d …dd d…f< |d dk�rt |	|
d d
…  ¡|d d …dd d…f< n t |	|
 ¡|d d …dd d…f< |  d| d¡¡ n¼|dk�rbt t d||¡d ¡| _n–|dk�r¬tjdt |¡|d�}|  ddtj | ¡ t d| |¡| _nL|dk�rät t d|d ¡t ¡ t |d |¡¡| _n|dk�rðntdƒ‚d S )NÚpos_embed_bufÚ
time_omegag�íµ ÷Æ°>Ú
sinusoidalr   )Údtypeé   é   g     ˆÃ@éÿÿÿÿÚ	learnableg{®Gáz”?Útime_fourier)ÚstartÚendÚstepsr   ÚnonezTmode must be 'sinusoidal' | 'learnable' | 'time_fourier' | 'time_learnable' | 'none') ÚsuperÚ__init__ÚmodeÚ	embed_dimÚmax_lenÚregister_bufferÚ	pos_embedÚ	time_projÚtime_mlpÚ
time_min_sÚ
time_max_sÚtime_epsÚtorchÚzerosÚarangeÚfloat32Ú	unsqueezeÚexpÚmathÚlogÚsinÚcosÚnnÚ	ParameterÚrandnÚlogspaceÚlog10ÚpiÚLinearÚ
SequentialÚReLUÚ
ValueError)Úselfr   r   r   Útime_n_freqÚtime_max_freqr    r!   ÚpeÚpositionZdiv_termZfreqs_hz©Ú	__class__© ú,/var/www/html/bwave/python/mdd_model_arch.pyr      sH    

* * 


ý
zPositionalEncoding.__init__N©Útimesc                 C   s¨  | j dkr|S |j\}}}| j dkrT|| jd d …d |…d d …f  |j¡ |j¡ S | j dkrŽ|| jd d …d |…d d …f  |j¡ |j¡ S | j dk�r"|d krªtdƒ‚| ¡ dkrÈ| 	d¡ 
|d¡}| 	d¡| j ddd¡ |j¡ }tjt |¡t |¡gdd	�}|  | |j¡¡}|| S | j d
k�r¤|d k�r@tdƒ‚| ¡ dk�r`| 	d¡ 
|d¡}| j}| j}	|| t|	| | jƒ }
|  |
 	d¡ |j¡¡}|| S |S )Nr   r   r   r   z&times required for mode='time_fourier'r   r   r   ©Údimr   z(times required for mode='time_learnable')r   Úshaper   Útor   Údevicer
   r6   rC   r'   Úexpandr   Úviewr#   Úcatr+   r,   r   r    r!   Úmaxr"   r   )r7   ÚxrA   ÚBÚLÚDÚx_tr:   Út0Út1Zt_normr>   r>   r?   ÚforwardK   s6    

0
0"
zPositionalEncoding.forward)r   r   r   r   r   r	   )N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r#   ÚTensorrR   Ú__classcell__r>   r>   r<   r?   r      s          þ0r   c                       s&   e Zd Zd‡ fdd„	Zdd„ Z‡  ZS )ÚPatchEmbeddingÚgeluc           	         sØ   t ƒ  ¡  t|d ƒ}d}|| _|| _tjd|d|fd|fd�| _tj|||dfdd�| _tj	d|||d�| _
tj	||ddd�| _t |¡| _t |¡| _|dkr®t ¡ | _n&|dkrÂt ¡ | _n|dkrÔt ¡ | _d S )	Nr   ç333333Ó?r   )Úin_channelsÚout_channelsÚkernel_sizeÚstride)r   r   ÚGELUr5   ÚELU)r   r   ÚintÚ
patch_sizeÚpatch_strider-   ÚConv2dÚtemporal_EEGÚspatialÚConv1dÚtemporal_PPGÚprojÚDropoutÚdropoutÚ	LayerNormÚnormr`   Úactr5   ra   )	r7   r\   rc   rd   r   Útemporal_dimÚ
activationZmid_dimrl   r<   r>   r?   r   q   sJ    
  þ  þ  þ  þzPatchEmbedding.__init__c                 C   sr   |j d dkr8| d¡}|  |¡}|  |¡}| d¡}n
|  |¡}|  |¡}|  |¡}|  |¡}| 	ddd¡}|S )Nr   r   r   )
rD   r'   rf   rg   Úsqueezeri   ro   rl   rj   Úpermute)r7   rK   r>   r>   r?   rR   �   s    






zPatchEmbedding.forward)rZ   ©rS   rT   rU   r   rR   rX   r>   r>   r<   r?   rY   p   s   rY   c                       s&   e Zd Zd‡ fdd„	Zdd„ Z‡  ZS )	ÚSelfAttnBlocké   ç      à?Tc              	      s’   t ƒ  ¡  || _tj||d|d�| _t |¡| _t t 	||| ¡t 
¡ t |¡t 	|| |¡t |¡¡| _t |¡| _d | _d | _t|ƒ| _d S ©NT)Úbatch_firstrl   ©r   r   ÚisPreLNr-   ÚMultiheadAttentionÚattnrm   Úln1r4   r3   r5   rk   ÚffnÚln2Ú	last_attnÚlast_attn_outr   Ú	drop_path©r7   rC   ÚheadsÚ	mlp_ratiorl   Ú	drop_probr{   r<   r>   r?   r   £   s    
ûzSelfAttnBlock.__init__c                 C   s  | j rŒ|  |¡}| j|||dd�\}}|| _|jr<| j ¡  || _|jrR| j ¡  ||  |¡ }|  |¡}|  	|¡}||  |¡ }|||fS | j|||dd�\}}|| _|jr¸| j ¡  || _|jrÎ| j ¡  |  || ¡}|  	|¡}|  || ¡}|||fS d S ©NF)Úaverage_attn_weights©
r{   r~   r}   r‚   Úrequires_gradÚretain_gradr�   rƒ   r€   r   )r7   rK   Úx_normÚattn_outr}   Zx_norm2Úfr>   r>   r?   rR   µ   s2    








zSelfAttnBlock.forward)rv   rv   rw   rw   Trt   r>   r>   r<   r?   ru   ¢   s   ru   c                       s&   e Zd Zd‡ fdd„	Zdd„ Z‡  ZS )	ÚCrossAttnBlockrv   rw   Tc              	      s’   t ƒ  ¡  || _tj||d|d�| _t |¡| _t t 	||| ¡t 
¡ t |¡t 	|| |¡t |¡¡| _t |¡| _d | _d | _t|ƒ| _d S rx   rz   r„   r<   r>   r?   r   Ø   s    
ûzCrossAttnBlock.__init__c           	      C   s  | j rŒ|  |¡}| j|||dd�\}}|| _|jr<| j ¡  || _|jrR| j ¡  ||  |¡ }|  |¡}|  	|¡}||  |¡ }|||fS | j|||dd�\}}|| _|jr¸| j ¡  || _|jrÎ| j ¡  |  || ¡}|  	|¡}|  || ¡}|||fS d S rˆ   rŠ   )	r7   ÚqÚkvÚq_normrŽ   r}   rK   r�   r�   r>   r>   r?   rR   ê   s2    








zCrossAttnBlock.forward)rv   rv   rw   rw   Trt   r>   r>   r<   r?   r�   ×   s   r�   c                       s8   e Zd Zd‡ fdd„	Zdd„ Zdd„ Zddd„Z‡  ZS )ÚBHITransformerr   r   r   r   r   é
   r   r	   r[   rw   TÚFullc              
      sº  t ƒ  ¡  dddddddg| _|| jkr>td|› d	| j› �ƒ‚|| _t|||ˆ||	ƒ| _t|||ˆ||	ƒ| _|| _t	ˆ||||||d
�| _
t	ˆ||||||d
�| _t ‡ ‡‡‡‡fdd„t|ƒD ƒ¡| _t ‡ ‡‡‡‡fdd„t|ƒD ƒ¡| _t ‡ ‡‡‡‡fdd„t|ƒD ƒ¡| _t ‡ ‡‡‡‡fdd„t|ƒD ƒ¡| _| jdk�rPdˆ }n| jdk�rfdˆ }ndˆ }ˆ}t t |¡t ||¡t ¡ t ˆ d ¡t ||¡¡| _|  | j¡ d S )Nr–   ÚSelfÚCrossÚSelf_EEGÚSelf_PPGÚ	Cross_E2PÚ	Cross_P2EzUnknown ablation_mode: z. Choose from )r   r   r8   r9   r    r!   c              
      s    g | ]}t ˆˆd ˆ ˆˆd�‘qS ©rv   )rC   r…   r†   rl   r‡   r{   ©ru   ©Ú.0Ú_©rl   Údroppathr   r{   Ú	num_headsr>   r?   Ú
<listcomp>)  s     z+BHITransformer.__init__.<locals>.<listcomp>c              
      s    g | ]}t ˆˆd ˆ ˆˆd�‘qS r�   rž   rŸ   r¢   r>   r?   r¥   *  s     c              
      s    g | ]}t ˆˆd ˆ ˆˆd�‘qS r�   ©r�   rŸ   r¢   r>   r?   r¥   ,  s     c              
      s    g | ]}t ˆˆd ˆ ˆˆd�‘qS r�   r¦   rŸ   r¢   r>   r?   r¥   -  s     r   )r—   r˜   rv   r   gš™™™™™É?)r   r   Úvalid_modesr6   Úablation_moderY   Ú	eeg_embedÚ	ppg_embedÚpos_moder   Úeeg_posÚppg_posr-   Ú
ModuleListÚrangeÚself_attn_eegÚself_attn_ppgÚcross_attn_e2pÚcross_attn_p2er4   rm   r3   r`   rk   Ú
classifierÚapplyÚ_init_weights)r7   Úeeg_channelsÚppg_channelsÚeeg_patch_sizeÚppg_patch_sizeÚeeg_patch_strideÚppg_patch_strider   rp   rq   r¤   Ú
num_layersÚnum_classesÚpos_encoding_modeZ
pe_max_lenr8   r9   r    r!   rl   r£   r{   r¨   Ú	input_dimZbottleneck_dimr<   r¢   r?   r     s8    

&&&&



ûzBHITransformer.__init__c                 C   sf   t |tjƒr6tj |j¡ |jd k	rbtj |jd¡ n,t |tjƒrbtj |jd¡ tj |jd¡ d S )Nr   g      ð?)	Ú
isinstancer-   r3   ÚinitÚxavier_uniform_ÚweightÚbiasÚ	constant_rm   )r7   Úmr>   r>   r?   r¶   B  s    
zBHITransformer._init_weightsc                 C   s.   |j dd�}|jdd�\}}tj||gdd�S )Nr   rB   r   )ÚmeanrJ   r#   rI   )r7   rK   Zavg_poolZmax_poolr¡   r>   r>   r?   Ú_get_bhi_summaryK  s    zBHITransformer._get_bhi_summaryNc                 C   sô  |   |¡}|  |¡}d}|j\}}	}
|j\}}}
tj|	|jd�| j j | j jd  | }tj||jd�| jj | jjd  | }| d¡ 	|d¡}| d¡ 	|d¡}| j
 d¡rÎ| j||d�}| j||d�}n|  |¡}|  |¡}g }| jdk�r |}| jD ]}||ƒ\}}
}
qü| |  |¡¡ | jd	k�r\|}| jD ]}||ƒ\}}
}
�q6| |  |¡¡ | jd
k�rš|}| jD ]}|||ƒ\}}
}
�qr| |  |¡¡ | jdk�rØ|}| jD ]}|||ƒ\}}
}
�q°| |  |¡¡ tj|dd�}|  |¡}|S )Ng      p@)rF   r   r   r   Útimer@   )r–   r—   r™   )r–   r—   rš   )r–   r˜   r›   )r–   r˜   rœ   rB   )r©   rª   rD   r#   r%   rF   rd   rc   r'   rG   r«   Ú
startswithr¬   r­   r¨   r°   ÚappendrÉ   r±   r²   r³   rI   r´   )r7   ÚeegÚppgZ	eeg_timesZ	ppg_timesZeeg_tokZppg_tokÚfsrL   ÚLer¡   ZLpZeeg_dyn_timeZppg_dyn_timeZeeg_featZppg_featZfinal_vectorsZself_eegÚblkZself_ppgZ	cross_e2pZ	cross_p2eZfinal_vectorÚlogitsr>   r>   r?   rR   P  sL    

((






zBHITransformer.forward)r   r   r   r   r   r•   r   r	   r[   rw   Tr–   )NN)rS   rT   rU   r   r¶   rÉ   rR   rX   r>   r>   r<   r?   r”     s                      ö5	r”   )rV   r)   r#   Útorch.nnr-   Ztimm.layersr   ÚModuler   rY   ru   r�   r”   r>   r>   r>   r?   Ú<module>   s   ^255