U
    <jg;                  	   @   sT  d dl mZ d dlmZmZmZmZmZ d dlZd dlm	Z	m
Z
 d dlmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZ ddlmZ ddlmZmZ dddddddddg	Z G dd de	j!Z"G dd de	j#Z$G dd dZ%G dd de	j#Z&ee% e'ee e(ee&dd d!Z)d"ed#d$d%Z*G d&d deZ+G d'd deZ,G d(d deZ-G d)d deZ.e ed*e+j/fd+dd,d-ee+ e(ee&d.d/dZ0e ed*e,j/fd+dd,d-ee, e(ee&d.d0dZ1e ed*e-j/fd+dd,d-ee- e(ee&d.d1dZ2e ed*e.j/fd+dd,d-ee. e(ee&d.d2dZ3dS )3    )partial)AnyCallableListOptionalSequenceN)nnTensor)
functional   )Conv2dNormActivationPermute)StochasticDepth)ImageClassification)_log_api_usage_once   )register_modelWeightsWeightsEnum)_IMAGENET_CATEGORIES)_ovewrite_named_paramhandle_legacy_interfaceConvNeXtConvNeXt_Tiny_WeightsConvNeXt_Small_WeightsConvNeXt_Base_WeightsConvNeXt_Large_Weightsconvnext_tinyconvnext_smallconvnext_baseconvnext_largec                   @   s   e Zd ZeedddZdS )LayerNorm2dxreturnc                 C   s>   | dddd}t|| j| j| j| j}| dddd}|S )Nr   r      r   )ZpermuteFZ
layer_normZnormalized_shapeweightbiasepsselfr#    r,   ?/tmp/pip-unpacked-wheel-xh8d94dr/torchvision/models/convnext.pyforward   s    zLayerNorm2d.forwardN)__name__
__module____qualname__r	   r.   r,   r,   r,   r-   r!      s   r!   c                       sH   e Zd Zd	eeeedejf  dd fddZe	e	dddZ
  ZS )
CNBlockN.)layer_scalestochastic_depth_prob
norm_layerr$   c                    s   t    |d kr ttjdd}ttj||dd|ddtdddd	g||tj|d
| ddt	 tjd
| |ddtddd	dg| _
tt|d	d	| | _t|d| _d S )Nư>r)      r%   T)kernel_sizepaddinggroupsr(   r   r   r      )Zin_featuresZout_featuresr(   row)super__init__r   r   	LayerNorm
SequentialConv2dr   LinearZGELUblock	ParametertorchZonesr3   r   stochastic_depth)r+   Zdimr3   r4   r5   	__class__r,   r-   r?   '   s    
	zCNBlock.__init__)inputr$   c                 C   s&   | j | | }| |}||7 }|S N)r3   rD   rG   )r+   rJ   resultr,   r,   r-   r.   >   s    
zCNBlock.forward)N)r/   r0   r1   floatr   r   r   Moduler?   r	   r.   __classcell__r,   r,   rH   r-   r2   &   s    r2   c                   @   s2   e Zd Zeee eddddZedddZdS )CNBlockConfigN)input_channelsout_channels
num_layersr$   c                 C   s   || _ || _|| _d S rK   )rQ   rR   rS   )r+   rQ   rR   rS   r,   r,   r-   r?   G   s    zCNBlockConfig.__init__)r$   c                 C   s:   | j jd }|d7 }|d7 }|d7 }|d7 }|jf | jS )N(zinput_channels={input_channels}z, out_channels={out_channels}z, num_layers={num_layers}))rI   r/   format__dict__)r+   sr,   r,   r-   __repr__Q   s    zCNBlockConfig.__repr__)r/   r0   r1   intr   r?   strrY   r,   r,   r,   r-   rP   E   s   
rP   c                
       sr   e Zd Zdee eeeeede	j
