
    AVh9                        d 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 dd	lmZ dd
lmZ ddlmZ ddlmZ dZdZ G d d      Z edg        G d de             Z edg        G d de             Z edg        G d de             Z edg        G d de             Z edg        G d d e             Z G d! d"e      Z G d# d$e      Z G d% d&e      Z G d' d(e      Z G d) d*e      Z G d+ d,e      ZeZ eZ!eZ"eZ#eZ$eZ%eZ&eZ'eZ(eZ)eZ*d4d-Z+d4d.Z,d4d/Z-d4d0Z.d1 Z/ G d2 d3      Z0exZ1Z2exZ3Z4eZ5exZ6Z7exZ8Z9eZ:eZ;eZ<eZ=eZ>y)5zInitializers for TF 2.    N)constant_op)dtypes)	array_ops)gen_linalg_ops)linalg_ops_impl)math_ops)
random_ops)stateless_random_ops)_compute_fans)	tf_exportpartition_shapepartition_offsetc                   6    e Zd ZdZddZd Zed        ZddZy)	Initializera[  Initializer base class: all initializers inherit from this class.

  Initializers should implement a `__call__` method with the following
  signature:

  ```python
  def __call__(self, shape, dtype=None, **kwargs):
    # returns a tensor of shape `shape` and dtype `dtype`
    # containing values drawn from a distribution of your choice.
  ```
  Nc                     t         )a  Returns a tensor object initialized as specified by the initializer.

    Args:
      shape: Shape of the tensor.
      dtype: Optional dtype of the tensor. If not provided will return tensor
        of `tf.float32`.
      **kwargs: Additional keyword arguments. Accepted values:
        `partition_shape` and `partition_offset`. Used when creating a single
        partition in a partitioned variable. `partition_shape` is the shape of
        the partition (i.e. the shape of the returned tensor) and
        `partition_offset` is a tuple of `int` specifying the offset of this
        partition w.r.t each axis. For example, a tensor of shape `(30, 100)`
        can be partitioned into two partitions: `p0` of shape `(10, 100)` and
        `p1` of shape `(20, 100)`; if the initializer is called with
        `partition_shape=(20, 100)` and `partition_offset=(10, 0)`, it should
        return the value for `p1`.
    )NotImplementedErrorselfshapedtypekwargss       Q/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/init_ops_v2.py__call__zInitializer.__call__0   s
    $     c                     i S )zReturns the configuration of the initializer as a JSON-serializable dict.

    Returns:
      A JSON-serializable Python dict.
     r   s    r   
get_configzInitializer.get_configD   s	     Ir   c                 6    |j                  dd        | di |S )a{  Instantiates an initializer from a configuration dictionary.

    Example:

    ```python
    initializer = RandomUniform(-1, 1)
    config = initializer.get_config()
    initializer = RandomUniform.from_config(config)
    ```

    Args:
      config: A Python dictionary.
        It will typically be the output of `get_config`.

    Returns:
      An Initializer instance.
    r   Nr   )pop)clsconfigs     r   from_configzInitializer.from_configL   s    & JJw==r   c                     |D ]X  }|t         t        fvr$t        dt        t         t        g       d|       |r8t	        | j
                  j                   d       y )Nz"Keyword argument should be one of z. Received: z8 initializer doesn't support partition-related arguments)_PARTITION_SHAPE_PARTITION_OFFSET	TypeErrorlist
