o
    QeZH                     @   s   d dl mZ d dl m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
 ddlmZ d	d
lmZ g ZdddZG dd dejZG dd dZG dd dejZG dd dejZG dd deZG dd deZd"ddZd"ddZd"d d!ZdS )#    )absolute_import)division)print_functionN)get_weights_path_from_url)partial   _make_divisible   )ConvNormActivation)zIhttps://paddle-hapi.bj.bcebos.com/models/mobilenet_v3_small_x1.0.pdparamsZ 34fe0e7c1f8b00b2b056ad6788d0590c)zIhttps://paddle-hapi.bj.bcebos.com/models/mobilenet_v3_large_x1.0.pdparamsZ 118db5792b4e183b925d8e8e334db3df)zmobilenet_v3_small_x1.0zmobilenet_v3_large_x1.0c                       s:   e Zd ZdZejejf fdd	Zdd Zdd Z	  Z
S )SqueezeExcitationa  
    This block implements the Squeeze-and-Excitation block from https://arxiv.org/abs/1709.01507 (see Fig. 1).
    Parameters ``activation``, and ``scale_activation`` correspond to ``delta`` and ``sigma`` in eq. 3.
    This code is based on the torchvision code with modifications.
    You can also see at https://github.com/pytorch/vision/blob/main/torchvision/ops/misc.py#L127
    Args:
        input_channels (int): Number of channels in the input image
        squeeze_channels (int): Number of squeeze channels
        activation (Callable[..., paddle.nn.Layer], optional): ``delta`` activation. Default: ``paddle.nn.ReLU``
        scale_activation (Callable[..., paddle.nn.Layer]): ``sigma`` activation. Default: ``paddle.nn.Sigmoid``
    c                    sJ   t    td| _t||d| _t||d| _| | _| | _	d S )Nr   )
super__init__nnAdaptiveAvgPool2DavgpoolZConv2Dfc1fc2
activationscale_activation)selfZinput_channelsZsqueeze_channelsr   r   	__class__ PD:\Projects\ConvertPro\env\Lib\site-packages\paddle/vision/models/mobilenetv3.pyr   4   s   
zSqueezeExcitation.__init__c                 C   s2   |  |}| |}| |}| |}| |S N)r   r   r   r   r   r   inputscaler   r   r   _scale@   s
   




zSqueezeExcitation._scalec                 C   s   |  |}|| S r   )r   r   r   r   r   forwardG   s   
zSqueezeExcitation.forward)__name__
__module____qualname____doc__r   ReLUZSigmoidr   r   r    __classcell__r   r   r   r   r   '   s    r   c                   @   s&   e Zd Z	dddZedddZdS )InvertedResidualConfig      ?c	           	      C   s   | j ||d| _|| _| j ||d| _| j ||d| _|| _|d u r&d | _n|dkr/tj| _n|dkr8tj	| _nt
d||| _d S )N)r   relu	hardswishz,The activation function is not supported: {})adjust_channelsin_channelskernelexpanded_channelsout_channelsuse_seactivation_layerr   r%   	HardswishRuntimeErrorformatstride)	r   r,   r-   r.   r/   r0   r   r5   r   r   r   r   r   N   s&   	


zInvertedResidualConfig.__init__c                 C   s   t | | dS )N   r   )Zchannelsr   r   r   r   r+   i   s   z&InvertedResidualConfig.adjust_channelsN)r(   )r!   r"   r#   r   staticmethodr+   r   r   r   r   r'   L   s
    

r'   c                       s$   e Zd Z fddZdd Z  ZS )InvertedResidualc	           	   
      s   t    |dko||k| _|| _||k| _| jr%t||ddd||d| _t||||t|d d |||d| _| jrHt	|t
|d tjd| _t||ddd|d d| _d S )Nr   r   )r,   r/   kernel_sizer5   padding
norm_layerr1   r
   r,   r/   r9   r5   r:   groupsr;   r1      )r   )r   r   use_res_connectr0   expandr   expand_convintbottleneck_convr   r	   r   ZHardsigmoidmid_selinear_conv)	r   r,   r.   r/   filter_sizer5   r0   r1   r;   r   r   r   r   p   sN   

	
zInvertedResidual.__init__c                 C   sN   |}| j r
| |}| |}| jr| |}| |}| jr%t||}|S r   )	r@   rA   rC   r0   rD   rE   r?   paddleadd)r   xidentityr   r   r   r       s   