f  eede	j
f  edd fddZeed	d
dZeed	ddZ  ZS )r           r6     N.)block_settingr4   r3   num_classesrD   r5   kwargsr$   c                    s  t    t|  |s tdn$t|tr<tdd |D sDtd|d krPt}|d krdt	t
dd}g }|d j}	|td|	d	d	d|d d
d tdd |D }
d}|D ]}g }t|jD ]0}|| |
d  }|||j|| |d7 }q|tj|  |jd k	r|t||jtj|j|jddd qtj| | _td| _|d }|jd k	rf|jn|j}t||tdt||| _|  D ]F}t|tjtjfrtjj|jdd |jd k	rtj |j qd S )Nz%The block_setting should not be emptyc                 S   s   g | ]}t |tqS r,   )
isinstancerP   ).0rX   r,   r,   r-   
<listcomp>j   s     z%ConvNeXt.__init__.<locals>.<listcomp>z/The block_setting should be List[CNBlockConfig]r6   r7   r   r%   r<   T)r9   strider:   r5   Zactivation_layerr(   c                 s   s   | ]}|j V  qd S rK   )rS   )rb   cnfr,   r,   r-   	<genexpr>   s     z$ConvNeXt.__init__.<locals>.<genexpr>g      ?r   r   )r9   rd   g{Gz?)Zstd)!r>   r?   r   
ValueErrorra   r   all	TypeErrorr2   r   r!   rQ   appendr   sumrangerS   r   rA   rR   rB   featuresZAdaptiveAvgPool2davgpoolZFlattenrC   
classifiermodulesinitZtrunc_normal_r'   r(   Zzeros_)r+   r^   r4   r3   r_   rD   r5   r`   ZlayersZfirstconv_output_channelsZtotal_stage_blocksZstage_block_idre   Zstage_Zsd_probZ	lastblockZlastconv_output_channelsmrH   r,   r-   r?   [   sn    





  
zConvNeXt.__init__r"   c                 C   s"   |  |}| |}| |}|S rK   )rn   ro   rp   r*   r,   r,   r-   _forward_impl   s    


zConvNeXt._forward_implc                 C   s
   |  |S rK   )ru   r*   r,   r,   r-   r.      s    zConvNeXt.forward)r\   r6   r]   NN)r/   r0   r1   r   rP   rM   rZ   r   r   r   rN   r   r?   r	   ru   r.   rO   r,   r,   rH   r-   r   Z   s"        N)r^   r4   weightsprogressr`   r$   c                 K   sR   |d k	rt |dt|jd  t| fd|i|}|d k	rN||j|dd |S )Nr_   
categoriesr4   T)rw   Z
check_hash)r   lenmetar   Zload_state_dictZget_state_dict)r^   r4   rv   rw   r`   modelr,   r,   r-   	_convnext   s    r|   )    r}   zNhttps://github.com/pytorch/vision/tree/main/references/classification#convnexta  
        These weights improve upon the results of the original paper by using a modified version of TorchVision's
        `new training recipe
        <https://pytorch.org/blog/how-to-train-state-of-the-art-models-using-torchvision-latest-primitives/>`_.
    )Zmin_sizerx   ZrecipeZ_docsc                	   @   s@   e Zd Zedeedddeddddd	id
dddZeZdS )r   z>https://download.pytorch.org/models/convnext_tiny-983f1562.pth      Z	crop_sizeZresize_sizeiH<ImageNet-1KgzGT@gMbX	X@zacc@1zacc@5gm@gV-G[@Z
num_paramsZ_metricsZ_ops
_file_sizeurlZ
transformsrz   N	r/   r0   r1   r   r   r   _COMMON_METAIMAGENET1K_V1DEFAULTr,   r,   r,   r-   r      s   c                	   @   s@   e Zd Zedeedddeddddd	id
dddZeZdS )r   z?https://download.pytorch.org/models/convnext_small-0c510722.pthr~      r   iHZr   gClT@g)X@r   g|?5^!@g"~g@r   r   Nr   r,   r,   r,   r-   r      s   c                	   @   s@   e Zd Zedeedddeddddd	id
dddZeZdS )r   z>https://download.pytorch.org/models/convnext_base-6075fbad.pthr~      r   ihGr   gU@gHz7X@r   g(\µ.@g/$!u@r   r   Nr   r,   r,   r,   r-   r      s   c                	   @   s@   e Zd Zedeedddeddddd	id
dddZeZdS )r   z?https://download.pytorch.org/models/convnext_large-ea097f82.pthr~   r   r   ir   g"~U@gX9v>X@r   g|?5.A@gK@r   r   Nr   r,   r,   r,   r-   r     s   Z
pretrained)rv   T)rv   rw   )rv   rw   r`   r$   c                 K   sT   t | } tdddtdddtdddtdddg}|dd	}t||| |f|S )
a  ConvNeXt Tiny model architecture from the
    `A ConvNet for the 2020s <https://arxiv.org/abs/2201.03545>`_ paper.

    Args:
        weights (:class:`~torchvision.models.convnext.ConvNeXt_Tiny_Weights`, optional): The pretrained
            weights to use. See :class:`~torchvision.models.convnext.ConvNeXt_Tiny_Weights`
            below for more details and possible values. By default, no pre-trained weights are used.
        progress (bool, optional): If True, displays a progress bar of the download to stderr. Default is True.
        **kwargs: parameters passed to the ``torchvision.models.convnext.ConvNext``
            base class. Please refer to the `source code
            <https://github.com/pytorch/vision/blob/main/torchvision/models/convnext.py>`_
            for more details about this class.

    .. autoclass:: torchvision.models.ConvNeXt_Tiny_Weights
        :members:
    `      r%        	   Nr4   g?)r   verifyrP   popr|   rv   rw   r`   r^   r4   r,   r,   r-   r   !  s    




