
    AVh                        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m	Z	 ddlm
Z
 ddlmZ  ej                  d	      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d      d
ej                  fd       Z ej                  d       d
ej                  fd!       Z ej                  d"      d
ej                  fd#       Z ej                  d$      d
ej                  fd%       Z ej                  d&      d
ej                  fd'       Z ej                  d(      d
ej                  fd)       Z ej                  d*      d+ej                  fd,       Z ej                  d-      d
ej                  fd.       Z ej                  d/      d
ej                  fd0       Z  ej                  d1      d
ej                  fd2       Z! ej                  d3      d
ej                  fd4       Z" ej                  d5      d
ej                  fd6       Z# ej                  d7      d
ej                  fd8       Z$ ej                  d9      d
ej                  fd:       Z% ej                  d;      d
ej                  fd<       Z& ej                  d=      d
ej                  fd>       Z' ej                  d?      d
ej                  fd@       Z( ej                  dA      d
ej                  fdB       Z) ej                  dC      d
ej                  fdD       Z* ej                  dE      d
ej                  fdF       Z+dG Z, ej                  dH      d
ej                  fdI       Z- ej                  dJ      d
ej                  fdK       Z. ej                  dL      d
ej                  fdM       Z/ ej                  dN      d
ej                  fdO       Z0 ej                  dP      d
ej                  fdQ       Z1 ej                  dR      d
ej                  fdS       Z2 ej                  dT      d
ej                  fdU       Z3 ej                  dV      d
ej                  fdW       Z4 ej                  dX      d
ej                  fdY       Z5 ej                  dZ      d
ej                  fd[       Z6 ej                  d\      d
ej                  fd]       Z7 ej                  d^      d_        Z8 ej                  d`      d
ej                  fda       Z9 ej                  db      d
ej                  fdc       Z: ej                  dd      d
ej                  fde       Z; ej                  df      d
ej                  fdg       Z< ej                  dh      d
ej                  fdi       Z=d
ej                  fdjZ> ej                  dk      d
ej                  fdl       Z? ej                  dm      d
ej                  fdn       Z@ ej                  do      d
ej                  fdp       ZA ej                  dq      d
ej                  fdr       ZB ej                  ds       ej                  dt      d
ej                  fdu              ZC ej                  dv      d
ej                  fdw       ZD ej                  dx      d
ej                  fdy       ZEdz ZF ej                  d{      d
ej                  fd|       ZGy)}z-Gradients for operators defined in nn_ops.py.    N)dtypes)ops)	array_ops)array_ops_stack)
gen_nn_ops)math_opsConv2DBackpropInputopc                    dt        j                  |t        j                  | j                  d         | j                  d   | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      | j                  d	      j                         
	      t        j                  || j                  d   | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      | j                  d	      j                         
      gS )The derivatives for deconvolution.

  Args:
    op: the Deconvolution op.
    grad: the tensor representing the gradient w.r.t. the output

  Returns:
    the gradients w.r.t. the input and the filter
  N      	dilationsstridespaddingexplicit_paddingsuse_cudnn_on_gpudata_formatr   r   r   r   r   r   )r   conv2d_backprop_filterr   shapeinputsget_attrdecodeconv2dr
   grads     M/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/nn_grad.py_Conv2DBackpropInputGradr      s    ''

//"))A,
'
))A,KK,++i(++i(KK(;<;;'9:kk-0779	; 

))A,KK,++i(++i(KK(;<;;'9:kk-0779;
     Conv2DBackpropFilterc                    t        j                  t        j                  | j                  d         || j                  d   | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      j                         		      d t        j                  | j                  d   || j                  d      | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      j                         	      gS )
Nr   r   r   r   r   r   r   r   r   )r   conv2d_backprop_inputr   r   r   r   r   r   r   s     r   _Conv2DBackpropFilterGradr$   B   s   
 &&
//"))A,
'

))A,KK,++i(++i(KK(;<;;'9:kk-0779	; =A
))A,
KK,++i(++i(KK(;<;;'9:kk-0779;
 r    "DepthwiseConv2dNativeBackpropInputc                    dt        j                  |t        j                  | j                  d         | j                  d   | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      	      t        j                  || j                  d   | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      	      gS )
r   Nr   r   r   r   r   r   r   r   r   r   r   r   )r   'depthwise_conv2d_native_backprop_filterr   r   r   r   depthwise_conv2d_nativer   s     r   '_DepthwiseConv2dNativeBackpropInputGradr*   ]   s     88

//"))A,
'
))A,KK,++i(++i(KK(;<kk-02 ((

))A,KK,++i(++i(KK(;<kk-02
 r    #DepthwiseConv2dNativeBackpropFilterc                    t        j                  t        j                  | j                  d         || j                  d   | j                  d      | j                  d      | j                  d      | j                  d      | j                  d            d t        j                  | j                  d   || j                  d      | j                  d      | j                  d      | j                  d      | j                  d            gS )	Nr   r   r   r   r   r   r   r'   )r   &depthwise_conv2d_native_backprop_inputr   r   r   r   r)   r   s     r   (_DepthwiseConv2dNativeBackpropFilterGradr.   ~   s     77
//"))A,
'

))A,KK,++i(++i(KK(;<kk-02 48((
))A,
KK,++i(++i(KK(;<kk-02
 r    Conv3Dc                     | j                  d      j                         }t        j                  | j                  d   | j                  d   g      \  }}t        j                  || j                  d   || j                  d      | j                  d      | j                  d      |      t        j                  | j                  d   ||| j                  d      | j                  d      | j                  d      |      gS )Nr   r   r   r   r   r   r   r   r   r   )r   r   r   shape_nr   r   conv3d_backprop_input_v2conv3d_backprop_filter_v2)r
   r   r   shape_0shape_1s        r   _Conv3DGradr7      s    M*113+&&		!biil'CD'7))

))A,
KK,++i(++i(!# **
))A,

KK,++i(++i(!
 r    Conv3DBackpropInputV2c                    | j                  d      j                         }d t        j                  |t	        j
                  | j                  d         | j                  d   | j                  d      | j                  d      | j                  d      |      t        j                  || j                  d   | j                  d      | j                  d      | j                  d      |      gS )Nr   r   r   r   r   r   r1   )r   r   r   r4   r   r   r   conv3dr
   r   r   s      r   _Conv3DBackpropInputGradr<      s    M*113+
**

//"))A,
'
))A,KK,++i(++i(!# 

))A,KK,++i(++i(!#
 r    Conv3DBackpropFilterV2c                    | j                  d      j                         }t        j                  t	        j
                  | j                  d         || j                  d   | j                  d      | j                  d      | j                  d      |      d t        j                  | j                  d   || j                  d      | j                  d      | j                  d      |      gS )Nr   r   r   r   r   r   r1   )r   r   r   r3   r   r   r   r:   r;   s      r   _Conv3DBackpropFilterGradr?      s    M*113+))
//"))A,
'

))A,KK,++i(++i(!# %)
))A,
KK,++i(++i(!#
 r    	AvgPool3Dc           
         t        j                  t        j                  | j                  d         || j                  d      | j                  d      | j                  d      | j                  d      j                               S Nr   ksizer   r   r   )rC   r   r   r   )r   avg_pool3d_gradr   r   r   r   r   r   s     r   _AvgPool3DGradrE      se    		#	#oobiil#
KK kk)$kk)$++m,335
7 7r    AvgPool3DGradc           
         t        j                  | j                  d         t        j                  || j                  d      | j                  d      | j                  d      | j                  d      j                               fS Nr   rC   r   r   r   r   )r   stop_gradientr   r   
avg_pool3dr   r   r   s     r   _AvgPool3DGradGradrL      sn    

!
!"))A,
/


kk'"kk)$kk)$++m4;;=?
@ @r    	MaxPool3Dc                    t        j                  | j                  d   | j                  d   || j	                  d      | j	                  d      | j	                  d      | j	                  d      j                               S rB   )r   max_pool3d_gradr   outputsr   r   r   s     r   _MaxPool3DGradrQ      sg    		#	#iiljjm
KK kk)$kk)$++m,335
7 7r    MaxPool3DGradc                    t        j                  | j                  d         t        j                  | j                  d         t        j                  | j                  d   | j                  d   || j                  d      | j                  d      | j                  d      | j                  d      j                               fS Nr   r   rC   r   r   r   r   r   )r   
zeros_liker   r   max_pool3d_grad_gradr   r   r   s     r   _MaxPool3DGradGradrX      s    


ryy|
,


ryy|
,

)
)iiliilkk'"kk)$kk),++m4;;=?	
@ 	@r    MaxPool3DGradGradc                    t        j                  | j                  d         t        j                  | j                  d         t        j                  | j                  d   | j                  d   || j                  d      | j                  d      | j                  d      | j                  d      j                               fS rT   )r   rV   r   r   rO   r   r   r   s     r   _MaxPool3DGradGradGradr[     s    


ryy|
,


ryy|
,

$
$iiliilkk'"kk)$kk),++m4;;=?	
@ 	@r    Softmaxc                 f    | j                   d   }t        j                  ||z  dd      }||z
  |z  S )a  The derivative of the softmax nonlinearity.

  We assume that probs is of shape [batch_size * dim]
  The formula for dsoftmax / dx = (diag(softmax) - softmax * softmax').
  This matrix is diagonal minus a rank one matrix, so it is easy to implement
  as follows:

    grad_x = grad_softmax * softmax - sum(grad_softmax * softmax) * softmax

  Args:
     op: the Softmax op.
     grad_softmax:  the tensor representing the gradient w.r.t. the softmax
       output.

  Returns:
     gradient w.r.t the input to the softmax

  r   Tkeepdims)rP   r   
reduce_sum)r
   grad_softmaxsoftmaxsum_channelss       r   _SoftmaxGradre     s:    ( JJqM'$$\G%;R$O,

%	00r    
LogSoftmaxc                     t        j                  | j                  d         }|t        j                  |dd      |z  z
  S )a  The gradient for log_softmax.

      log_softmax = input - log(sum(exp(input))
      dlog_softmax/dinput = diag - softmax(input)

  Args:
    op: The log softmax op.
    grad: The tensor representing the gradient w.r.t. the output.

  Returns:
    The gradients w.r.t. the input.
  r   r^   Tr_   )r   exprP   ra   )r
   r   rc   s      r   _LogSoftmaxGradri   2  s9     LLA''	##D"t<wF	FFr    BiasAddc                 z    	 | j                  d      }|t        j                  ||      fS # t        $ r d}Y &w xY w)a  Return the gradients for the 2 inputs of bias_op.

  The first input of unused_bias_op is the tensor t, and its gradient is
  just the gradient the unused_bias_op received.

  The second input of unused_bias_op is the bias vector which has one fewer
  dimension than "received_grad" (the batch dimension.)  Its gradient is the
  received gradient Summed on the batch dimension, which is the first dimension.

  Args:
    op: The BiasOp for which we need to generate gradients.
    received_grad: Tensor.  The gradients passed to the BiasOp.

  Returns:
    Two tensors, the first one for the "tensor" input of the BiasOp,
    the second one for the "bias" input of the BiasOp.
  r   N)out_backpropr   )r   
ValueErrorr   bias_add_grad)r
   received_gradr   s      r   _BiasAddGradrp   D  sP    &++m,K 

"
"(kC
D D 
 Ks   , ::BiasAddGradc           	      z   	 | j                  d      }t        j                  | j                  d         }t        j                  |      }|dk(  rft        j
                  t        j                  |dd       |t        j                  |dd       gd      }t        j
                  |dd dg|dd gd      }nJt        j
                  t        j                  |dd       |gd      }t        j
                  |dd dggd      }t        j                  ||      }t        j                  ||      S # t        $ r d}Y &w xY w)a(  Gradient for the BiasAddGrad op.

  Args:
    op: BiasAddGrad op for which we are calculating gradients.
    received_grad: The gradients passed to the BiasAddGrad op.

  Returns:
    A single gradient Tensor for the input to BiasAddGrad (which
    is the gradient of the bias term in BiasAdd)
  r   Nr      NCHWr   r   r^   )	r   rm   r   r   r   concat	ones_likereshapetile)r
   ro   r   r   
bias_shapeexpanded_shape
tile_multsexpanded_grads           r   _BiasAddGradGradr|   `  s3   ++m,K //"))A,
'%}-*G%%E"1I&
E!"I&' 	
N !!5!9qc59"=qAJ%%			U3BZ	(*5q:N!!5":s"3Q7J##M>B-	z	22% 
 Ks   D+ +D:9D:	BiasAddV1unused_bias_opc                     t        j                  t        j                  |      dz
        }|t        j                  ||      fS )a  Return the gradients for the 2 inputs of bias_op.

  The first input of unused_bias_op is the tensor t, and its gradient is
  just the gradient the unused_bias_op received.

  The second input of unused_bias_op is the bias vector which has one fewer
  dimension than "received_grad" (the batch dimension.)  Its gradient is the
  received gradient Summed on the batch dimension, which is the first dimension.

  Args:
    unused_bias_op: The BiasOp for which we need to generate gradients.
    received_grad: Tensor.  The gradients passed to the BiasOp.

  Returns:
    Two tensors, the first one for the "tensor" input of the BiasOp,
    the second one for the "bias" input of the BiasOp.
  r   )r   ranger   rankra   )r~   ro   reduction_dim_tensors      r   _BiasAddGradV1r     sC    & "	}(E(IJ
