o
    *jN                     @   s  d dl Z d dlZd dlZd dlmZ d dlZd dlmZ d dlmZ	 d dl
mZ e dg dZe dg d	Zd
eej ej_d
eej ej_eedrSejZn	G dd dejZG dd dejjZG dd dejZdd Zdd Zdd Zdd Zdd Zd
ddZ G dd dej!Z"G d d! d!ej!Z#d
d"d#Z$G d$d% d%ej%Z&G d&d' d'ej%Z'G d(d) d)e(Z)d*d+ Z*				,	,	-	.d6d/d0Z+d1d2 Z,		.	3	.d7d4d5Z-dS )8    N)partial)nn)
functional)	model_zooGlobalParamswidth_coefficientdepth_coefficient
image_sizedropout_ratenum_classesZbatch_norm_momentumZbatch_norm_epsilondrop_connect_ratedepth_divisor	min_depthinclude_top	BlockArgs
num_repeatkernel_sizestrideexpand_ratioinput_filtersoutput_filtersse_ratioid_skipNSiLUc                   @      e Zd Zdd ZdS )Swishc                 C   s   |t | S r   )torchsigmoidselfx r$   r/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/models/cv/face_emotion/efficient/utils.pyforward"   s   zSwish.forwardN__name__
__module____qualname__r&   r$   r$   r$   r%   r           r   c                   @   s$   e Zd Zedd Zedd ZdS )SwishImplementationc                 C   s   |t | }| | |S r   )r   r    Zsave_for_backward)ctxiresultr$   r$   r%   r&   (   s   
zSwishImplementation.forwardc                 C   s,   | j d }t|}||d|d|     S )Nr      )Zsaved_tensorsr   r    )r-   Zgrad_outputr.   Z	sigmoid_ir$   r$   r%   backward.   s   

zSwishImplementation.backwardN)r(   r)   r*   staticmethodr&   r1   r$   r$   r$   r%   r,   &   s
    
r,   c                   @   r   )MemoryEfficientSwishc                 C   s
   t |S r   )r,   applyr!   r$   r$   r%   r&   7   s   
zMemoryEfficientSwish.forwardNr'   r$   r$   r$   r%   r3   5   r+   r3   c                 C   sd   |j }|s| S |j}|j}| |9 } |p|}t|t| |d  | | }|d|  k r.||7 }t|S )a[  Calculate and round number of filters based on width multiplier.
       Use width_coefficient, depth_divisor and min_depth of global_params.
    Args:
        filters (int): Filters number to be calculated.
        global_params (namedtuple): Global params of the model.
    Returns:
        new_filters: New filters number after calculating.
       g?)r   r   r   maxint)filtersglobal_params
multiplierZdivisorr   Znew_filtersr$   r$   r%   round_filters;   s   	r;   c                 C   s    |j }|s| S tt||  S )a>  Calculate module's repeat number of a block based on depth multiplier.
       Use depth_coefficient of global_params.
    Args:
        repeats (int): num_repeat to be calculated.
        global_params (namedtuple): Global params of the model.
    Returns:
        new repeat: New repeat number after calculating.
    )r	   r7   mathceil)Zrepeatsr9   r:   r$   r$   r%   round_repeatsS   s   	r>   c                 C   s|   d|  krdksJ d J d|s| S | j d }d| }|}|tj|dddg| j| jd7 }t|}| | | }|S )zDrop connect.
    Args:
        input (tensor: BCWH): Input of this structure.
        p (float: 0.0~1.0): Probability of drop connection.
        training (bool): The running mode.
    Returns:
        output: Output after drop connection.
    r   r0   zp must be in range of [0,1])dtypedevice)shaper   Zrandr?   r@   floor)ZinputspZtrainingZ
batch_sizeZ	keep_probZrandom_tensorZbinary_tensoroutputr$   r$   r%   drop_connectb   s   $	

rE   c                 C   s0   t | tr	| | fS t | tst | tr| S t )zObtain height and width from x.
    Args:
        x (int, tuple or list): Data size.
    Returns:
        size: A tuple or list (H,W).
    )
isinstancer7   listtuple	TypeError)r#   r$   r$   r%   get_width_and_height_from_size}   s
   