ValueError	__class____name__)r   r   support_partitionkwargs       r   _validate_kwargszInitializer._validate_kwargsb   s|     +	'):;	;0%'89:;<wPQ 	Q !~~&&' (* *+ 	++r   N)T)	r+   
__module____qualname____doc__r   r   classmethodr#   r.   r   r   r   r   r   #   s*    
(  *	+r   r   zeros_initializer)v1c                   .    e Zd ZdZej
                  fdZy)Zerosai  Initializer that generates tensors initialized to 0.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.zeros_initializer())
  >>> v1
  <tf.Variable ... shape=(3,) ... numpy=array([0., 0., 0.], dtype=float32)>
  >>> v2
  <tf.Variable ... shape=(3, 3) ... numpy=
  array([[0., 0., 0.],
         [0., 0., 0.],
         [0., 0., 0.]], dtype=float32)>
  >>> make_variables(4, tf.random_uniform_initializer(minval=-1., maxval=1.))
  (<tf.Variable...shape=(4,) dtype=float32...>, <tf.Variable...shape=(4, 4) ...
  c                     | j                  |       t        j                  |      }|j                  r|t        j                  k(  rt        d| d      t        |v r	|t           }t        j                  ||      S )aL  Returns a tensor object initialized as specified by the initializer.

    Args:
      shape: Shape of the tensor.
      dtype: Optional dtype of the tensor. Only numeric or boolean dtypes are
       supported.
      **kwargs: Additional keyword arguments.

    Raises:
      ValuesError: If the dtype is not numeric or boolean.
    =Argument `dtype` expected to be numeric or boolean. Received .)	r.   r   as_dtypeis_numpy_compatiblestringr)   r%   r   zerosr   s       r   r   zZeros.__call__   sv     	&!OOE"E$$(> ##(', - -6!%&e??5%((r   Nr+   r0   r1   r2   r   float32r   r   r   r   r7   r7   n   s    . #).. )r   r7   ones_initializerc                   .    e Zd ZdZej
                  fdZy)Onesah  Initializer that generates tensors initialized to 1.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.ones_initializer())
  >>> v1
  <tf.Variable ... shape=(3,) ... numpy=array([1., 1., 1.], dtype=float32)>
  >>> v2
  <tf.Variable ... shape=(3, 3) ... numpy=
  array([[1., 1., 1.],
         [1., 1., 1.],
         [1., 1., 1.]], dtype=float32)>
  >>> make_variables(4, tf.random_uniform_initializer(minval=-1., maxval=1.))
  (<tf.Variable...shape=(4,) dtype=float32...>, <tf.Variable...shape=(4, 4) ...
  c                     | j                  |       t        j                  |      }|j                  r|t        j                  k(  rt        d| d      t        |v r	|t           }t        j                  ||      S )aM  Returns a tensor object initialized as specified by the initializer.

    Args:
      shape: Shape of the tensor.
      dtype: Optional dtype of the tensor. Only numeric or boolean dtypes are
        supported.
      **kwargs: Additional keyword arguments.

    Raises:
      ValuesError: If the dtype is not numeric or boolean.
    r9   r:   )	r.   r   r;   r<   r=   r)   r%   r   onesr   s       r   r   zOnes.__call__   sv     	&!OOE"E$$(> ##(', - -6!%&e>>%''r   Nr?   r   r   r   rC   rC      s    . #).. (r   rC   constant_initializerc                   &    e Zd ZdZddZddZd Zy)Constanta
  Initializer that generates tensors with constant values.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  `tf.constant_initializer` returns an object which when called returns a tensor
  populated with the `value` specified in the constructor. This `value` must be
  convertible to the requested `dtype`.

  The argument `value` can be a scalar constant value, or a list of
  values. Scalars broadcast to whichever shape is requested from the
  initializer.

  If `value` is a list, then the length of the list must be equal to the number
  of elements implied by the desired shape of the tensor. If the total number of
  elements in `value` is not equal to the number of elements required by the
  tensor shape, the initializer will raise a `TypeError`.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.constant_initializer(2.))
  >>> v1
  <tf.Variable ... shape=(3,) ... numpy=array([2., 2., 2.], dtype=float32)>
  >>> v2
  <tf.Variable ... shape=(3, 3) ... numpy=
  array([[2., 2., 2.],
         [2., 2., 2.],
         [2., 2., 2.]], dtype=float32)>
  >>> make_variables(4, tf.random_uniform_initializer(minval=-1., maxval=1.))
  (<tf.Variable...shape=(4,) dtype=float32...>, <tf.Variable...shape=(4, 4) ...

  >>> value = [0, 1, 2, 3, 4, 5, 6, 7]
  >>> init = tf.constant_initializer(value)
  >>> # Fitting shape
  >>> tf.Variable(init(shape=[2, 4], dtype=tf.float32))
  <tf.Variable ...
  array([[0., 1., 2., 3.],
         [4., 5., 6., 7.]], dtype=float32)>
  >>> # Larger shape
  >>> tf.Variable(init(shape=[3, 4], dtype=tf.float32))
  Traceback (most recent call last):
  ...
  TypeError: ...value has 8 elements, shape is (3, 4) with 12 elements...
  >>> # Smaller shape
  >>> tf.Variable(init(shape=[2, 3], dtype=tf.float32))
  Traceback (most recent call last):
  ...
  TypeError: ...value has 8 elements, shape is (2, 3) with 6 elements...

  Args:
    value: A Python scalar, list or tuple of values, or a N-dimensional numpy
      array. All elements of the initialized variable will be set to the
      corresponding value in the `value` argument.
    support_partition: If true, the initizer supports passing partition
        offset and partition shape arguments to variable creators. This is
        particularly useful when initializing sharded variables where each
        variable shard is initialized to a slice of constant initializer.
      
  Raises:
    TypeError: If the input `value` is not one of the expected types.
  c                     t        j                  |      sGt        |t        t        t         j
                  f      s"t        dt        |      j                   d      || _	        || _
        y )Nz Invalid type for initial value: zD. Expected Python scalar, list or tuple of values, or numpy.ndarray.)npisscalar