,,]-AC 
D Dr    Reluc                 H    t        j                  || j                  d         S Nr   )r   	relu_gradrP   r   s     r   	_ReluGradr         			dBJJqM	22r    EluGradc                     | j                   d   }t        j                  ||      t        j                  |dk  || j                   d   z  t        j
                  |            fS )Nr   r   )r   r   elu_gradr   whererV   )r
   r   elu_xs      r   _EluGradGradr     s[    
))A,%


dE
*
//ai		!,i.B.B5.IK
L Lr    SeluGradc                     | j                   d   }t        j                  ||      t        j                  |dk  || j                   d   z  t        j
                  |            fS )Nr   g        r   )r   r   	selu_gradr   r   rV   )r
   r   selu_xs      r   _SeluGradGradr     s[    99Q<&


tV
,
//rk4"))A,.	0D0DV0LN
O Or    Relu6c                 H    t        j                  || j                  d         S r   )r   
relu6_gradrP   r   s     r   
_Relu6Gradr     s    			tRZZ]	33r    	Relu6Gradc                 v    | j                   d   }t        j                  ||      t        j                  |      fS Nr   )r   r   r   r   rV   r
   r   xs      r   _Relu6GradGradr     s2    iil!


a
()*>*>q*A	BBr    	LeakyReluc                 r    | j                   d   }| j                  d      }t        j                  |||      S )Nr   alphar   )r   r   r   leaky_relu_gradr
   r   r   r   s       r   _LeakyReluGradr     s2    iil!