c                 K   sT   t | } tdddtdddtdddtdddg}|dd	}t||| |f|S )
a  ConvNeXt Small model architecture from the
    `A ConvNet for the 2020s <https://arxiv.org/abs/2201.03545>`_ paper.

    Args:
        weights (:class:`~torchvision.models.convnext.ConvNeXt_Small_Weights`, optional): The pretrained
            weights to use. See :class:`~torchvision.models.convnext.ConvNeXt_Small_Weights`
            below for more details and possible values. By default, no pre-trained weights are used.
        progress (bool, optional): If True, displays a progress bar of the download to stderr. Default is True.
        **kwargs: parameters passed to the ``torchvision.models.convnext.ConvNext``
            base class. Please refer to the `source code
            <https://github.com/pytorch/vision/blob/main/torchvision/models/convnext.py>`_
            for more details about this class.

    .. autoclass:: torchvision.models.ConvNeXt_Small_Weights
        :members:
    r   r   r%   r   r      Nr4   g?)r   r   rP   r   r|   r   r,   r,   r-   r   @  s    




c                 K   sT   t | } tdddtdddtdddtdddg}|dd	}t||| |f|S )
a  ConvNeXt Base model architecture from the
    `A ConvNet for the 2020s <https://arxiv.org/abs/2201.03545>`_ paper.

    Args:
        weights (:class:`~torchvision.models.convnext.ConvNeXt_Base_Weights`, optional): The pretrained
            weights to use. See :class:`~torchvision.models.convnext.ConvNeXt_Base_Weights`
            below for more details and possible values. By default, no pre-trained weights are used.
        progress (bool, optional): If True, displays a progress bar of the download to stderr. Default is True.
        **kwargs: parameters passed to the ``torchvision.models.convnext.ConvNext``
            base class. Please refer to the `source code
            <https://github.com/pytorch/vision/blob/main/torchvision/models/convnext.py>`_
            for more details about this class.

    .. autoclass:: torchvision.models.ConvNeXt_Base_Weights
        :members:
          r%   i   i   r   Nr4         ?)r   r   rP   r   r|   r   r,   r,   r-   r   a  s    




c                 K   sT   t | } tdddtdddtdddtdddg}|dd	}t||| |f|S )
a  ConvNeXt Large model architecture from the
    `A ConvNet for the 2020s <https://arxiv.org/abs/2201.03545>`_ paper.

    Args:
        weights (:class:`~torchvision.models.convnext.ConvNeXt_Large_Weights`, optional): The pretrained
            weights to use. See :class:`~torchvision.models.convnext.ConvNeXt_Large_Weights`
            below for more details and possible values. By default, no pre-trained weights are used.
        progress (bool, optional): If True, displays a progress bar of the download to stderr. Default is True.
        **kwargs: parameters passed to the ``torchvision.models.convnext.ConvNext``
            base class. Please refer to the `source code
            <https://github.com/pytorch/vision/blob/main/torchvision/models/convnext.py>`_
            for more details about this class.

    .. autoclass:: torchvision.models.ConvNeXt_Large_Weights
        :members:
    r   r   r%   r   i   r   Nr4   r   )r   r   rP   r   r|   r   r,   r,   r-   r      s    




)4	functoolsr   typingr   r   r   r   r   rF   r   r	   Ztorch.nnr
   r&   Zops.miscr   r   Zops.stochastic_depthr   Ztransforms._presetsr   utilsr   Z_apir   r   r   Z_metar   _utilsr   r   __all__r@   r!   rN   r2   rP   r   rM   boolr|   r   r   r   r   r   r   r   r   r   r    r,   r,   r,   r-   <module>   s   Z$   $   