isinstancer(   tuplendarrayr'   typer+   valuer,   )r   rP   r,   s      r   __init__zConstant.__init__  sa    KK*UT5"**4M"N,T%[-A-A,B CF FG G DJ.Dr   Nc                     | j                  || j                         |t        j                  |      }t	        j
                  | j                  ||      S )a  Returns a tensor object initialized as specified by the initializer.

    Args:
      shape: Shape of the tensor.
      dtype: Optional dtype of the tensor. If not provided the dtype of the
        tensor created will be the type of the inital value.
      **kwargs: Additional keyword arguments.

    Raises:
      TypeError: If the initializer cannot create a tensor of the requested
       dtype.
    r,   )r   r   )r.   r,   r   r;   r   constantrP   r   s       r   r   zConstant.__call__  sJ     	&D4J4JKooe$e

%uEEr   c                     d| j                   iS )NrP   )rP   r   s    r   r   zConstant.get_config*  s    TZZ  r   )r   Fr/   )r+   r0   r1   r2   rQ   r   r   r   r   r   rH   rH      s    @D/F$!r   rH   random_uniform_initializerc                   <    e Zd ZdZddZej                  fdZd Zy)RandomUniforma  Initializer that generates tensors with a uniform distribution.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.ones_initializer())
  >>> v1
  <tf.Variable ... shape=(3,) ... numpy=array([1., 1., 1.], dtype=float32)>
  >>> v2
  <tf.Variable ... shape=(3, 3) ... numpy=
  array([[1., 1., 1.],
         [1., 1., 1.],
         [1., 1., 1.]], dtype=float32)>
  >>> make_variables(4, tf.random_uniform_initializer(minval=-1., maxval=1.))
  (<tf.Variable...shape=(4,) dtype=float32...>, <tf.Variable...shape=(4, 4) ...

  Args:
    minval: A python scalar or a scalar tensor. Lower bound of the range of
      random values to generate (inclusive).
    maxval: A python scalar or a scalar tensor. Upper bound of the range of
      random values to generate (exclusive).
    seed: A Python integer. Used to create random seeds. See
      `tf.random.set_seed` for behavior.
  Nc                 N    || _         || _        || _        t        |      | _        y r/   )minvalmaxvalseed_RandomGenerator_random_generator)r   rZ   r[   r\   s       r   rQ   zRandomUniform.__init__O  s$    DKDKDI-d3Dr   c                 "   | j                  |       t        j                  |      }|j                  s|j                  st        d| d      t        |v r	|t           }| j                  j                  || j                  | j                  |      S )aH  Returns a tensor object initialized as specified by the initializer.

    Args:
      shape: Shape of the tensor.
      dtype: Optional dtype of the tensor. Only floating point and integer
        types are supported.
      **kwargs: Additional keyword arguments.

    Raises:
      ValueError: If the dtype is not numeric.
    r9   r:   )r.   r   r;   is_floating