++g
%		#	#D!5	99r    LeakyReluGradc                     | j                   d   }| j                  d      }t        j                  |||      t	        j
                  |      fS )Nr   r   r   )r   r   r   r   r   rV   r   s       r   _LeakyReluGradGradr     sL    iil!
++g
%

$
$T1+023<3G3G3J
L Lr    Eluc                 H    t        j                  || j                  d         S r   )r   r   rP   r   s     r   _EluGradr     s    			T2::a=	11r    Seluc                 H    t        j                  || j                  d         S r   )r   r   rP   r   s     r   	_SeluGradr     r   r    Softplusc                 L    |t        j                  | j                  d         z  S r   )r   sigmoidr   r   s     r   _SoftplusGradr     s     	  1.	..r    SoftplusGradc                    | j                   \  }}t        j                  |g      5  t        j                  ||      }||z  t        j                  |       dz   t        j                  |      z   z  }||fcd d d        S # 1 sw Y   y xY w)Ng       @)r   r   control_dependenciesr   softplus_gradr   rh   )r
   r   dyr   ddyd2xs         r   _SoftplusGradGradr     sz     ))%"a
' 

"
"4
+C
)x||QB'#-Q?
@C:  s   AA??BSoftsignc                 H    t        j                  || j                  d         S r   )r   softsign_gradr   r   s     r   _SoftsignGradr     s    		!	!$		!	55r    ReluGradc                 v    | j                   d   }t        j                  ||      t        j                  |      fS r   )r   r   r   r   rV   r   s      r   _ReluGradGradr     s2    iil!


