a
    dM                     @   s  d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
T ddlmZmZmZmZmZ g dZeeZd	Zd
ZdZeeedZdd Zdd Zd-ddZd.ddZdd Zdd Zdd Z d/d d!Z!d0d"d#Z"G d$d% d%Z#d1d(d)Z$d2e	j%d*d+d,Z&dS )3z EfficientNet, MobileNetV3, etc Builder

Assembles EfficieNet and related network feature blocks from string definitions.
Handles stride, dilation calculations, and selects feature extraction points.

Hacked together by / Copyright 2019, Ross Wightman
    Ndeepcopy)partial   )*)
CondConv2dget_condconv_initializerget_act_layerget_attnmake_divisible)EfficientNetBuilderdecode_arch_defefficientnet_init_weightsresolve_bn_argsresolve_act_layerround_channelsBN_MOMENTUM_TF_DEFAULTBN_EPS_TF_DEFAULTFgGz?gMbP?)momentumepsc                   C   s   t  S N)_BN_ARGS_TFcopy r   r   j/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/timm/models/_efficientnet_builder.pyget_bn_args_tf&   s    r   c                 C   s@   i }|  dd }|d ur ||d< |  dd }|d ur<||d< |S )Nbn_momentumr   bn_epsr   )pop)kwargsZbn_argsr   r   r   r   r   r   *   s    r   reluc                 C   s   t | d|S )N	act_layer)r	   r   )r   defaultr   r   r   r   5   s    r         ?   ?c                 C   s   |s| S t | | |||dS )z2Round number of filters based on depth multiplier.)round_limit)r   )Zchannels
multiplierZdivisorZchannel_minr&   r   r   r   r   9   s    r   c                 C   s   |rt |  d S r   )_loggerinfo)msg	conditionr   r   r   _log_info_if@   s    r,   c                 C   s(   |   rt| S dd | dD S d S )Nc                 S   s   g | ]}t |qS r   )int).0kr   r   r   
<listcomp>I       z _parse_ksize.<locals>.<listcomp>.)isdigitr-   split)ssr   r   r   _parse_ksizeE   s    r6   c              
   C   s  t | tsJ | d}|d }|dd }i }d}|D ]}|dkrJd}q8|dkrXd}q8|d	r|d }|dd }|d
krtd}nJ|dkrtd}n8|dkrtd}n&|dkrtd}n|dkr8td}nq8|||< q8td|}	t|	dkr8|	dd \}}|||< q8d	|v r |d	 nd}
d|v r:t|d nd}d|v rTt|d nd}d|v rnt|d nd}t|d }t	|t|d t|d |
d}|dkr|
t	t|d ||t|d d |v rt|d  nd!|du d" d#|v rt|d# |d$< n|d%ks|d&krf|
t	t|d |d |v rDt|d  nd!|d&k|d&kp\|du d' n|d(kr|
t	t|d |t|d |d |v rt|d  nd!|du d) n<|d*kr|
t	t|d |du d+ ndsJ d,| d-|v r|d- |d.< ||fS )/a@   Decode block definition string

    Gets a list of block arg (dicts) through a string notation of arguments.
    E.g. ir_r2_k3_s2_e1_i32_o16_se0.25_noskip

    All args can exist in any order with the exception of the leading string which
    is assumed to indicate the block type.

    leading string - block type (
      ir = InvertedResidual, ds = DepthwiseSep, dsa = DeptwhiseSep with pw act, cn = ConvBnAct)
    r - number of repeat blocks,
    k - kernel size,
    s - strides (1-9),
    e - expansion ratio,
    c - output channels,
    se - squeeze/excitation ratio
    n - activation fn ('re', 'r6', 'hs', or 'sw')
    Args:
        block_str: a string representation of block arguments.
    Returns:
        A list of block args (dicts)
    Raises:
        ValueError: if the string def not properly specified (TODO)
    _r   r   NnoskipFskipTnrer    Zr6Zrelu6ZhsZ
hard_swishswZswishmiZmishz(\d.*)   apZfcrcs)
block_typeout_chsstrider!   irr/   ese        )dw_kernel_sizeexp_kernel_sizepw_kernel_size	exp_ratiose_ratior8   ccnum_expertsdsdsa)rK   rM   rO   Zpw_actr8   er)rL   rM   rN   force_in_chsrO   r8   cn)kernel_sizer9   zUnknown block type (%s)Zgs
group_size)
isinstancestrr4   
startswithr	   r;   lenr6   r-   dictupdatefloat)	block_stropsrD   optionsr9   opkeyvvaluesplitsr!   rL   rM   rU   
num_repeat
block_argsr   r   r   _decode_block_strL   s    
