is_integerr)   r%   r^   random_uniformrZ   r[   r   s       r   r   zRandomUniform.__call__U  s     	&!OOE"EU%5%5 ##(', - -6!%&e!!0015eE Er   c                 J    | j                   | j                  | j                  dS )NrZ   r[   r\   rd   r   s    r   r   zRandomUniform.get_configk  s!    ++++		 r   )g皙?N	r+   r0   r1   r2   rQ   r   r@   r   r   r   r   r   rX   rX   .  s     >4 #).. E,r   rX   random_normal_initializerc                   <    e Zd ZdZddZej                  fdZd Zy)RandomNormala  Initializer that generates tensors with a normal distribution.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3,
  ...                         tf.random_normal_initializer(mean=1., stddev=2.))
  >>> v1
  <tf.Variable ... shape=(3,) ... numpy=array([...], dtype=float32)>
  >>> v2
  <tf.Variable ... shape=(3, 3) ... numpy=
  ...
  >>> make_variables(4, tf.random_uniform_initializer(minval=-1., maxval=1.))
  (<tf.Variable...shape=(4,) dtype=float32...>, <tf.Variable...shape=(4, 4) ...

  Args:
    mean: a python scalar or a scalar tensor. Mean of the random values to
      generate.
    stddev: a python scalar or a scalar tensor. Standard deviation of the random
      values to generate.
    seed: A Python integer. Used to create random seeds. See
      `tf.random.set_seed` for behavior.

  Nc                 N    || _         || _        || _        t        |      | _        y r/   meanstddevr\   r]   r^   r   rl   rm   r\   s       r   rQ   zRandomNormal.__init__  $    DIDKDI-d3Dr   c                     | j                  |       t        |      }t        |v r	|t           }| j                  j	                  || j
                  | j                  |      S B  Returns a tensor object initialized as specified by the initializer.

    Args:
      shape: Shape of the tensor.
      dtype: Optional dtype of the tensor. Only floating point types are
        supported.
      **kwargs: Additional keyword arguments.

    Raises:
      ValueError: If the dtype is not floating point
    )r.   _assert_float_dtyper%   r^   random_normalrl   rm   r   s       r   r   zRandomNormal.__call__  sY     	&!&E6!%&e!!//tyy$++057 7r   c                 J    | j                   | j                  | j                  dS Nrl   rm   r\   rw   r   s    r   r   zRandomNormal.get_config  !    		++		 r           re   Nrf   r   r   r   ri   ri   s  s    >4 #).. 7&r   ri   c                   <    e Zd ZdZddZej                  fdZd Zy)TruncatedNormalas  Initializer that generates a truncated normal distribution.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  These values are similar to values from a `tf.initializers.RandomNormal`
  except that values more than two standard deviations from the mean are
  discarded and re-drawn. This is the recommended initializer for neural network
  weights and filters.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(
  ...     3, tf.initializers.TruncatedNormal(mean=1., stddev=2.))
  >>> v1
  <tf.Variable ... shape=(3,) ... numpy=array([...], dtype=float32)>
  >>> v2
  <tf.Variable ... shape=(3, 3) ... numpy=
  ...
  >>> make_variables(4, tf.initializers.RandomUniform(minval=-1., maxval=1.))
  (<tf.Variable...shape=(4,) dtype=float32...>, <tf.Variable...shape=(4, 4) ...

  Args:
    mean: a python scalar or a scalar tensor. Mean of the random values
      to generate.
    stddev: a python scalar or a scalar tensor. Standard deviation of the
      random values to generate.
    seed: A Python integer. Used to create random seeds. See
      `tf.random.set_seed` for behavior.
  Nc                 N    || _         || _        || _        t        |      | _        y r/   rk   rn   s       r   rQ   zTruncatedNormal.__init__  ro   r   c                     | j                  |       t        |      }t        |v r	|t           }| j                  j	                  || j
                  | j                  |      S rq   )r.   rs   r%   r^   truncated_normalrl   rm   r   s       r   r   zTruncatedNormal.__call__  s[     	&!&E6!%&e!!225$))37;;G Gr   c                 J    | j                   | j                  | j                  dS rv   rw   r   s    r   r   zTruncatedNormal.get_config  rx   r   ry   rf   r   r   r   r|   r|     s!    !F4 #).. G&r   r|   c                   D    e Zd ZdZ	 	 	 	 ddZej                  fdZd Zy)VarianceScalinga=  Initializer capable of adapting its scale to the shape of weights tensors.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  With `distribution="truncated_normal" or "untruncated_normal"`, samples are
  drawn from a truncated/untruncated normal distribution with a mean of zero and
  a standard deviation (after truncation, if used) `stddev = sqrt(scale / n)`
  where n is:

    - number of input units in the weight tensor, if mode = "fan_in"
    - number of output units, if mode = "fan_out"
    - average of the numbers of input and output units, if mode = "fan_avg"

  With `distribution="uniform"`, samples are drawn from a uniform distribution
  within [-limit, limit], with `limit = sqrt(3 * scale / n)`.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.initializers.VarianceScaling(scale=1.))
  >>> v1
  <tf.Variable ... shape=(3,) ... numpy=array([...], dtype=float32)>
  >>> v2
  <tf.Variable ... shape=(3, 3) ... numpy=
  ...
  >>> make_variables(4, tf.initializers.VarianceScaling(distribution='uniform'))
  (<tf.Variable...shape=(4,) dtype=float32...>, <tf.Variable...shape=(4, 4) ...

  Args:
    scale: Scaling factor (positive float).
    mode: One of "fan_in", "fan_out", "fan_avg".
    distribution: Random distribution to use. One of "truncated_normal",
      "untruncated_normal" and  "uniform".
    seed: A Python integer. Used to create random seeds. See
      `tf.random.set_seed` for behavior.

  Raises:
    ValueError: In case of an invalid value for the "scale", mode" or
      "distribution" arguments.
  Nc                     |dk  rt        d|       |dvrt        d|       |j                         }|dk(  rd}|dvrt        d|       || _        || _        || _        || _        t        |      | _        y )	Nrz   z5Argument `scale` must be a positive float. Received: >   fan_infan_avgfan_outzMArgument `mode` should be one of ('fan_in', 'fan_out', 'fan_avg'). Received: normalr   >   uniformr   untruncated_normalzjArgument `distribution` should be one of ('uniform', 'truncated_normal', 'untruncated_normal'). Received: )r)   lowerscalemodedistributionr\   r]   r^   )r   r   r   r   r\   s        r   rQ   zVarianceScaling.__init__(  s    
 {N" # #33 004v7 8 8%%'Lx'l 2 2 O&) * * DJDI$DDI-d3Dr   c                    | j                  |       t        |      }| j                  }t        |      \  }}t        |v r	|t           }| j
                  dk(  r|t        d|      z  }n4| j
                  dk(  r|t        d|      z  }n|t        d||z   dz        z  }| j                  dk(  r6t        j                  |      dz  }| j                  j                  |d||      S | j                  dk(  r3t        j                  |      }| j                  j                  |d||      S t        j                  d	|z        }| j                  j                  || ||      S )