tQ
')=)=a)@	AAr    c                 8    t        j                  | d      } | |z  S )zMultiply after broadcasting vec to match dimensions of mat.

  Args:
    vec: A 1-D tensor of dimension [D0]
    mat: A 2-D tensor of dimension [D0, D1]

  Returns:
    A tensor of dimension [D0, D1], the result of vec * mat
  r^   )r   expand_dims)vecmats     r   _BroadcastMulr     s      	c2&#	sr    SoftmaxCrossEntropyWithLogitsc                    | j                   d   }t        ||      }| j                  d   }|~t        |dd      sqt	        j
                  |      }||t        j                  t        j                  t        j                  |d      t        j                  |d            d      z
  |z  z  }|t        |t	        j                  |             fS )z4Gradient function for SoftmaxCrossEntropyWithLogits.r   r   _is_zeros_tensorFr   axis)rP   r   r   getattrr   rc   r   squeezer   matmulr   log_softmaxr
   	grad_loss	grad_gradsoftmax_gradr   logitsrc   s          r   "_SoftmaxCrossEntropyWithLogitsGradr     s     A,	y,	/$99Q<&
)/
7  (Gi)++!!)Q/!!'1-	/ 	  	 D 
}Y)?)?)G(GH	HHr    #SparseSoftmaxCrossEntropyWithLogitsc                 ^   | j                   d   }t        ||      }| j                  d   }|~t        |dd      sqt	        j
                  |      }||t        j                  t        j                  t        j                  |d      t        j                  |d            d      z
  |z  z  }|dfS )z:Gradient function for SparseSoftmaxCrossEntropyWithLogits.r   r   Nr   Fr   r   )rP   r   r   r   r   rc   r   r   r   r   r   r   s          r   (_SparseSoftmaxCrossEntropyWithLogitsGradr     s     A,	y,	/$99Q<&
)/
7  (Gi)++!!)Q/!!'1-	/ 	  	 D 
tr    Conv2Dc                    | j                  d      }| j                  d      }| j                  d      }| j                  d      }| j                  d      }| j                  d      }t        j                  | j                  d   | j                  d   g      \  }}	t	        j
                  || j                  d   |||||||		      t	        j                  | j                  d   |	|||||||		      gS )
zGradient function for Conv2D.r   r   r   r   r   r   r   r   r   )r   r   r2   r   r   r#   r   )
r
   r   r   r   r   r   r   r   r5   r6   s
             r   _Conv2DGradr   6  s     kk+&)KK	"'KK	"'kk"56[[!34M*+&&		!biil'CD'7 &&

))A,
-+!	# ''
))A,

