o
    پig"                     @   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$defddZed$defddZed$defddZed$defd d!Zed$def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sJ d|dks!J d|| }|| j }|
p-|	}
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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__ E/home/ubuntu/.local/lib/python3.10/site-packages/timm/models/sknet.pyr      s:   

zSelectiveKernelBasic.__init__c                 C   .   t | jjdd d urtj| jjj d S d S Nweight)getattrr!   bnr   initzeros_r9   r&   r5   r5   r6   zero_init_last@      z#SelectiveKernelBasic.zero_init_lastc                 C   sj   |}|  |}| |}| jd ur| |}| jd ur | |}| jd ur*| |}||7 }| |}|S N)r    r!   r"   r%   r$   r#   r&   xshortcutr5   r5   r6   forwardD   s   








zSelectiveKernelBasic.forward__name__
__module____qualname__r   r   ReLUBatchNorm2dr   r?   rE   __classcell__r5   r5   r3   r6   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 }|
p*|	}
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   rM   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%   r0   widthr1   r2   r3   r5   r6   r   V   s.   

z"SelectiveKernelBottleneck.__init__c                 C   r7   r8   )r:   rS   r;   r   r<   r=   r9   r>   r5   r5   r6   r?   |   r@   z(SelectiveKernelBottleneck.zero_init_lastc                 C   st   |}|  |}| |}| |}| jd ur| |}| jd ur%| |}| jd ur/| |}||7 }| |}|S rA   )r    r!   rS   r"   r%   r$   r#   rB   r5   r5   r6   rE      s   









z!SelectiveKernelBottleneck.forwardrF   r5   r5   r3   r6   rM   S   s&    &rM   Fc                 K   s   t t| |fi |S rA   )r
   r   )variant
pretrainedkwargsr5   r5   r6   _create_skresnet   s   rX    c                 K   s   | dddddt tddd
|S )	Ni  )r      rZ   )   r[   g      ?bicubicr    fc)
urlnum_classes
input_size	pool_sizecrop_pctinterpolationmeanstd
first_conv
classifierr   )r^   rW   r5   r5   r6   _cfg   s   rh   ztimm/)	hf_hub_idzconv1.0)rf   )zskresnet18.ra_in1kzskresnet34.ra_in1kzskresnet50.untrainedzskresnet50d.untrainedzskresnext50_32x4d.ra_in1kreturnc                 K   F   t dddd}t tg dt |ddd}td	| fi t |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rd_ratio
rd_divisorsplit_input)   rr   rr   rr   r+   Fblocklayers
block_argsr?   
skresnet18r   r   rX   rV   rW   r+   
model_argsr5   r5   r6   rx         rx   c                 K   rk   )
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.
    rl   rm   Trn   r   rN      r   rs   Frt   
skresnet34ry   rz   r5   r5   r6   r      r|   r   c                 K   sB   t dd}t tg dt |ddd}td| fi t |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rq   r}   rs   Frt   
skresnet50r   rM   rX   rz   r5   r5   r6   r      s   
r   c              	   K   sH   t dd}t tg ddddt |ddd}td	| fi t |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.
    Tr   r}       deeprs   F)ru   rv   
stem_width	stem_typeavg_downrw   r?   skresnet50dr   rz   r5   r5   r6   r      s   

r   c                 K   sJ   t dddd}t tg dddt |ddd}td	| fi t |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      ?r   Frn   r}   rN   rs   )ru   rv   r)   r*   rw   r?   skresnext50_32x4dr   rz   r5   r5   r6   r      s   
r   )F)rY   )__doc__rQ   torchr   	timm.datar   r   timm.layersr   r   r   _builderr
   	_registryr   r   resnetr   Moduler   rM   rX   rh   default_cfgsrx   r   r   r   r   r5   r5   r5   r6   <module>   s>    
=
=
	