rr   r         ?r          @r   g۶%?rz   r   g      @)r.   rs   r   r   r%   r   maxr   mathsqrtr^   r   rt   rb   )	r   r   r   r   r   r   r   rm   limits	            r   r   zVarianceScaling.__call__B  sE    	&!&EJJE#E*OFG6!%&eyyHs2ve	i	s2wes2(B.//e..yy"44f##44UCOO			2	2yyf##11%feLLiie$e##2255&%OOr   c                 `    | j                   | j                  | j                  | j                  dS )Nr   r   r   r\   r   r   s    r   r   zVarianceScaling.get_confige  s*    		))			 r   )r   r   r   Nrf   r   r   r   r   r     s0    +\ .	44 #).. !PFr   r   c                   <    e Zd ZdZddZej                  fdZd Zy)
Orthogonala  Initializer that generates an orthogonal matrix.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  If the shape of the tensor to initialize is two-dimensional, it is initialized
  with an orthogonal matrix obtained from the QR decomposition of a matrix of
  random numbers drawn from a normal distribution.
  If the matrix has fewer rows than columns then the output will have orthogonal
  rows. Otherwise, the output will have orthogonal columns.

  If the shape of the tensor to initialize is more than two-dimensional,
  a matrix of shape `(shape[0] * ... * shape[n - 2], shape[n - 1])`
  is initialized, where `n` is the length of the shape vector.
  The matrix is subsequently reshaped to give a tensor of the desired shape.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k, k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.initializers.Orthogonal())
  >>> v1
  <tf.Variable ... shape=(3, 3) ...
  >>> v2
  <tf.Variable ... shape=(3, 3, 3) ...
  >>> make_variables(4, tf.initializers.Orthogonal(gain=0.5))
  (<tf.Variable ... shape=(4, 4) dtype=float32...
   <tf.Variable ... shape=(4, 4, 4) dtype=float32...

  Args:
    gain: multiplicative factor to apply to the orthogonal matrix
    seed: A Python integer. Used to create random seeds. See
      `tf.random.set_seed` for behavior.

  References:
      [Saxe et al., 2014](https://openreview.net/forum?id=_wzZwKpTDF_9C)
      ([pdf](https://arxiv.org/pdf/1312.6120.pdf))
  Nc                 @    || _         || _        t        |      | _        y r/   )gainr\   r]   r^   )r   r   r\   s      r   rQ   zOrthogonal.__init__  s    DIDI-d3Dr   c                    | j                  |d       t        |      }t        |      dk  rt        d|       d}|dd D ]  }||z  }	 |d   }t	        ||      t        ||      f}| j                  j                  ||      }t        j                  |d	      \  }	}
t        j                  |
      }|	t        j                  |      z  }	||k  rt        j                  |	      }	| j                  t        j                   |	|      z  S )
aj  Returns a tensor object initialized as specified by the initializer.

    Args:
      shape: Shape of the tensor.
      dtype: Optional dtype of the tensor. Only floating point types are
        supported.
      **kwargs: Additional keyword arguments.

    Raises:
      ValueError: If the dtype is not floating point or the input shape is not
       valid.
    FrS      iThe tensor to initialize, specified by argument `shape` must be at least two-dimensional. Received shape=   Nr   )full_matrices)r.   rs   lenr)   r   minr^   rt   r   qrr   	diag_partr   signmatrix_transposer   reshape)r   r   r   r   num_rowsdimnum_cols
