o
    *j'>                     @   s|   d dl Z d dl mZ d dlmZ ddlmZmZmZm	Z	m
Z
mZmZmZmZmZ dZG dd dejZG d	d
 d
ejZdS )    N)nn)
functional   )
MemoryEfficientSwishSwishcalculate_output_image_sizedrop_connectefficientnet_paramsget_model_paramsget_same_padding_conv2dload_pretrained_weightsround_filtersround_repeats)
zefficientnet-b0zefficientnet-b1zefficientnet-b2zefficientnet-b3zefficientnet-b4zefficientnet-b5zefficientnet-b6zefficientnet-b7zefficientnet-b8zefficientnet-l2c                       s2   e Zd Zd	 fdd	Zd	ddZd
ddZ  ZS )MBConvBlockNc                    s  t    || _d|j | _|j| _| jjd uo%d| jj  k o#dkn  | _|j	| _	| jj
}| jj
| jj }| jjdkrVt|d}|||ddd| _tj|| j| jd| _| jj}| jj}t|d}||||||dd| _tj|| j| jd| _t||}| jrtdd}tdt| jj
| jj }	|||	dd	| _||	|dd	| _| jj}
t|d}|||
ddd| _tj|
| j| jd| _t | _d S )
Nr   r   
image_sizeF)in_channelsout_channelskernel_sizebiasZnum_featuresZmomentumeps)r   r   groupsr   strider   )r   r   )r   r   r   )super__init___block_argsbatch_norm_momentumZ_bn_mombatch_norm_epsilonZ_bn_epsZse_ratiohas_seid_skipinput_filtersexpand_ratior   _expand_convr   BatchNorm2d_bn0r   r   _depthwise_conv_bn1r   maxint
_se_reduce
_se_expandoutput_filters_project_conv_bn2r   _swish)self
block_argsglobal_paramsr   inpZoupConv2dksZnum_squeezed_channelsZ	final_oup	__class__ r/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/models/cv/face_emotion/efficient/model.pyr      s|   








zMBConvBlock.__init__c                 C   s   |}| j jdkr| |}| |}| |}| |}| |}| |}| jrEt	|d}| 
|}| |}| |}t|| }| |}| |}| j j| j j}}| jrs| j jdkrs||krs|rot||| jd}|| }|S )zMBConvBlock's forward function.
        Args:
            inputs (tensor): Input tensor.
            drop_connect_rate (bool): Drop connect rate (float, between 0 and 1).
        Returns:
            Output of this block after processing.
        r   )ptraining)r   r"   r#   r%   r/   r&   r'   r   FZadaptive_avg_pool2dr*   r+   torchZsigmoidr-   r.   r!   r,   r    r   r   r<   )r0   inputsdrop_connect_ratexZ
x_squeezedr!   r,   r9   r9   r:   forwardL   s0   	










zMBConvBlock.forwardTc                 C   s   |rt  | _dS t | _dS zSets swish function as memory efficient (for training) or standard (for export).
        Args:
            memory_efficient (bool): Whether to use memory-efficient version of swish.
        N)r   r   r/   )r0   memory_efficientr9   r9   r:   	set_swishq   s   zMBConvBlock.set_swish)NT)__name__
__module____qualname__r   rB   rE   __classcell__r9   r9   r7   r:   r      s    
7%r   c                       s   e Zd ZdZd fdd	ZdddZdd	 Zd
d Zdd Ze	dddZ
e					dddZe	dd Ze	dd Zdd Z  ZS )EfficientNetaj  EfficientNet model.
       Most easily loaded with the .from_name or .from_pretrained methods.
    Args:
        blocks_args (list[namedtuple]): A list of BlockArgs to construct blocks.
        global_params (namedtuple): A set of GlobalParams shared between blocks.
    References:
        [1] https://arxiv.org/abs/1905.11946 (EfficientNet)
    Example:
        >>> import torch
        >>> from efficientnet.model import EfficientNet
        >>> inputs = torch.rand(1, 3, 224, 224)
        >>> model = EfficientNet.from_pretrained('efficientnet-b0')
        >>> model.eval()
        >>> outputs = model(inputs)
    Nc              	      s  t    t|tsJ dt|dksJ d|| _|| _d| jj }| jj}|j	}t
