U
    d.                  
   @   s   d dl mZ d dlZG dd dZdddZdd	d	d
dddZddddgZe  edZ	e	
ej dddZdddZdS )    )brewNc                   @   sH   e Zd ZdZdddZddd	Zd
d Zdd ZdddZdddZ	dS )ResNetBuilderz8
    Helper class for constructing residual blocks.
    h㈵>?c                 C   s<   || _ d| _d| _|| _|| _|| _|| _|r2dnd| _d S )Nr      )model
comp_countcomp_idx	prev_blobis_test
bn_epsilonbn_momentumno_bias)selfr   r
   r   r   r   r    r   ?/tmp/pip-unpacked-wheel-ua33x9lu/caffe2/python/models/resnet.py__init__   s    	zResNetBuilder.__init__r   r   c                 C   sL   |  j d7  _ tj| j| jd| j| j f ||di f||||| jd| _| jS )Nr   zcomp_%d_conv_%dMSRAFill)weight_initkernelstridegrouppadr   )r	   r   convr   r
   r   r   )r   Z
in_filtersZout_filtersr   r   r   r   r   r   r   add_conv)   s    	zResNetBuilder.add_convc                 C   s   t | j| j| j| _| jS )N)r   relur   r
   )r   r   r   r   add_reluB   s    zResNetBuilder.add_reluc              	   C   s6   t j| j| jd| j| jf || j| j| jd| _| jS )Nzcomp_%d_spatbn_%depsilonZmomentumr   )	r   
spatial_bnr   r
   r   r	   r   r   r   )r   num_filtersr   r   r   add_spatial_bnJ   s    	zResNetBuilder.add_spatial_bnTc           	      C   s$  d| _ | j}| j||ddd |r,| | |   | j||d||dd |rX| | |   | j||dd}|r~| |}||krtj| j|d| j ||di fd|| j	d		}|rtj
| j|d
| j || j| j| jd}t| j||gd| j| j f | _|  j d7  _ |   |  jd7  _|S )Nr   r   r   r      )r   r   r   r   )r   shortcut_projection_%dr   r   r   r   r   shortcut_projection_%d_spatbnr   comp_%d_sum_%d)r	   r
   r   r!   r   r   r   r   r   r   r   r   r   r   sum)	r   input_filtersZbase_filtersZoutput_filtersr   r   spatial_batch_normshortcut_blob	last_convr   r   r   add_bottleneckZ   sp    	
	


 zResNetBuilder.add_bottleneckFc                 C   s  d| _ | j}| j||d|dkr"dnddd |r:| | |   | j||ddd}|rb| |}||krtj| j|d| j ||d	i fd|dkrdnd| j	d
	}|rtj
| j|d| j |d| jd}t| j||gd| j| j f | _|  j d7  _ |   |  jd7  _d S )Nr   r#   Fr      r   r   r   )r   r   r$   r   r%   r&   MbP?r   r   r'   )r	   r
   r   r!   r   r   r   r   r   r   r   r   r(   )r   r)   r    down_samplingr*   r+   r,   r   r   r   add_simple_block   sX    

	 zResNetBuilder.add_simple_blockN)r   r   )r   r   r   )r   r   T)FT)
__name__
__module____qualname____doc__r   r   r   r!   r-   r3   r   r   r   r   r      s"   
  
   
   
W  r   Fc              	   C   s   t j| |d|dddd t j| dddd|d t | dd	 dd
dg}t| d	d|d}d}tddD ]X}	tdd| D ]<}
|j|
dkr|n||	 ||	 |
dkr|	dkrdndd qv||	 }qdt j| |jdddd t 	| ddd| t 
| dd}|S )zp
    Create residual net for smaller images (sec 4.2 of He et. al (2015))
    num_groups = 'n' in the paper
    conv1   r#   r   r"   Zconv1_spatbnr0   r1   Zrelu1    @   r   )r   r   r.   TF)r2   	final_avg   last_outsoftmax)r   r   r   r   r   ranger3   average_poolr
   fcr?   )r   datanum_input_channels
num_groups
num_labelsr   filtersbuilderZprev_filtersZgroupidxZblockidxr?   r   r   r   create_resnet_32x32   sT               

    rI   )r.   r.   r.   r.   )r#         r#   )r#   rJ      r#   )r#   r=   $   r#   )r#      rM   r#   )   "   2   e         r   r.   Zresnext_builder   r   r   c           $      C   s  |t kr|d| t | }t}dddddg}|dkrHdddddg}|d	 }tj| |d
||d di f||d|
d
}tj| |d|d |||d}t| ||}tj| |ddddd}t	| ||
|ddd}|| }t
dD ]\}|| }|| }|| }t
|D ].}|j||||d  |dkr"|nd|d}q|d9 }qtj| |jd|ddd} t| | d|||}!|	rr|!S |d k	r| |!|gddg\}"}#|"|#fS t| |!dS d S ) Nz&{}-layer is invalid for resnext configr;      i   i   i   )rO   rP      r8   r   r   r#   )r   r   r   r   r   Zconv1_spatbn_relur   Zpool1r.   r   r/   r   r   )r   r   r   r   rJ   )r   r   r<   T)r   r   Zglobal_poolingzlast_out_L{}r?   loss)RESNEXT_BLOCK_CONFIGerrorformatRESNEXT_STRIDESr   r   r   r   max_poolr   r@   r-   rA   r
   rB   ZSoftmaxWithLossr?   )$r   rC   rD   rF   
num_layersrE   num_width_per_grouplabelr   no_lossr   conv1_kernelconv1_stridefinal_avg_kernellogr   r   Z
num_blocksstridesr    Znum_featuresZ	conv_blobZbn_blobZ	relu_blobr^   rH   Z	inner_dimZresidual_idxZresidual_numZresidual_strideZdim_inZblk_idxr<   r>   r?   rY   r   r   r   create_resnext#  s    	  


    
rh   c                 C   s$   t | |||ddd||||||	|
dS )NrQ   r   r;   )
r_   rE   r`   ra   r   rb   r   rc   rd   re   )rh   )r   rC   rD   rF   ra   r   rb   r   rc   rd   re   r   r   r   create_resnet50  s     ri   )F)
NFFr   rU   r.   rU   Nr   r   )NFFr   rU   r.   rU   )Zcaffe2.pythonr   loggingr   rI   rZ   r]   basicConfig	getLoggerrf   setLevelDEBUGrh   ri   r   r   r   r   <module>   sF   	 Z 
(	
          
w       