flat_shapeaqrds               r   r   zOrthogonal.__call__  s    	&E:&E
5zA~ L" # #
 HSbz #ohRyHh)3x+BCJ 	,,Zu,EAQe4DAqAAq	A(

$
$Q
'a99y((E222r   c                 4    | j                   | j                  dS )Nr   r\   r   r   s    r   r   zOrthogonal.get_config  s    IItyy11r   )r   Nrf   r   r   r   r   r   n  s!    'R4
 #).. %3N2r   r   c                   <    e Zd ZdZddZej                  fdZd Zy)IdentityaI  Initializer that generates the identity matrix.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Only usable for generating 2D matrices.

  Examples:

  >>> def make_variable(k, initializer):
  ...   return tf.Variable(initializer(shape=[k, k], dtype=tf.float32))
  >>> make_variable(2, tf.initializers.Identity())
  <tf.Variable ... shape=(2, 2) dtype=float32, numpy=
  array([[1., 0.],
         [0., 1.]], dtype=float32)>
  >>> make_variable(3, tf.initializers.Identity(gain=0.5))
  <tf.Variable ... shape=(3, 3) dtype=float32, numpy=
  array([[0.5, 0. , 0. ],
         [0. , 0.5, 0. ],
         [0. , 0. , 0.5]], dtype=float32)>

  Args:
    gain: Multiplicative factor to apply to the identity matrix.
  c                     || _         y r/   r   )r   r   s     r   rQ   zIdentity.__init__  s	    DIr   c                     | j                  |d       t        |      }t        |      dk7  rt        d|       t	        j
                  |d|i}| j                  |z  S )a  Returns a tensor object initialized as specified by the initializer.

    Args:
      shape: Shape of the tensor.
      dtype: Optional dtype of the tensor. Only floating point types are
       supported.
      **kwargs: Additional keyword arguments.

    Raises:
      ValueError: If the dtype is not floating point
      ValueError: If the requested shape does not have exactly two axes.
    FrS   r   r   r   )r.   rs   r   r)   r   eyer   )r   r   r   r   initializers        r   r   zIdentity.__call__  so     	&E:&E