rJ   c                 C   sZ   | du rdS t | \}}t|tr|n|d }tt|| }tt|| }||gS )ag  Calculates the output image size when using Conv2dSamePadding with a stride.
       Necessary for static padding. Thanks to mannatsingh for pointing this out.
    Args:
        input_image_size (int, tuple or list): Size of input image.
        stride (int, tuple or list): Conv2d operation's stride.
    Returns:
        output_image_size: A list [H,W].
    Nr   )rJ   rF   r7   r<   r=   )Zinput_image_sizer   Zimage_heightZimage_widthr$   r$   r%   calculate_output_image_size   s   	rK   c                 C      | du rt S tt| dS )a*  Chooses static padding if you have specified an image size, and dynamic padding otherwise.
       Static padding is necessary for ONNX exporting of models.
    Args:
        image_size (int or tuple): Size of the image.
    Returns:
        Conv2dDynamicSamePadding or Conv2dStaticSamePadding.
    Nr
   )Conv2dDynamicSamePaddingr   Conv2dStaticSamePaddingrM   r$   r$   r%   get_same_padding_conv2d      rP   c                       s2   e Zd ZdZ				d fdd	Zdd Z  ZS )	rN   z2D Convolutions like TensorFlow, for a dynamic image size.
       The padding is operated in forward function by calculating dynamically.
    r0   Tc              
      sJ   t  ||||d||| t| jdkr| j| _d S | jd gd | _d S )Nr   r5   )super__init__lenr   )r"   in_channelsout_channelsr   r   dilationgroupsbias	__class__r$   r%   rS      s   z!Conv2dDynamicSamePadding.__init__c              	   C   s  |  dd  \}}| j  dd  \}}| j\}}t|| t|| }}	|d | jd  }
t|
|d | jd   d | d}|	d | jd  }t||d | jd   d | d}|dksg|dkr}t||d ||d  |d ||d  g}t	|| j| j
| j| j| j| jS Nr0   r   r5   )sizeweightr   r<   r=   r6   rW   Fpadconv2drY   paddingrX   )r"   r#   ihiwkhkwshswohowZa1pad_hZa2pad_wr$   r$   r%   r&      s   
$$ z Conv2dDynamicSamePadding.forward)r0   r0   r0   Tr(   r)   r*   __doc__rS   r&   __classcell__r$   r$   rZ   r%   rN      s    rN   c                       s.   e Zd ZdZ		d fdd	Zdd Z  ZS )	rO   z2D Convolutions like TensorFlow's 'SAME' mode, with the given input image size.
       The padding module is calculated in construction function, then used in forward.
    r0   Nc                    s^  t  j||||fi | t| jdkr| jn| jd gd | _|d us&J t|tr/||fn|\}}| j dd  \}	}
| j\}}t	|| t	|| }}|d | jd  }t
||	d | jd   d | d}|d | jd  }t
||
d | jd   d | d}|dks|dkrt|d ||d  |d ||d  f| _d S t | _d S )Nr5   r   r]   r0   )rR   rS   rT   r   rF   r7   r_   r^   r<   r=   r6   rW   r   	ZeroPad2dstatic_paddingIdentity)r"   rU   rV   r   r   r
   kwargsrd   re   rf   rg   rh   ri   rj   rk   b1rl   b2rm   rZ   r$   r%   rS      s>   

$$

z Conv2dStaticSamePadding.__init__c              	   C   0   |  |}t|| j| j| j| j| j| j}|S r   )	rr   r`   rb   r_   rY   r   rc   rW   rX   r!   r$   r$   r%   r&      s
   
zConv2dStaticSamePadding.forward)r0   Nrn   r$   r$   rZ   r%   rO      s    rO   c                 C   rL   )a0  Chooses static padding if you have specified an image size, and dynamic padding otherwise.
       Static padding is necessary for ONNX exporting of models.
    Args:
        image_size (int or tuple): Size of the image.
    Returns:
        MaxPool2dDynamicSamePadding or MaxPool2dStaticSamePadding.
    NrM   )MaxPool2dDynamicSamePaddingr   MaxPool2dStaticSamePaddingrM   r$   r$   r%   get_same_padding_maxPool2d   rQ   rz   c                       s2   e Zd ZdZ				d	 fdd	Zdd Z  ZS )
rx   z2D MaxPooling like TensorFlow's 'SAME' mode, with a dynamic image size.
       The padding is operated in forward function by calculating dynamically.
    r   r0   Fc                    s   t  |||||| t| jtr| jgd n| j| _t| jtr'| jgd n| j| _t| jtr:| jgd | _d S | j| _d S )Nr5   )rR   rS   rF   r   r7   r   rW   )r"   r   r   rc   rW   return_indices	ceil_moderZ   r$   r%   rS     s$   z$MaxPool2dDynamicSamePadding.__init__c              	   C   s  |  dd  \}}| j\}}| j\}}t|| t|| }}	|d | jd  }
t|
|d | jd   d | d}|	d | jd  }t||d | jd   d | d}|dksa|dkrwt||d ||d  |d ||d  g}t	|| j| j| j
| j| j| jS r\   )r^   r   r   r<   r=   r6   rW   r`   ra   
max_pool2drc   r|   r{   )r"   r#   rd   re   rf   rg   rh   ri   rj   rk   c1rl   c2rm   r$   r$   r%   r&     s   