zInvertedResidual.forward)r!   r"   r#   r   r    r&   r   r   r   r   r8   n   s    )r8   c                       s0   e Zd ZdZ			d	 fdd	Zdd Z  ZS )
MobileNetV3a_  MobileNetV3 model from
    `"Searching for MobileNetV3" <https://arxiv.org/abs/1905.02244>`_.

    Args:
        config (list[InvertedResidualConfig]): MobileNetV3 depthwise blocks config.
        last_channel (int): The number of channels on the penultimate layer.
        scale (float, optional): Scale of channels in each layer. Default: 1.0.
        num_classes (int, optional): Output dim of last fc layer. If num_classes <=0, last fc layer
                            will not be defined. Default: 1000.
        with_pool (bool, optional): Use pool before the last fc layer or not. Default: True.
    r(     Tc              
      s
  t    || _|| _|| _|| _|| _|d j| _|d j| _	| j	d | _
ttjddd td| jddd	d	tj d
| _tj fdd| jD  | _t| j	| j
d	d	dd	 tjd| _|rctd	| _|dkrtt| j
| jt tjddt| j|| _d S d S )Nr      gMbP?gGz?)epsilonZmomentum   r
   r   )r,   r/   r9   r5   r:   r=   r1   r;   c                    s2   g | ]}t |j|j|j|j|j|j|j d qS ))r,   r.   r/   rF   r5   r0   r1   r;   )r8   r,   r.   r/   r-   r5   r0   r1   ).0cfgr;   r   r   
<listcomp>   s    z(MobileNetV3.__init__.<locals>.<listcomp>r<   g?)p)r   r   configr   last_channelnum_classes	with_poolr,   Zfirstconv_in_channelsZlastconv_in_channelsZlastconv_out_channelsr   r   ZBatchNorm2Dr   r2   convZ
Sequentialblockslastconvr   r   ZLinearZDropout
classifier)r   rV   rW   r   rX   rY   r   rS   r   r      sR   
	


zMobileNetV3.__init__c                 C   sR   |  |}| |}| |}| jr| |}| jdkr't|d}| |}|S )Nr   r   )	rZ   r[   r\   rY   r   rX   rG   flattenr]   )r   rI   r   r   r   r       s   





zMobileNetV3.forwardr(   rL   T)r!   r"   r#   r$   r   r    r&   r   r   r   r   rK      s    9rK   c                       "   e Zd ZdZd fdd	Z  ZS )MobileNetV3Smalla  MobileNetV3 Small architecture model from
    `"Searching for MobileNetV3" <https://arxiv.org/abs/1905.02244>`_.

    Args:
        scale (float, optional): Scale of channels in each layer. Default: 1.0.
        num_classes (int, optional): Output dim of last fc layer. If num_classes <= 0, last fc layer 
                            will not be defined. Default: 1000.
        with_pool (bool, optional): Use pool before the last fc layer or not. Default: True.

    Returns:
        :ref:`api_paddle_nn_Layer`. An instance of MobileNetV3 Small architecture model.

    Examples:
        .. code-block:: python

            import paddle
            from paddle.vision.models import MobileNetV3Small

            # build model
            model = MobileNetV3Small(scale=1.0)

            x = paddle.rand([1, 3, 224, 224])
            out = model(x)

            print(out.shape)
            # [1, 1000]
    r(   rL   Tc                    s  t ddddddd|t ddddddd|t ddd	dddd
|t ddddddd|t ddddddd
|t ddddddd
|t ddddddd
|t ddddddd
|t ddddddd|t ddddddd
|t ddddddd
|g}td| d}t j|||||d d S )N   rP   Tr)   r
   H      FX   r      `   (   r*      x   0      i   i@  i   r6   rW   r   rY   rX   r'   r	   r   r   r   r   rX   rY   rV   rW   r   r   r   r     s&   
zMobileNetV3Small.__init__r_   r!   r"   r#   r$   r   r&   r   r   r   r   ra          ra   c                       r`   )MobileNetV3Largea  MobileNetV3 Large architecture model from
    `"Searching for MobileNetV3" <https://arxiv.org/abs/1905.02244>`_.

    Args:
        scale (float, optional): Scale of channels in each layer. Default: 1.0.
        num_classes (int, optional): Output dim of last fc layer. If num_classes <= 0, last fc layer 
                            will not be defined. Default: 1000.
        with_pool (bool, optional): Use pool before the last fc layer or not. Default: True.

    Returns:
        :ref:`api_paddle_nn_Layer`. An instance of MobileNetV3 Large architecture model.

    Examples:
        .. code-block:: python

            import paddle
            from paddle.vision.models import MobileNetV3Large

            # build model
            model = MobileNetV3Large(scale=1.0)

            x = paddle.rand([1, 3, 224, 224])
            out = model(x)

            print(out.shape)
            # [1, 1000]
    r(   rL   Tc                    sX  t ddddddd|t ddddddd|t ddd	dddd|t dd
d	dddd|t dd
ddddd|t dd
ddddd|t ddddddd|t ddddddd|t ddddddd|t ddddddd|t ddddddd|t ddddddd|t dd
ddddd|t dd
ddddd|t dd
ddddd|g}td| d}t j|||||d d S )Nrb   rP   Fr)   r   @   rd   r
   rc   rf   rh   Trj   ri   P   r*         i  p   i     i  i   r6   rm   rn   ro   r   r   r   r   K  sR   