|d}d}td| j}|||ddd	d
| _tj|||d| _t|d}tg | _| jD ]N}	|	jt|	j| jt|	j| jt|	j| jd}	| jt|	| j|d t||	j}|	jdkr|	j|	jdd}	t|	jd D ]}
| jt|	| j|d qqY|	j}td| j}t
|d}|||dd	d| _tj|||d| _td| _| jj rt!| jj"| _#t$|| jj%| _&t' | _(d S )Nzblocks_args should be a listr   z!block args must be greater than 0r   r             Fr   r   r   r   )r!   r,   
num_repeat)r!   r   i   )r   r   ))r   r   
isinstancelistlen_global_paramsZ_blocks_argsr   r   r   r   r   
_conv_stemr   r$   r%   r   Z
ModuleList_blocks_replacer!   r,   r   rP   appendr   r   range
_conv_headr'   ZAdaptiveAvgPool2d_avg_poolinginclude_topZDropoutZdropout_rate_dropoutZLinearnum_classes_fcr   r/   )r0   blocks_argsr2   Zbn_momZbn_epsr   r4   r   r   r1   _r7   r9   r:   r      s   






zEfficientNet.__init__Tc                 C   s,   |rt  nt | _| jD ]}|| qdS rC   )r   r   r/   rV   rE   )r0   rD   blockr9   r9   r:   rE      s   
zEfficientNet.set_swishc                 C   s   t  }| | | |}|}t| jD ]G\}}| jj}|r*|t|t	| j 9 }|||d}|
d|
dkrF||dt	|d < n|t	| jd krZ||dt	|d < |}q| | | |}||dt	|d < |S )a?  Use convolution layer to extract features
        from reduction levels i in [1, 2, 3, 4, 5].
        Args:
            inputs (tensor): Input tensor.
        Returns:
            Dictionary of last intermediate features
            with reduction levels i in [1, 2, 3, 4, 5].
        Example:
            >>> import torch
            >>> from efficientnet.model import EfficientNet
            >>> inputs = torch.rand(1, 3, 224, 224)
            >>> model = EfficientNet.from_pretrained('efficientnet-b0')
            >>> endpoints = model.extract_endpoints(inputs)
            >>> print(endpoints['reduction_1'].shape)  # torch.Size([1, 16, 112, 112])
            >>> print(endpoints['reduction_2'].shape)  # torch.Size([1, 24, 56, 56])
            >>> print(endpoints['reduction_3'].shape)  # torch.Size([1, 40, 28, 28])
            >>> print(endpoints['reduction_4'].shape)  # torch.Size([1, 112, 14, 14])
            >>> print(endpoints['reduction_5'].shape)  # torch.Size([1, 320, 7, 7])
            >>> print(endpoints['reduction_6'].shape)  # torch.Size([1, 1280, 7, 7])
        r@   rN   zreduction_{}r   )dictr/   r%   rU   	enumeraterV   rT   r@   floatrS   sizeformatr'   rZ   )r0   r?   Z	endpointsrA   Zprev_xidxrb   r@   r9   r9   r:   extract_endpoints   s$   
