a
    dI"                     @   s2  d Z ddlZddlmZ ddlmZ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	lmZ G d
d dejZG dd dejZd$ddZd%ddZeeddedde eddedddZed&edddZed'edddZed(edddZed)edd d!Zed*edd"d#ZdS )+a   Selective Kernel Networks (ResNet base)

Paper: Selective Kernel Networks (https://arxiv.org/abs/1903.06586)

This was inspired by reading 'Compounding the Performance Improvements...' (https://arxiv.org/abs/2001.06268)
and a streamlined impl at https://github.com/clovaai/assembled-cnn but I ended up building something closer
to the original paper with some modifications of my own to better balance param count vs accuracy.

Hacked together by / Copyright 2020 Ross Wightman
    N)nnIMAGENET_DEFAULT_MEANIMAGENET_DEFAULT_STD)SelectiveKernelConvNormActcreate_attn   )build_model_with_cfg)register_modelgenerate_default_cfgs)ResNetc                       sR   e Zd ZdZddddddddejejddddf fdd	Zdd Zdd	 Z	  Z
S )
SelectiveKernelBasicr	   N@   c                    s   t t|   |pi }t||d}|dks2J d|dksBJ d|| }|| j }|
pZ|	}
t||f||
||d||| _t||fd|	dd	|| _t	||| _
|d
d| _|| _|| _d S )N	act_layer
norm_layerr	   z)BasicBlock only supports cardinality of 1r   z0BasicBlock doest not support changing base width)stridedilationaa_layer
drop_layer   F)kernel_sizer   	apply_actTZinplace)superr   __init__dict	expansionr   conv1r   conv2r   seact
downsample	drop_path)selfinplanesplanesr   r#   cardinality
base_width	sk_kwargsreduce_firstr   first_dilationr   r   
attn_layerr   
drop_blockr$   conv_kwargsfirst_planes	outplanes	__class__ Z/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/timm/models/sknet.pyr      s:    
zSelectiveKernelBasic.__init__c                 C   s*   t | jjdd d ur&tj| jjj d S Nweight)getattrr    bnr   initzeros_r7   r%   r4   r4   r5   zero_init_last@   s    z#SelectiveKernelBasic.zero_init_lastc                 C   sj   |}|  |}| |}| jd ur,| |}| jd ur@| |}| jd urT| |}||7 }| |}|S N)r   r    r!   r$   r#   r"   r%   xZshortcutr4   r4   r5   forwardD   s    








zSelectiveKernelBasic.forward__name__
__module____qualname__r   r   ZReLUZBatchNorm2dr   r=   rA   __classcell__r4   r4   r2   r5   r      s$   'r   c                       sR   e Zd ZdZddddddddejejddddf fdd	Zdd Zd	d
 Z	  Z
S )SelectiveKernelBottleneck   r	   Nr   c                    s   t t|   |pi }t||d}tt||d  | }|| }|| j }|
pT|	}
t||fddi|| _	t
||f||
|||d||| _t||fddd|| _t||| _|dd	| _|| _|| _d S )
Nr   r   r   r	   )r   r   groupsr   r   F)r   r   Tr   )r   rG   r   r   intmathfloorr   r   r   r   r    conv3r   r!   r"   r#   r$   )r%   r&   r'   r   r#   r(   r)   r*   r+   r   r,   r   r   r-   r   r.   r$   r/   widthr0   r1   r2   r4   r5   r   V   s.    
z"SelectiveKernelBottleneck.__init__c                 C   s*   t | jjdd d ur&tj| jjj d S r6   )r8   rM   r9   r   r:   r;   r7   r<   r4   r4   r5   r=   |   s    z(SelectiveKernelBottleneck.zero_init_lastc                 C   st   |}|  |}| |}| |}| jd ur6| |}| jd urJ| |}| jd ur^| |}||7 }| |}|S r>   )r   r    rM   r!   r$   r#   r"   r?   r4   r4   r5   rA      s    









z!SelectiveKernelBottleneck.forwardrB   r4   r4   r2   r5   rG   S   s$   &rG   Fc                 K   s   t t| |fi |S r>   )r
   r   )variant
pretrainedkwargsr4   r4   r5   _create_skresnet   s    rR    c                 K   s   | dddddt tddd
|S )	Ni  )r      rT   )   rU   g      ?Zbicubicr   Zfc)
urlZnum_classesZ
input_sizeZ	pool_sizeZcrop_pctinterpolationmeanZstd
first_conv
classifierr   )rV   rQ   r4   r4   r5   _cfg   s    r[   ztimm/)Z	hf_hub_idzconv1.0)rY   )zskresnet18.ra_in1kzskresnet34.ra_in1kzskresnet50.untrainedzskresnet50d.untrainedzskresnext50_32x4d.ra_in1k)returnc                 K   sB   t dddd}t f tg dt |ddd|}td	| fi |S )
zConstructs a Selective Kernel ResNet-18 model.

    Different from configs in Select Kernel paper or "Compounding the Performance Improvements..." this
    variation splits the input channels to the selective convolutions to keep param count down.
          ?   TZrd_ratioZ
rd_divisorsplit_input)   ra   ra   ra   r*   Fblocklayers
block_argsr=   
skresnet18r   r   rR   rP   rQ   r*   Z
model_argsr4   r4   r5   rg      s    rg   c                 K   sB   t dddd}t f tg dt |ddd|}td	| fi |S )
zConstructs a Selective Kernel ResNet-34 model.

    Different from configs in Select Kernel paper or "Compounding the Performance Improvements..." this
    variation splits the input channels to the selective convolutions to keep param count down.
    r]   r^   Tr_   r   rH      r   rb   Frc   
skresnet34rh   ri   r4   r4   r5   rl      s    rl   c                 K   s>   t dd}t f tg dt |ddd|}td| fi |S )zConstructs a Select Kernel ResNet-50 model.

    Different from configs in Select Kernel paper or "Compounding the Performance Improvements..." this
    variation splits the input channels to the selective convolutions to keep param count down.
    Tr`   rj   rb   Frc   
skresnet50r   rG   rR   ri   r4   r4   r5   rn      s    
rn   c              
   K   sD   t dd}t f tg ddddt |ddd|}td	| fi |S )
zConstructs a Select Kernel ResNet-50-D model.

    Different from configs in Select Kernel paper or "Compounding the Performance Improvements..." this
    variation splits the input channels to the selective convolutions to keep param count down.
    Trm   rj       deeprb   F)rd   re   Z
stem_widthZ	stem_typeZavg_downrf   r=   skresnet50dro   ri   r4   r4   r5   rr      s    

rr   c              	   K   sF   t dddd}t f tg dddt |ddd|}td	| fi |S )
zConstructs a Select Kernel ResNeXt50-32x4d model. This should be equivalent to
    the SKNet-50 model in the Select Kernel Paper
    g      ?rp   Fr_   rj   rH   rb   )rd   re   r(   r)   rf   r=   skresnext50_32x4dro   ri   r4   r4   r5   rs      s    
rs   )F)rS   )F)F)F)F)F)__doc__rK   Ztorchr   Z	timm.datar   r   Ztimm.layersr   r   r   Z_builderr
   	_registryr   r   Zresnetr   Moduler   rG   rR   r[   Zdefault_cfgsrg   rl   rn   rr   rs   r4   r4   r4   r5   <module>   s<   
==
	