-+!	#
 r    DepthwiseConv2dNativec                 V   t        j                  t        j                  | j                  d         | j                  d   || j                  d      | j                  d      | j                  d      | j                  d      | j                  d            t        j                  | j                  d   t        j                  | j                  d         || j                  d      | j                  d      | j                  d      | j                  d      | j                  d            gS )	Nr   r   r   r   r   r   r   r'   )r   r-   r   r   r   r   r(   r   s     r   _DepthwiseConv2dNativeGradr   _  s     77
//"))A,
'
))A,
KK,++i(++i(KK(;<kk-02 88
))A,
//"))A,
'
KK,++i(++i(KK(;<kk-02
 r    
Dilation2Dc                    t        j                  | j                  d   | j                  d   || j                  d      | j                  d      | j                  d            t        j                  | j                  d   | j                  d   || j                  d      | j                  d      | j                  d            gS )Nr   r   r   ratesr   )r   dilation2d_backprop_inputr   r   dilation2d_backprop_filterr   s     r   _Dilation2DGradr   w  s     **299Q<1t+-;;y+A+-;;w+?+-;;y+AC ++BIIaL"))A,,.KK	,B,.KK,@,.KK	,BD	
 	r    LRNc           	          | j                  d      }| j                  d      }| j                  d      }| j                  d      }t        j                  || j                  d   | j                  d   ||||      gS )Ndepth_radiusbiasr   betar   )r   r   lrn_gradr   rP   )r
   r   r   r   r   r   s         r   _LRNGradr     sq    ^,,	V	$
++g
%	V	$$		!bjjm\4'
 r    AvgPoolc           
         t        j                  t        j                  | j                  d   t
        j                        || j                  d      | j                  d      | j                  d      | j                  d            S )Nr   )out_typerC   r   r   r   rI   )r   avg_pool_gradr   r   r   r   int32r   r   s     r   _AvgPoolGradr     sb    		!	!oobiilV\\:
kk'kk)kk)++m,
. .r    AvgPoolGradc           
          t        j                  | j                  d         t        j                  || j                  d      | j                  d      | j                  d      | j                  d            fS rH   )r   rJ   r   r   avg_poolr   r   s     r   _AvgPoolGradGradr     sc    

!
!"))A,
/


kk'"kk)$kk)$++m46
7 7r    MaxPoolc                    t        j                  | j                  d   | j                  d   || j	                  d      | j	                  d      | j	                  d      | j	                  d      | j	                  d            S )Nr   rC   r   r   r   r   )r   r   r   )r   max_pool_gradr   rP   r   r   s     r   _MaxPoolGradr     sk    		!	!iiljjm
kk'kk)kk)$$78++m,
. .r    	MaxPoolV2c                     | j                   d   }| j                   d   }t        j                  | j                   d   | j                  d   |||| j	                  d      | j	                  d            d d fS )Nr   r   r   r   r   rU   )r   r   max_pool_grad_v2rP   r   r
   r   rC   r   s       r   _MaxPoolGradV2r     sr    
))A,%IIaL'		$	$iiljjm
kk)$++m,
. 04T
: :r    MaxPoolWithArgmaxc                     ~t        j                  | j                  d   || j                  d   | j	                  d      | j	                  d      | j	                  d      | j	                  d            S )Nr   r   rC   r   r   include_batch_in_index)r   r  )r   max_pool_grad_with_argmaxr   rP   r   )r
   r   unused_argmax_grads      r   _MaxPoolGradWithArgmaxr    sb    		-	-iil
jjmkk'kk)kk)$[[)AB
 r    MaxPoolGradc                 l   t        j                  | j                  d         t        j                  | j                  d         t        j                  | j                  d   | j                  d   || j                  d      | j                  d      | j                  d      | j                  d            fS rT   )r   rV   r   r   max_pool_grad_gradr   r   s     r   _MaxPoolGradGradr    s     299Q<(299Q<(##
))A,
))A,

++g

++i
 ++i(kk-0
 r    MaxPoolGradV2c                 p   | j                   d   }| j                   d   }t        j                  | j                   d         t        j                  | j                   d         t        j                  | j                   d   | j                   d   |||| j                  d      | j                  d            d d fS )N      r   r   r   r   rU   )r   r   rV   r   max_pool_grad_grad_v2r   r   s       r   _MaxPoolGradGradV2r    s    
))A,%IIaL'299Q<(299Q<(&&
))A,
))A,


++i(kk-0 

 r    MaxPoolGradGradc                 l   t        j                  | j                  d         t        j                  | j                  d         t        j                  | j                  d   | j                  d   || j                  d      | j                  d      | j                  d      | j                  d            fS rT   )r   rV   r   r   r   r   r   s     r   _MaxPoolGradGradGradr    s     299Q<(299Q<(
))A,
))A,

