o
    Qe                     @   s   d dl 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iZ
G d	d
 d
ejZG dd dejZdddZdddZdS )    N)get_weights_path_from_url   )_make_divisible   )ConvNormActivationzmobilenetv2_1.0)zChttps://paddle-hapi.bj.bcebos.com/models/mobilenet_v2_x1.0.pdparamsZ 0340af0a901346c8d46f4529882fb63dc                       s*   e Zd Zejf fdd	Zdd Z  ZS )InvertedResidualc                    s   t t|   || _|dv sJ tt|| }| jdko ||k| _g }|dkr5|t||d|t	j
d |t|||||t	j
dt	j||ddddd||g t	j| | _d S )N)r   r   r   Zkernel_size
norm_layeractivation_layer)stridegroupsr	   r
   r   F)Z	bias_attr)superr   __init__r   introunduse_res_connectappendr   nnReLU6extendZConv2D
Sequentialconv)selfinpZoupr   expand_ratior	   Z
hidden_dimZlayers	__class__ PD:\Projects\ConvertPro\env\Lib\site-packages\paddle/vision/models/mobilenetv2.pyr   !   s6   
zInvertedResidual.__init__c                 C   s   | j r
|| | S | |S )N)r   r   r   xr   r   r   forwardB   s   
zInvertedResidual.forward)__name__
__module____qualname__r   BatchNorm2Dr   r!   __classcell__r   r   r   r   r      s    !r   c                       s*   e Zd ZdZd	 fdd	Zdd Z  ZS )
MobileNetV2aV  MobileNetV2 model from
    `"MobileNetV2: Inverted Residuals and Linear Bottlenecks" <https://arxiv.org/abs/1801.04381>`_.

    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 MobileNetV2 model.

    Examples:
        .. code-block:: python

            import paddle
            from paddle.vision.models import MobileNetV2

            model = MobileNetV2()

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

            print(out.shape)
            # [1, 1000]
          ?  Tc                    sZ  t t|   || _|| _d}d}t}d}tj}g dg dg dg dg dg d	g d
g}	t|| |}t|t	d| || _
td|d|tjdg}
|	D ]*\}}}}t|| |}t|D ]}|dkrg|nd}|
||||||d |}q_qN|
t|| j
d|tjd tj|
 | _|rtd| _| jdkrttdt| j
|| _d S d S )N    i      )r      r   r   )      r   r   )r-   r*      r   )r-   @      r   )r-   `   r/   r   )r-      r/   r   )r-   i@  r   r   r(   r/   r   )r   r	   r
   r   r   )r   r	   r   g?)r   r'   r   num_classes	with_poolr   r   r%   r   maxlast_channelr   r   ranger   r   featuresZAdaptiveAvgPool2D
pool2d_avgZDropoutZLinear
classifier)r   scaler4   r5   Zinput_channelr7   blockZround_nearestr	   Zinverted_residual_settingr9   tcnsZoutput_channelir   r   r   r   r   e   sr   



zMobileNetV2.__init__c                 C   s>   |  |}| jr| |}| jdkrt|d}| |}|S )Nr   r   )r9   r5   r:   r4   paddleflattenr;   r   r   r   r   r!      s   



zMobileNetV2.forward)r(   r)   T)r"   r#   r$   __doc__r   r!   r&   r   r   r   r   r'   I   s    ;r'   Fc                 K   sZ   t di |}|r+| tv sJ d| tt|  d t|  d }t|}|| |S )NzL{} model do not have a pretrained model now, you should set pretrained=Falser   r   r   )r'   
model_urlsformatr   rC   load	load_dict)arch
pretrainedkwargsmodelZweight_pathparamr   r   r   
_mobilenet   s   


rO   r(   c                 K   s"   t dt| | fd|i|}|S )aq  MobileNetV2 from
    `"MobileNetV2: Inverted Residuals and Linear Bottlenecks" <https://arxiv.org/abs/1801.04381>`_.
    
    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:`MobileNetV2 <api_paddle_vision_MobileNetV2>`.

    Returns:
        :ref:`api_paddle_nn_Layer`. An instance of MobileNetV2 model.

    Examples:
        .. code-block:: python

            import paddle
            from paddle.vision.models import mobilenet_v2

            # build model
            model = mobilenet_v2()

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

            # build mobilenet v2 with scale=0.5
            model = mobilenet_v2(scale=0.5)

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

            print(out.shape)
            # [1, 1000]
    Zmobilenetv2_r<   )rO   str)rK   r<   rL   rM   r   r   r   mobilenet_v2   s   "rQ   )F)Fr(   )rC   Z	paddle.nnr   Zpaddle.utils.downloadr   utilsr   opsr   __all__rF   ZLayerr   r'   rO   rQ   r   r   r   r   <module>   s   *
c