5zQ L" # # "%%u:E:K99{""r   c                     d| j                   iS )Nr   r   r   s    r   r   zIdentity.get_config      DIIr   N)r   rf   r   r   r   r   r     s    4 #).. #,r   r   c                   *     e Zd ZdZd fd	Zd Z xZS )GlorotUniforma  The Glorot uniform initializer, also called Xavier uniform initializer.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Draws samples from a uniform distribution within [-limit, limit] where `limit`
  is `sqrt(6 / (fan_in + fan_out))` where `fan_in` is the number of input units
  in the weight tensor and `fan_out` is the number of output units in the weight
  tensor.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k, k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.initializers.GlorotUniform())
  >>> v1
  <tf.Variable ... shape=(3, 3) ...
  >>> v2
  <tf.Variable ... shape=(3, 3, 3) ...
  >>> make_variables(4, tf.initializers.RandomNormal())
  (<tf.Variable ... shape=(4, 4) dtype=float32...
   <tf.Variable ... shape=(4, 4, 4) dtype=float32...

  Args:
    seed: A Python integer. Used to create random seeds. See
      `tf.random.set_seed` for behavior.

  References:
      [Glorot et al., 2010](http://proceedings.mlr.press/v9/glorot10a.html)
      ([pdf](http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf))
  c                 4    t         t        |   ddd|       y )Nr   r   r   r   )superr   rQ   r   r\   r*   s     r   rQ   zGlorotUniform.__init__#  s#    	-'	 ( r   c                     d| j                   iS Nr\   r\   r   s    r   r   zGlorotUniform.get_config*  r   r   r/   r+   r0   r1   r2   rQ   r   __classcell__r*   s   @r   r   r           Dr   r   c                   *     e Zd ZdZd fd	Zd Z xZS )GlorotNormala  The Glorot normal initializer, also called Xavier normal initializer.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Draws samples from a truncated normal distribution centered on 0 with `stddev
  = sqrt(2 / (fan_in + fan_out))` where `fan_in` is the number of input units in
  the weight tensor and `fan_out` is the number of output units in the weight
  tensor.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k, k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.initializers.GlorotNormal())
  >>> v1
  <tf.Variable ... shape=(3, 3) ...
  >>> v2
  <tf.Variable ... shape=(3, 3, 3) ...
  >>> make_variables(4, tf.initializers.RandomNormal())
  (<tf.Variable ... shape=(4, 4) dtype=float32...
   <tf.Variable ... shape=(4, 4, 4) dtype=float32...

  Args:
    seed: A Python integer. Used to create random seeds. See
      `tf.random.set_seed` for behavior.

  References:
      [Glorot et al., 2010](http://proceedings.mlr.press/v9/glorot10a.html)
      ([pdf](http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf))
  c                 4    t         t        |   ddd|       y )Nr   r   r   r   )r   r   rQ   r   s     r   rQ   zGlorotNormal.__init__Q  s#    	,&'	 ' r   c                     d| j                   iS r   r   r   s    r   r   zGlorotNormal.get_configX  r   r   r/   r   r   s   @r   r   r   .  r   r   r   c                      t        ddd|       S )a  LeCun normal initializer.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Draws samples from a truncated normal distribution centered on 0 with `stddev
  = sqrt(1 / fan_in)` where `fan_in` is the number of input units in the weight
  tensor.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k, k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.initializers.lecun_normal())
  >>> v1
  <tf.Variable ... shape=(3, 3) ...
  >>> v2
  <tf.Variable ... shape=(3, 3, 3) ...
  >>> make_variables(4, tf.initializers.RandomNormal())
  (<tf.Variable ... shape=(4, 4) dtype=float32...
   <tf.Variable ... shape=(4, 4, 4) dtype=float32...

  Args:
    seed: A Python integer. Used to seed the random generator.

  Returns:
    A callable Initializer with `shape` and `dtype` arguments which generates a
    tensor.

  References:
      - Self-Normalizing Neural Networks,
      [Klambauer et al., 2017]
      (https://papers.nips.cc/paper/6698-self-normalizing-neural-networks)
      ([pdf]
      (https://papers.nips.cc/paper/6698-self-normalizing-neural-networks.pdf))
      - Efficient Backprop,
      [Lecun et al., 1998](http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf)
  r   r   r   r   r   r   s    r   lecun_normalr   m  s    R 
X,>T
K Kr   c                      t        ddd|       S )a  LeCun uniform initializer.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Draws samples from a uniform distribution within [-limit, limit] where `limit`
  is `sqrt(3 / fan_in)` where `fan_in` is the number of input units in the
  weight tensor.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k, k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.initializers.lecun_uniform())
  >>> v1
  <tf.Variable ... shape=(3, 3) ...
  >>> v2
  <tf.Variable ... shape=(3, 3, 3) ...
  >>> make_variables(4, tf.initializers.RandomNormal())
  (<tf.Variable ... shape=(4, 4) dtype=float32...
   <tf.Variable ... shape=(4, 4, 4) dtype=float32...

  Args:
    seed: A Python integer. Used to seed the random generator.

  Returns:
    A callable Initializer with `shape` and `dtype` arguments which generates a
    tensor.

  References:
      - Self-Normalizing Neural Networks,
      [Klambauer et al., 2017](https://papers.nips.cc/paper/6698-self-normalizing-neural-networks) # pylint: disable=line-too-long
      ([pdf](https://papers.nips.cc/paper/6698-self-normalizing-neural-networks.pdf))
      - Efficient Backprop,
      [Lecun et al., 1998](http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf)
  r   r   r   r   r   r   s    r   lecun_uniformr     s    N 
XID
B Br   c                      t        ddd|       S )a_  He normal initializer.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  It draws samples from a truncated normal distribution centered on 0 with
  `stddev = sqrt(2 / fan_in)` where `fan_in` is the number of input units in the
  weight tensor.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k, k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.initializers.he_normal())
  >>> v1
  <tf.Variable ... shape=(3, 3) ...
  >>> v2
  <tf.Variable ... shape=(3, 3, 3) ...
  >>> make_variables(4, tf.initializers.RandomNormal())
  (<tf.Variable ... shape=(4, 4) dtype=float32...
   <tf.Variable ... shape=(4, 4, 4) dtype=float32...

  Args:
    seed: A Python integer. Used to seed the random generator.

  Returns:
    A callable Initializer with `shape` and `dtype` arguments which generates a
    tensor.

  References:
      [He et al., 2015](https://www.cv-foundation.org/openaccess/content_iccv_2015/html/He_Delving_Deep_into_ICCV_2015_paper.html) # pylint: disable=line-too-long
      ([pdf](https://www.cv-foundation.org/openaccess/content_iccv_2015/papers/He_Delving_Deep_into_ICCV_2015_paper.pdf))
  r   r   r   r   r   r   s    r   	he_normalr     s    H 
X,>T
K Kr   c                      t        ddd|       S )ar  He uniform variance scaling initializer.

  Initializers allow you to pre-specify an initialization strategy, encoded in
  the Initializer object, without knowing the shape and dtype of the variable
  being initialized.

  Draws samples from a uniform distribution within [-limit, limit] where `limit`
  is `sqrt(6 / fan_in)` where `fan_in` is the number of input units in the
  weight tensor.

  Examples:

  >>> def make_variables(k, initializer):
  ...   return (tf.Variable(initializer(shape=[k, k], dtype=tf.float32)),
  ...           tf.Variable(initializer(shape=[k, k, k], dtype=tf.float32)))
  >>> v1, v2 = make_variables(3, tf.initializers.he_uniform())
  >>> v1
  <tf.Variable ... shape=(3, 3) ...
  >>> v2
  <tf.Variable ... shape=(3, 3, 3) ...
  >>> make_variables(4, tf.initializers.RandomNormal())
  (<tf.Variable ... shape=(4, 4) dtype=float32...
   <tf.Variable ... shape=(4, 4, 4) dtype=float32...

  Args:
    seed: A Python integer. Used to seed the random generator.

  Returns:
    A callable Initializer with `shape` and `dtype` arguments which generates a
    tensor.

  References:
      [He et al., 2015](https://www.cv-foundation.org/openaccess/content_iccv_2015/html/He_Delving_Deep_into_ICCV_2015_paper.html) # pylint: disable=line-too-long
      ([pdf](https://www.cv-foundation.org/openaccess/content_iccv_2015/papers/He_Delving_Deep_into_ICCV_2015_paper.pdf))
  r   r   r   r   r   r   s    r   
he_uniformr     s    H 
XID
B Br   c                 f    t        j                  |       } | j                  st        d|  d      | S )zValidate and return floating point type based on `dtype`.

  `dtype` must be a floating point type.

  Args:
    dtype: The data type to validate.

  Returns:
    Validated type.

  Raises:
    ValueError: if `dtype` is not a floating point type.
  z=Argument `dtype` is expected to be floating point. Received: r:   )r   r;   r`   r)   r   s    r   rs   rs     s>     //%
 %			
 ""'+ , ,	,r   c                   R     e Zd ZdZd fd	Zddej                  fdZd Zd Z	 xZ