++g

++i
 ++i(kk-0
 r    FractionalMaxPoolc           
          t        j                  | j                  d   | j                  d   || j                  d   | j                  d   | j	                  d            S )a  Returns gradient for FractionalMaxPool.

  Since FractionalMaxPool has three outputs, there are three gradients passed in
  for each of the outputs. Only the first one is useful, the other two gradients
  are empty.

  Args:
    op: The FractionalMaxPoolOp.
    grad_0: Gradient with respect to op.outputs[0]
    unused_grad_1: Gradient with respect to op.outputs[1]/row_seq. It is empty.
    unused_grad_2: Gradient with respect to op.outputs[2]/col_seq. It is empty.

  Returns:
    Input backprop for FractionalMaxPool op.
  r   r   r   overlapping)r   fractional_max_pool_gradr   rP   r   r
   grad_0unused_grad_1unused_grad_2s       r   _FractionalMaxPoolGradr    sR    & 
	,	,iiljjmjjmjjmkk- 
 r    FractionalAvgPoolc           	          t        j                  | j                  d   j                         || j                  d   | j                  d   | j                  d            S )a  Returns gradient for FractionalAvgPool.

  Since FractionalAvgPool has three outputs, there are three gradients passed in
  for each of the outputs. Only the first one is useful, the other two gradients
  are empty.

  Args:
    op: The FractionalAvgPoolOp.
    grad_0: Gradient with respect to op.outputs[0]
    unused_grad_1: Gradient with respect to op.outputs[1]/row_seq. It is empty.
    unused_grad_2: Gradient with respect to op.outputs[2]/col_seq. It is empty.

  Returns:
    Input backprop for FractionalAvgPool op.
  r   r   r   r  )r   fractional_avg_pool_gradr   	get_shaperP   r   r  s       r   _FractionalAvgPoolGradr  $  sO    & 
	,	,RYYq\-C-C-Ev-/ZZ]BJJqM-/[[-G
I Ir     BatchNormWithGlobalNormalizationc                     t        j                  | j                  d   | j                  d   | j                  d   | j                  d   || j                  d      | j                  d            \  }}}}}|||||fS )a$  Return the gradients for the 5 inputs of BatchNormWithGlobalNormalization.

  We do not backprop anything for the mean and var intentionally as they are
  not being trained with backprop in the operation.

  Args:
    op: The BatchNormOp for which we need to generate gradients.
    grad: Tensor.  The gradients passed to the BatchNormOp.

  Returns:
    dx: Backprop for input, which is (grad * (g * rsqrt(v + epsilon)))
    dm: Backprop for mean, which is
        sum_over_rest(grad * g) * (-1 / rsqrt(v + epsilon))
    dv: Backprop for variance, which is
        sum_over_rest(grad * g * (x - m)) * (-1/2) * (v + epsilon) ^ (-3/2)
    db: Backprop for beta, which is grad reduced in all except the
        last dimension.
    dg: Backprop for gamma, which is (grad * ((x - m) * rsqrt(v + epsilon)))
  r   r   r   r  variance_epsilonscale_after_normalization)r   )batch_norm_with_global_normalization_gradr   r   )r
   r   dxdmdvdbdgs          r   %_BatchNormWithGlobalNormalizationGradr*  <  sw    * "KKiilBIIaL"))A,		!dkk$%r{{3N'OQ"b"b" 
RR	r    c           	         | j                   d   }|d   }| j                   d   }| j                  d      }| j                  d      }| j                  d      }|dk(  rt        j                  }	n&|dk(  rt        j                  }	nt        j
                  }	|rK|||| j                  d   | j                  d   |||d	}
|dk(  r| j                  d
   |
d<    |	di |
\  }}}}}n| j                   d   }| j                   d   }|dk(  r1t        j                  |g d      }t        j                  |g d      }n5|dk(  r0t        j                  |g d      }t        j                  |g d      }|dv rdnd}||||||||d	}
|dk(  r| j                  d
   |
d<    |	di |
\  }}}}}|dk(  rt        j                  |g d      }n|dk(  rt        j                  |g d      }|||ddfS )a  Return the gradients for the 3 inputs of BatchNorm.

  Args:
    op: The BatchNormOp for which we need to compute gradients.
    version: Integer indicating which version to use of the fused batch
      norm gradient.
    *grad: An argument list for tensors of gradients wrt the outputs
      with grad[0] as grad_y.

  Returns:
    grad_x: gradient for x, which is scale * rsqrt(variance + epsilon) *
            [grad_y - mean(grad_y) - (x - mean(x)) *
            mean(grad_y * (x - mean(x))) / (variance + epsilon)]
            in training mode; grad_y * scale * rsqrt(pop_variance + epsilon)
            in freeze mode.

    grad_scale: gradient for scale, which is sum(grad_y * (x - mean(x)) *
                rsqrt(variance + epsilon)) in training mode;
                sum(grad_y * (x - pop_mean) * rsqrt(pop_variance + epsilon))
                in freeze mode.

    grad_offset: gradient for offset, which is sum(grad_y) in training mode;
                 sum(grad_y) in freeze mode.
  r   r   epsilonr   is_trainingr   r  r  )