rj   ceilc                    s   t |}|dkr$tdt|| }ntt|| }g }|ddd D ]4}tdt|| | }|| ||8 }||8 }qH|ddd }g }	t| |D ]$\ }
|	 fddt	|
D  q|	S )a   Per-stage depth scaling
    Scales the block repeats in each stage. This depth scaling impl maintains
    compatibility with the EfficientNet scaling method, while allowing sensible
    scaling for other models that may have multiple block arg definitions in each stage.
    roundr   Nc                    s   g | ]}t  qS r   r   )r.   r7   bar   r   r0      r1   z&_scale_stage_depth.<locals>.<listcomp>)
summaxrl   r-   mathrk   appendzipextendrange)
stack_argsrepeatsdepth_multiplierdepth_truncrh   Znum_repeat_scaledZrepeats_scaledrA   rsZ	sa_scaledrepr   rn   r   _scale_stage_depth   s    	

r}   c                 C   s&  g }t |tr$t|t| ks2J n|ft|  }tt| |D ]\}\}}	t |tsZJ g }
g }|D ]n}t |tsxJ t|\}}|dddkr|dkr|d  |9  < |dur|	d| |

| |
| qf|r|dks|t| d kr|
t|
|d| q@|
t|
||	| q@|S )a6   Decode block architecture definition strings -> block kwargs

    Args:
        arch_def: architecture definition strings, list of list of strings
        depth_multiplier: network depth multiplier
        depth_trunc: networ depth truncation mode when applying multiplier
        experts_multiplier: CondConv experts multiplier
        fix_first_last: fix first and last block depths when multiplier is applied
        group_size: group size override for all blocks that weren't explicitly set in arch string

    Returns:
        list of list of block kwargs
    rQ   r   r   NrX   r#   )rY   tupler\   	enumeratert   listrZ   rj   get
setdefaultrs   r}   )Zarch_defry   rz   Zexperts_multiplierZfix_first_lastrX   Z	arch_args	stack_idxZblock_stringsr'   rw   rx   r`   ro   r|   r   r   r   r      s*    

 r   c                	   @   s<   e Zd ZdZddeddddddf	ddZd	d
 Zdd ZdS )r   a/   Build Trunk Blocks

    This ended up being somewhat of a cross between
    https://github.com/tensorflow/tpu/blob/master/models/official/mnasnet/mnasnet_models.py
    and
    https://github.com/facebookresearch/maskrcnn-benchmark/blob/master/maskrcnn_benchmark/modeling/backbone/fbnet_builder.py

         FNrJ   c
           
      C   s   || _ || _|| _|| _|| _|| _t|| _z| jddd d| _W n t	y^   d| _Y n0 || _
|	dkr|td d}	|	| _|	d	v sJ t| _d | _g | _d S )
Nr$   r#   Zrd_ratioTFZ	depthwisez>feature_location=='depthwise' is deprecated, using 'expansion'	expansion)
bottleneckr   r   )output_stridepad_typeround_chs_fnse_from_expr!   
norm_layerr
   se_layerse_has_ratio	TypeErrordrop_path_rater(   warningfeature_location_DEBUG_BUILDERverbosein_chsfeatures)
selfr   r   r   r   r!   r   r   r   r   r   r   r   __init__  s*    


zEfficientNetBuilder.__init__c                 C   s  | j | | }|d}| j|d< | |d |d< d|v rV|d rV| |d |d< | j|d< |d d urt|d n| j|d< |d d usJ | j|d< ||d< |d	kr|d
}|r| jd ur| js||	dd }| j
rt| j|d|d< n
| j|d< |dkrHtd|t|| j |	ddr8tf i |ntf i |}n|dks\|dkrtd|t|| j tf i |}nv|dkrtd|t|| j tf i |}nD|d	krtd|t|| j tf i |}ndsJ d| |d | _|S )NrD   r   rE   rU   r   r!   r   r   rV   rO   rN   r#   r   r   rG   z  InvertedResidual {}, Args: {}rQ   r   rR   rS   z!  DepthwiseSeparable {}, Args: {}rT   z  EdgeResidual {}, Args: {}z  ConvBnAct {}, Args: {}Fz-Uknkown block type (%s) while building model.)r   r   r   r   r   r!   r   r   r   r   r   r   r,   formatrZ   r   ZCondConvResidualZInvertedResidualZDepthwiseSeparableConvZEdgeResidualZ	ConvBnAct)r   ro   	block_idxZblock_countr   ZbtrO   blockr   r   r   _make_block8  sD    