S )	r]   z5Random generator that selects appropriate random ops.c                 P    t         t        |           |
|dg| _        y d | _        y )Nr   )r   r]   rQ   r\   r   s     r   rQ   z_RandomGenerator.__init__0  s)    	
D*,)didir   rz   r   c                     | j                   rt        j                  }nt        j                  } |||||| j                         S )z0A deterministic random normal if seed is passed.r   rl   rm   r   r\   )r\   r
   stateless_random_normalr	   rt   r   r   rl   rm   r   ops         r   rt   z_RandomGenerator.random_normal8  s=    yy77b##b$vUL Lr   c                     | j                   rt        j                  }nt        j                  } |||||| j                         S )z1A deterministic random uniform if seed is passed.)r   rZ   r[   r   r\   )r\   r
   stateless_random_uniformr	   rb   )r   r   rZ   r[   r   r   s         r   rb   z_RandomGenerator.random_uniformA  s=    yy88b$$bF6TYYP Pr   c                     | j                   rt        j                  }nt        j                  } |||||| j                         S )z3A deterministic truncated normal if seed is passed.r   )r\   r
   stateless_truncated_normalr	   r   r   s         r   r   z!_RandomGenerator.truncated_normalJ  s=    yy::b&&b$vUL Lr   r/   )r+   r0   r1   r2   rQ   r   r@   rt   rb   r   r   r   s   @r   r]   r]   -  s*    = '*!6>> LPLr   r]   r/   )?r2   r   numpyrJ   tensorflow.python.frameworkr   r   tensorflow.python.opsr   r   r   r   r	   r
   tensorflow.python.ops.init_opsr    tensorflow.python.util.tf_exportr   r%   r&   r   r7   rC   rH   rX   ri   r|   r   r   r   r   r   r4   rA   rF   rV   rg   truncated_normal_initializervariance_scaling_initializerglorot_uniform_initializerglorot_normal_initializerorthogonal_initializeridentity_initializerr   r   r   r   rs   r]   zeror>   onerE   rT   r   rb   r   rt   r   identity
orthogonalglorot_normalglorot_uniformr   r   r   <module>r      s      3 . + 0 1 * , 6 8 6$ & H+ H+V 2&+)K +) '+)\ "%+(; +( &+(\ !b)^!{ ^! *^!B 'B/AK A 0AH &2.>; > />BBk BJqk qhW2 W2t5{ 5p+O +\+? +b    * ( . . * ( #  *KZ(BV%KP%BV*$L $LR  u d( (.% %" 
r   