y_backpropr   scalereserve_space_1reserve_space_2r,  r   r-     reserve_space_3rs   )r   r   r  r   s   NCDHW)r   r   r  r  r   )rs   s   NHWCNHWCNDHWC)r   r  r   r   )r   r  r   r   r  N )	r   r   r   fused_batch_norm_grad_v3fused_batch_norm_grad_v2fused_batch_norm_gradrP   r   	transpose)r
   versionr   r   grad_yr/  r,  r   r-  grad_funargsr%  dscaledoffset_pop_meanpop_vartarget_data_formats                     r   _BaseFusedBatchNormGradrE  W  s	   2 	iil!7&
))A,%KK	"'M*+M*+\22H!|22H//H::a=::a=""	D !| "

1d ( 04 0BAyy|HiilGg


a
.a""6<8f		 


a
1a""6?;f$/ 4= %=&BI  #")"	D !| "

1d ( 04 0BAgr<0b		 r?3b	VWdD	((r    FusedBatchNormc                     t        | dg| S r   rE  r   s     r   _FusedBatchNormGradrI        	 Q	.	..r    FusedBatchNormV2c                     t        | dg| S r   rH  r   s     r   _FusedBatchNormV2GradrM    rJ  r    FusedBatchNormV3c                     t        | dg| S )Nr   rH  r   s     r   _FusedBatchNormV3GradrP    rJ  r    L2Lossc                 &    | j                   d   |z  S )zReturn the gradients for L2Loss.

  Args:
    op: The L2LossOp for which we need to generate gradients.
    grad: Tensor containing a single number.

  Returns:
    The gradient, which is (x * grad).
  r   )r   r   s     r   _L2LossGradrS    s     
1	r    TopKTopKV2c                    t        j                  | j                  d         }t        j                  | j                  d         }t        j                  t        j                  |t        j                        t        j                  |      dz
        }t        j                  | j                  d   t        j                  d|g            }t        j                  t        j                  |t        j                        t        j                  |      dz
        }t        j                  |      d   }t        j                  |t        j                  t        j                  t        j                  dt        j                  |t        j                        |z  |      d      t        j                        z   dg      }	t        j                  t        j                   t        j                  |	d      t        j                  |dg      t        j"                  |      g      |      t        j$                  g t        j                        gS )aE  Return the gradients for TopK.

  Args:
    op: The TopKOp for which we need to generate gradients.
    grad: Tensor. The gradients passed to the TopKOp.

  Returns:
    A list of two tensors, the first being the gradient w.r.t to the input and
    TopK, and the second being the gradient w.r.t. to the indices (all zero).
  r   r   r^   )dtype)r   r   r   rP   gatherr   castr   int64sizerv   r   stackr   r   r   
scatter_ndreduce_prodzeros)
r
   r   rA  in_shape	ind_shapeind_lastdimind_2d
in_lastdimouterdiminds
             r   	_TopKGradrg    s    __RYYq\*(oobjjm,)   mmIv||,nnY!#%+ jjm_**B+<=?& mmHfll+nnX"$* __V$Q'(x}}


nnQ%]]8V\\BZO')*,. 06||	= = @Bd	D# 


##C,i.?.?rd.K##H-.019; oob-
 r    
ApproxTopKc                    	
  j                   d   j                  dgz   	t        j                  t        j
                        }j                  
 j                  d      dk  r
z   	 
fdt        j                  t        fdt        
      D              
      }t        j                  ||
g      }t        j                  ||g      }t        j                  || j                  d   j                        S )zReturn the gradients for ApproxTopK.

  Args:
    op: The ApproxTopK for which we need to generate gradients.
    grad: The gradients for backprop.

  Returns:
    Scattered gradient based on the top-k indices.
  r   reduction_dimensionr   c                 *   | k(  r#t        j                  j                  d         S |    }t        t	        j
                  ddz               }||| <   t        j                  t        j                  |      |      }t        j                  |      S r   )	r   rv   rP   list	itertoolsrepeatr   r   broadcast_to)	diota_len