zMobileNetV3Large.__init__r_   rp   r   r   r   r   rr   .  rq   rr   Fr(   c                 K   s   | dkrt dd|i|}n	tdd|i|}|rAd| |} | tv s*J d| tt|  d t|  d }t|}|| |S )Nmobilenet_v3_larger   z{}_x{}zL{} model do not have a pretrained model now, you should set pretrained=Falser   r   r   )rr   ra   r4   
model_urlsr   rG   loadZset_dict)arch
pretrainedr   kwargsmodelZweight_pathparamr   r   r   _mobilenet_v3n  s    



r   c                 K      t d|| d|}|S )a  MobileNetV3 Small architecture model from
    `"Searching for MobileNetV3" <https://arxiv.org/abs/1905.02244>`_.

    Args:
        pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
                            on ImageNet. Default: False.
        scale (float, optional): Scale of channels in each layer. Default: 1.0.
        **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`MobileNetV3Small <api_paddle_vision_MobileNetV3Small>`.

    Returns:
        :ref:`api_paddle_nn_Layer`. An instance of MobileNetV3 Small architecture model.

    Examples:
        .. code-block:: python

            import paddle
            from paddle.vision.models import mobilenet_v3_small

            # build model
            model = mobilenet_v3_small()

            # build model and load imagenet pretrained weight
            # model = mobilenet_v3_small(pretrained=True)

            # build mobilenet v3 small model with scale=0.5
            model = mobilenet_v3_small(scale=0.5)

            x = paddle.rand([1, 3, 224, 224])
            out = model(x)

            print(out.shape)
            # [1, 1000]
    mobilenet_v3_smallr   r}   N)r   r   r}   r   r~   r   r   r   r   r        "r   c                 K   r   )a  MobileNetV3 Large architecture model from
    `"Searching for MobileNetV3" <https://arxiv.org/abs/1905.02244>`_.

    Args:
        pretrained (bool, optional): Whether to load pre-trained weights. If True, returns a model pre-trained
                            on ImageNet. Default: False.
        scale (float, optional): Scale of channels in each layer. Default: 1.0.
        **kwargs (optional): Additional keyword arguments. For details, please refer to :ref:`MobileNetV3Large <api_paddle_vision_MobileNetV3Large>`.

    Returns:
        :ref:`api_paddle_nn_Layer`. An instance of MobileNetV3 Large architecture model.

    Examples:
        .. code-block:: python

            import paddle
            from paddle.vision.models import mobilenet_v3_large

            # build model
            model = mobilenet_v3_large()

            # build model and load imagenet pretrained weight
            # model = mobilenet_v3_large(pretrained=True)

            # build mobilenet v3 large model with scale=0.5
            model = mobilenet_v3_large(scale=0.5)

            x = paddle.rand([1, 3, 224, 224])
            out = model(x)

            print(out.shape)
            # [1, 1000]
    ry   r   N)ry   r   r   r   r   r   ry     r   ry   )Fr(   )
__future__r   r   r   rG   Z	paddle.nnr   Zpaddle.utils.downloadr   	functoolsr   utilsr	   opsr   __all__rz   ZLayerr   r'   r8   rK   ra   rr   r   r   ry   r   r   r   r   <module>   s,   
%"8U3
@
)