,


zEfficientNetBuilder._make_blockc                 C   s^  t dt| | j || _tdd |D }d}d}d}g }|d d d dkr|td|d|| jd	krhd
ndd}| j| t	|D ]\}	}
|	d t|k}t d
|	| j t|
tsJ g }t	|
D ]z\}}|d t|
k}t d
|| j |d dv sJ |dkrd|d< d}|rN|	d }|t|kpL|| d d dk}|}|d dkr||d  }|| jkr||d  }d|d< t d
| j| j n|}||d< ||kr|}| |||}|| |r>tf |	d |d|| j}d|	 d| }|dd}|r*d||gn||d< | j| |d7 }q|tj|  q|S )aY   Build the blocks
        Args:
            in_chs: Number of input-channels passed to first block
            model_block_args: A list of lists, outer list defines stages, inner
                list contains strings defining block configuration(s)
        Return:
             List of block stacks (each stack wrapped in nn.Sequential)
        z&Building model trunk with %d stages...c                 S   s   g | ]}t |qS r   )r\   )r.   xr   r   r   r0   n  r1   z0EfficientNetBuilder.__call__.<locals>.<listcomp>r   r>   r   rF   Zact1r   Zforwardr   )moduleZnum_chsstage	reductionZ	hook_typez	Stack: {}z
 Block: {})r   r>   Fz=  Converting stride to dilation to maintain output_stride=={}Zdilation)r   r   zblocks.r2   r   )r,   r\   r   r   rp   r]   r   r   rs   r   r   rY   r   r   r   feature_infor   joinnnZ
Sequential)r   r   Zmodel_block_argsZtotal_block_countZtotal_block_idxZcurrent_strideZcurrent_dilationZstagesr   r   rw   Z
last_stackblocksr   ri   Z
last_blockZextract_featuresZnext_stack_idxZnext_dilationZnext_output_strider   module_nameZ	leaf_namer   r   r   __call__c  sx    	




zEfficientNetBuilder.__call__)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r     s   

+r   r   Tc                    sp  t | trn| jd | jd  | j  |r2 | j  t fdd| j| j}|| j | j	durlt
j| j	 nt | t
jr| jd | jd  | j  |r | j  t
j| jdtd   | j	durt
j| j	 nt | t
jrt
j| j t
j| j	 nht | t
jrl| jd d}d|v r8| jd}dt|   }t
j| j| | t
j| j	 dS )	a)   Weight initialization as per Tensorflow official implementations.

    Args:
        m (nn.Module): module to init
        n (str): module name
        fix_group_fanout (bool): enable correct (matching Tensorflow TPU impl) fanout calculation w/ group convs

    Handles layers in EfficientNet, EfficientNet-CondConv, MixNet, MnasNet, MobileNetV3, etc:
    * https://github.com/tensorflow/tpu/blob/master/models/official/mnasnet/mnasnet_model.py
    * https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/efficientnet_model.py
    r   r   c                    s   t j| dtd  S )Nr          @)r   initnormal_rr   sqrt)wZfan_outr   r   <lambda>  r1   z#_init_weight_goog.<locals>.<lambda>Nr   Z
routing_fnr#   )rY   r   rW   Zout_channelsgroupsr   rQ   Zweight_shapeZweightZbiasr   r   Zzeros_ZConv2dr   rr   r   ZBatchNorm2dZones_ZLinearsizeZuniform_)mr:   Zfix_group_fanoutZinit_weight_fnZfan_inZ
init_ranger   r   r   _init_weight_goog  s8    






r   )modelc                 C   s(   |pt }|  D ]\}}||| qd S r   )r   Znamed_modules)r   Zinit_fnr:   r   r   r   r   r     s    r   )r    )r#   r$   Nr%   )r#   rk   )r#   rk   r   FN)r   T)N)'r   loggingrr   r;   r   r   	functoolsr   Ztorch.nnr   Z_efficientnet_blocksZtimm.layersr   r   r	   r
   r   __all__	getLoggerr   r(   r   r   r   r]   r   r   r   r   r   r,   r6   rj   r}   r   r   r   Moduler   r   r   r   r   <module>   s@   


t
(     
. 
)