$$ z#MaxPool2dDynamicSamePadding.forward)r   r0   FFrn   r$   r$   rZ   r%   rx     s    rx   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )ry   z2D MaxPooling like TensorFlow's 'SAME' mode, with the given input image size.
       The padding module is calculated in construction function, then used in forward.
    Nc                    s  t  j||fi | t| jtr| jgd n| j| _t| jtr'| jgd n| j| _t| jtr7| jgd n| j| _|d usAJ t|trJ||fn|\}}| j\}}| j\}	}
t||	 t||
 }}|d | jd  }t	||d | jd   d | d}|d | jd  }t	||d | jd   d | d}|dks|dkrt
|d ||d  |d ||d  f| _d S t
 | _d S )Nr5   r0   r   )rR   rS   rF   r   r7   r   rW   r<   r=   r6   r   rq   rr   rs   )r"   r   r   r
   rt   rd   re   rf   rg   rh   ri   rj   rk   Zd1rl   Zd2rm   rZ   r$   r%   rS   2  sJ   

$$

z#MaxPool2dStaticSamePadding.__init__c              	   C   rw   r   )	rr   r`   r}   r   r   rc   rW   r|   r{   r!   r$   r$   r%   r&   L  s
   
z"MaxPool2dStaticSamePadding.forwardr   rn   r$   r$   rZ   r%   ry   -  s    ry   c                   @   s@   e Zd ZdZedd Zedd Zedd Zedd	 Zd
S )BlockDecoderz\Block Decoder for readability,
       straight from the official TensorFlow repository.
    c              
   C   s   t | tsJ | d}i }|D ]}td|}t|dkr*|dd \}}|||< qd|v r7t|d dksMt|d dkrK|d d |d d ksMJ tt|d t|d	 t|d d gt|d
 t|d t|d d|v ryt|d ndd| vdS )a2  Get a block through a string notation of arguments.
        Args:
            block_string (str): A string notation of arguments.
                                Examples: 'r1_k3_s11_e1_i32_o16_se0.25_noskip'.
        Returns:
            BlockArgs: The namedtuple defined at the top of this file.
        _z(\d.*)r5   Nsr0   r   rker.   osenoskipr   )rF   strsplitrerT   r   r7   float)block_stringopsoptionsopZsplitskeyvaluer$   r$   r%   _decode_block_stringX  s,   	





z!BlockDecoder._decode_block_stringc                 C   s   d| j  d| j d| jd | jd f d| j d| j d| j g}d| j  k r,dkr6n n|d	| j  | jd
u r@|d d	|S )zEncode a block to a string.
        Args:
            block (namedtuple): A BlockArgs type argument.
        Returns:
            block_string: A String form of BlockArgs.
        zr%dzk%dzs%d%dr   r0   ze%szi%dzo%dzse%sFr   r   )
r   r   stridesr   r   r   r   appendr   join)blockargsr$   r$   r%   _encode_block_stringz  s   	


z!BlockDecoder._encode_block_stringc                 C   s0   t | tsJ g }| D ]
}|t| q|S )a  Decode a list of string notations to specify blocks inside the network.
        Args:
            string_list (list[str]): A list of strings, each string is a notation of block.
        Returns:
            blocks_args: A list of BlockArgs namedtuples of block args.
        )rF   rG   r   r   r   )Zstring_listblocks_argsr   r$   r$   r%   decode  s
   zBlockDecoder.decodec                 C   s"   g }| D ]
}| t| q|S )a  Encode a list of BlockArgs to a list of strings.
        Args:
            blocks_args (list[namedtuples]): A list of BlockArgs namedtuples of block args.
        Returns:
            block_strings: A list of strings, each string is a notation of block.
        )r   r   r   )r   Zblock_stringsr   r$   r$   r%   encode  s   zBlockDecoder.encodeN)	r(   r)   r*   ro   r2   r   r   r   r   r$   r$   r$   r%   r   S  s    