iota_shapeiota	idx_shapelifted_idx_shaper
   r   reduction_dims	       r   GetLiftedIdxz)_ApproxTopKGradient.<locals>.GetLiftedIdx  s    Mrzz!}.>??|Hi&&q$(34JJqMX^^H5zBD!!$(899r    c              3   .   K   | ]  } |        y w)Nr6  ).0rp  rw  s     r   	<genexpr>z&_ApproxTopKGradient.<locals>.<genexpr>  s     
0q<?
0s   r   )rP   r   	functoolsreduceoperatormulr   r   r   rt   rl  r   rv   r]  r   )r
   r   rA  flat_shape_len
lifted_idxflat_idx	flat_gradrw  rt  ru  r   rv  s   `      @@@@@r   _ApproxTopKGradientr    s    " jjm!!)!_##HLL)<.	$++34-Q=(M: : 

0E$K
00t=*zND+AB(~&67)			h	299Q<3E3E	FFr    
NthElementc                    | j                   d   }| j                  d   }t        j                  t        j                  t        j                  |d      |      |j                        }t        j                  |d      }t        j                  t        j                  |d      d      }t        j                  ||      |z  dgS )a:  Return the gradients for NthElement.

  Args:
    op: The NthElementOp for which we need to generate gradients.
    grad: Tensor. The gradients passed to the NthElementOp

  Returns:
    A list of two tensors, the first being the gradient w.r.t. the input,
    the second being the gradient w.r.t. the N (None).
  r   r^   N)
r   rP   r   rY  equalr   r   rW  ra   divide)r
   r   inputoutput
indicatorsnum_selecteds         r   _NthElementGradr    s     ))A,%::a=&
 }}nnY**626>

L* 
		tR	($&&x':'::r'JBO,
//*l
3d
:D	AAr    c           	         g }t        t        j                  | | j                  d         t        j                  ||j                  d               D ]m  \  }}t	        j
                  ||t	        j                  |      dz         }|j                  t        j                  t        j                  ||      dg             o t        j                  |d      S )a}  Replaces each segment with its mean along the last axis.

  Specifically, each value in the `inputs` tensor gets replaced by the mean
  value computed from the values that belong to the same segment.

  Args:
   inputs: A 2-tensor. Aggregation is done over dimension 1.
   segments: A 2-tensor, same shape as `input`.

  Returns:
    The result, same shape and type as `inputs`.
  r   r   )num_segmentsr^   r   )zipr   splitr   r   unsorted_segment_mean
reduce_maxappendrv   rX  r   r\  )r   segmentsresultinputs_i
segments_imeans_is         r   _MeanAggregatorr  9  s     &!ooffll1o.oohq 124 Hh
 ,,*8+>+>z+JQ+NPG
MM)**7J?"FHH 
		vA	..r    IsotonicRegressionc                 :    ~| j                   d   }t        ||      S )af  Gradient for the isotonic regression function.

  Args:
    op: The IsotonicRegression tensorflow op.
    grad_output: Tensor of incoming gradients with respect to the output.
    grad_segments: Tensor of incoming gradients with respect to the segments.

  Returns:
    A tensor, same size as `grad_output` with the gradient with respect to
    the input.
  r   )rP   r  )r
   grad_outputgrad_segmentsr  s       r   _IsotonicRegressionGradr  T  s!     ZZ](	h	//r    )H__doc__r{  rm  r}  tensorflow.python.frameworkr   r   tensorflow.python.opsr   r   r   r   RegisterGradient	Operationr   r$   r*   r.   r7   r<   r?   rE   rL   rQ   rX   r[   re   ri   rp   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r*  rE  rI  rM  rP  rS  rg  r  r  r  r  r6  r    r   <module>r     s
   4    . + + 1 , * +,! ! -!H ,-#--  .4 :;  <@ ;<  =, hCMM   0 -.  /, ./#--  0* k"7s}} 7 #7 o&@3== @ '@ k"7s}} 7 #7 o&
@3== 
@ '
@ )*
@s}} 
@ +
@ i 1S]] 1 !10 l#G G $G" i DS]] D !D6 m$ 3  3 % 3F k"D3== D #D. f3#-- 3 3 i LS]] L !L j!Ocmm O "O g43== 4 4 k"Cs}} C #C
 k":s}} : #: o&L3== L 'L e2 2 2 f3#-- 3 3 j!/cmm / "/ n%	#-- 	 &	 j!6cmm 6 "6 j!Bcmm B "B
 56I3== I 7I0 ;<  =6 h%CMM %  %P -.3==  /. l#
 
 $
 e   i .S]] . !. m$7 7 %7 i 	.S]] 	. !	. k"
:s}} 
: #
: )*
s}} 
 +
 m$ %  o&3==  '( '(S]]  )  )* +8 )*II +I. 89cmm  :4O) O)d &'/CMM / (/ ()/cmm / */ ()/cmm / */ h
CMM 
  
 fh*#-- *   *Z l#%GCMM %G $%GP l#B B $B4/6 *+0 0 ,0r    