o
    ':j                     @   sj   d dl mZ d dlmZ ddlmZmZmZmZ d dl	m  m
Z
 G dd dejZG dd dejZdS )	    )OrderedDictN   )ABNACT_LEAKY_RELUACT_ELUACT_NONEc                       s4   e Zd ZdZdddedf fdd	Zdd Z  ZS )ResidualBlocka^  Configurable residual block

    Parameters
    ----------
    in_channels : int
        Number of input channels.
    channels : list of int
        Number of channels in the internal feature maps. Can either have two or three elements: if three construct
        a residual block with two `3 x 3` convolutions, otherwise construct a bottleneck block with `1 x 1`, then
        `3 x 3` then `1 x 1` convolutions.
    stride : int
        Stride of the first `3 x 3` convolution
    dilation : int
        Dilation to apply to the `3 x 3` convolutions.
    groups : int
        Number of convolution groups. This is used to create ResNeXt-style blocks and is only compatible with
        bottleneck blocks.
    norm_act : callable
        Function to create normalization / activation Module.
    dropout: callable
        Function to create Dropout Module.
    r   Nc                    s  t t|   t|dkrt|dkrtdt|dkr%|dkr%tdt|dk}|dkp4||d k}	|s||d }
t|
_dtj||d d||d	|d
fd||d fdtj|d |d dd|d	|d
fd|
fg}|d ur|dd d| fg |dd   }nb||d }t|_dtj||d dddd	dfd||d fdtj|d |d d||d	||dfd||d fdtj|d |d dddd	dfd|fg}|d ur|dd d| fg |dd   }t	t
|| _|	rtj||d d|dd	d| _||d | _t| j_d S d S )N      0channels must contain either two or three valuesr   /groups > 1 are only valid if len(channels) == 3conv1r   Fstridepaddingbiasdilationbn1conv2bn2dropoutr   r   r   r   r   r   groupsr   conv3bn3   )superr   __init__len
ValueErrorr   
activationnnConv2d
Sequentialr   convs	proj_convproj_bn)selfin_channelschannelsr   r   r   norm_actr   is_bottleneckneed_proj_convr   layersr   	__class__ 2/home/ubuntu/htdocs/OOTD3/SCHP/modules/residual.pyr   !   sR   $ 	$zResidualBlock.__init__c                 C   sv   t | dr| |}| |}n|}| || }| jjjtkr+tj|| jjj	ddS | jjjt
kr9tj|ddS |S )Nr'   T)negative_slopeinplace)r5   )hasattrr'   r(   r&   r   r"   r   
functional
leaky_relusloper   elu)r)   xresidualr2   r2   r3   forwardV   s   

zResidualBlock.forward)__name__
__module____qualname____doc__r   r   r=   __classcell__r2   r2   r0   r3   r   	   s    5r   c                       s0   e Zd Zdddedf fdd	Zdd Z  ZS )IdentityResidualBlockr   Nc                    s  t t|   t|dkrt|dkrtdt|dkr%|dkr%tdt|dk}|dkp4||d k}	||| _|s|dtj||d d||d	|d
fd||d fdtj|d |d dd|d	|d
fg}
|dur{|
dd d| fg |
dd  }
nVdtj||d d|dd	dfd||d fdtj|d |d dd|d	||dfd||d fdtj|d |d dddd	dfg}
|dur|
dd d| fg |
dd  }
tt	|
| _
|	rtj||d d|dd	d| _dS dS )a  Configurable identity-mapping residual block

        Parameters
        ----------
        in_channels : int
            Number of input channels.
        channels : list of int
            Number of channels in the internal feature maps. Can either have two or three elements: if three construct
            a residual block with two `3 x 3` convolutions, otherwise construct a bottleneck block with `1 x 1`, then
            `3 x 3` then `1 x 1` convolutions.
        stride : int
            Stride of the first `3 x 3` convolution
        dilation : int
            Dilation to apply to the `3 x 3` convolutions.
        groups : int
            Number of convolution groups. This is used to create ResNeXt-style blocks and is only compatible with
            bottleneck blocks.
        norm_act : callable
            Function to create normalization / activation Module.
        dropout: callable
            Function to create Dropout Module.
        r	   r
   r   r   r   r   r   r   Fr   r   r   Nr   r   r   r   r   r   )r   rC   r   r    r!   r   r#   r$   r%   r   r&   r'   )r)   r*   r+   r   r   r   r,   r   r-   r.   r/   r0   r2   r3   r   g   sD   
$ $ zIdentityResidualBlock.__init__c                 C   sJ   t | dr| |}| |}n	| }| |}| |}|| |S )Nr'   )r6   r   r'   cloner&   add_)r)   r;   r   shortcutoutr2   r2   r3   r=      s   




zIdentityResidualBlock.forward)r>   r?   r@   r   r   r=   rB   r2   r2   r0   r3   rC   f   s    DrC   )collectionsr   torch.nnr#   bnr   r   r   r   torch.nn.functionalr7   Moduler   rC   r2   r2   r2   r3   <module>   s    ]