!

r   c                 C   s"   ddddddddd	d
d
}||  S )zMap EfficientNet model name to parameter coefficients.
    Args:
        model_name (str): Model name to be queried.
    Returns:
        params_dict[model_name]: A (width,depth,res,dropout) tuple.
    )      ?r   p   皙?)r   皙?   r   )r   333333?i  333333?)r   ffffff?i,  r   )r   ?i|  皙?)g?皙@i  r   )r   g@i        ?)g       @g@iX  r   )r   g@i  r   )g333333@g333333@i   r   )
zefficientnet-b0zefficientnet-b1zefficientnet-b2zefficientnet-b3zefficientnet-b4zefficientnet-b5zefficientnet-b6zefficientnet-b7zefficientnet-b8zefficientnet-l2r$   )
model_nameparams_dictr$   r$   r%   efficientnet_params  s   r   r     Tc           	      C   s8   g d}t |}t| ||||dd|dd|d}||fS )aU  Create BlockArgs and GlobalParams for efficientnet model.
    Args:
        width_coefficient (float)
        depth_coefficient (float)
        image_size (int)
        dropout_rate (float)
        drop_connect_rate (float)
        num_classes (int)
        Meaning as the name suggests.
    Returns:
        blocks_args, global_params.
    )zr1_k3_s11_e1_i32_o16_se0.25zr2_k3_s22_e6_i16_o24_se0.25zr2_k5_s22_e6_i24_o40_se0.25zr3_k3_s22_e6_i40_o80_se0.25zr3_k5_s11_e6_i80_o112_se0.25zr4_k5_s22_e6_i112_o192_se0.25zr1_k3_s11_e6_i192_o320_se0.25gGz?gMbP?   Nr   )r   r   r   )	r   r	   r
   r   r   r   r   r   r9   r$   r$   r%   efficientnet  s    
	r   c                 C   sZ   |  drt| \}}}}t||||d\}}ntd| |r)|jdi |}||fS )zGet the block args and global params for a given model name.
    Args:
        model_name (str): Model's name.
        override_params (dict): A dict to modify global_params.
    Returns:
        blocks_args, global_params
    r   )r   r	   r   r
   z!model name is not pre-defined: {}Nr$   )
startswithr   r   NotImplementedErrorformat_replace)r   Zoverride_paramswdr   rC   r   r9   r$   r$   r%   get_model_params  s   
r   Fc           	      C   s   t |trtj|dd}n|rtnt}t|| }|r/| j|dd}|j	r.J d
|j	n$|d |d | j|dd}t|j	tddgksSJ d
|j	|jr^J d
|j|ritd
| d	S d	S )
aZ  Loads pretrained weights from weights path or download using url.
    Args:
        model (Module): The whole model of efficientnet.
        model_name (str): Model name of efficientnet.
        weights_path (None or str):
            str: path to pretrained weights file on the local disk.
            None: use pretrained weights downloaded from the Internet.
        load_fc (bool): Whether to load pretrained weights for fc layer at the end of the model.
        advprop (bool): Whether to load pretrained weights
                        trained with advprop (valid when weights_path is None).
    T)Zweights_onlyF)strictz0Missing keys when loading pretrained weights: {}z
_fc.weightz_fc.biasz Loaded pretrained weights for {}N)rF   r   r   loadZurl_map_advpropZurl_mapr   Zload_urlZload_state_dictZmissing_keysr   popsetZunexpected_keysprint)	modelr   Zweights_pathZload_fcZadvpropverboseZ
state_dictZurl_map_retr$   r$   r%   load_pretrained_weights  s2   




r   )NNNr   r   r   T)NTFT).collectionsr<   r   	functoolsr   r   r   Ztorch.nnr   r`   Ztorch.utilsr   
namedtupler   r   rT   _fields__new____defaults__hasattrr   r   ModuleZautogradFunctionr,   r3   r;   r>   rE   rJ   rK   rP   ZConv2drN   rO   rz   Z	MaxPool2drx   ry   objectr   r   r   r   r   r$   r$   r$   r%   <module>   sX   

#
)&&Y
/