zEfficientNet.extract_endpointsc                 C   sr   |  | | |}t| jD ]\}}| jj}|r%|t|t| j 9 }|||d}q|  | 	| 
|}|S )zuse convolution layer to extract feature .
        Args:
            inputs (tensor): Input tensor.
        Returns:
            Output of the final convolution
            layer in the efficientnet model.
        rc   )r/   r%   rU   re   rV   rT   r@   rf   rS   r'   rZ   )r0   r?   rA   ri   rb   r@   r9   r9   r:   extract_features   s   zEfficientNet.extract_featuresc                 C   s@   |  |}| |}| jjr|jdd}| |}| |}|S )a  EfficientNet's forward function.
           Calls extract_features to extract features, applies final linear layer, and returns logits.
        Args:
            inputs (tensor): Input tensor.
        Returns:
            Output of this model after processing.
        r   )Z	start_dim)rk   r[   rT   r\   flattenr]   r_   )r0   r?   rA   r9   r9   r:   rB     s   



zEfficientNet.forwardrL   c                 K   s0   |  | t||\}}| ||}|| |S )a  Create an efficientnet model according to name.
        Args:
            model_name (str): Name for efficientnet.
            in_channels (int): Input data's channel number.
            override_params (other key word params):
                Params to override model's global_params.
                Optional key:
                    'width_coefficient', 'depth_coefficient',
                    'image_size', 'dropout_rate',
                    'num_classes', 'batch_norm_momentum',
                    'batch_norm_epsilon', 'drop_connect_rate',
                    'depth_divisor', 'min_depth'
        Returns:
            An efficientnet model.
        )_check_model_name_is_validr
   _change_in_channels)cls
model_namer   override_paramsr`   r2   modelr9   r9   r:   	from_name  s   


zEfficientNet.from_nameF  c                 K   s$   | j |fd|i|}|| |S )a{  Create an efficientnet model according to name.
        Args:
            model_name (str): Name for efficientnet.
            weights_path (None or str):
                str: path to pretrained weights file on the local disk.
                None: use pretrained weights downloaded from the Internet.
            advprop (bool):
                Whether to load pretrained weights
                trained with advprop (valid when weights_path is None).
            in_channels (int): Input data's channel number.
            num_classes (int):
                Number of categories for classification.
                It controls the output size for final linear layer.
            override_params (other key word params):
                Params to override model's global_params.
                Optional key:
                    'width_coefficient', 'depth_coefficient',
                    'image_size', 'dropout_rate',
                    'batch_norm_momentum',
                    'batch_norm_epsilon', 'drop_connect_rate',
                    'depth_divisor', 'min_depth'
        Returns:
            A pretrained efficientnet model.
        r^   )rs   rn   )ro   rp   Zweights_pathZadvpropr   r^   rq   rr   r9   r9   r:   from_pretrained5  s    
zEfficientNet.from_pretrainedc                 C   s   |  | t|\}}}}|S )zGet the input image size for a given efficientnet model.
        Args:
            model_name (str): Name for efficientnet.
        Returns:
            Input image size (resolution).
        )rm   r	   )ro   rp   ra   resr9   r9   r:   get_image_sizeZ  s   
zEfficientNet.get_image_sizec                 C   s   |t vrtddt  dS )zValidates model name.
        Args:
            model_name (str): Name for efficientnet.
        Returns:
            bool: Is a valid name or not.
        zmodel_name should be one of: z, N)VALID_MODELS
ValueErrorjoin)ro   rp   r9   r9   r:   rm   f  s
   z'EfficientNet._check_model_name_is_validc                 C   s>   |dkrt | jjd}td| j}|||dddd| _dS dS )zAdjust model's first convolution layer to in_channels, if in_channels not equals 3.
        Args:
            in_channels (int): Input data's channel number.
        rL   r   rM   rN   FrO   N)r   rT   r   r   rU   )r0   r   r4   r   r9   r9   r:   rn   r  s   
z EfficientNet._change_in_channels)NNrF   )rL   )NFrL   rt   )rG   rH   rI   __doc__r   rE   rj   rk   rB   classmethodrs   ru   rw   rm   rn   rJ   r9   r9   r7   r:   rK   y   s(    
<	+$

rK   )r>   r   Ztorch.nnr   r=   utilsr   r   r   r   r	   r
   r   r   r   r   rx   Moduler   rK   r9   r9   r9   r:   <module>   s   0f