a
    Sicq                     @   sv   d Z ddlm  mZ ddlmZ ddlmZ ddl	m
Z
 e e
dg dG dd	 d	ejZej d
eje_ dS )zSGD optimizer implementation.    N)	optimizer)generic_utils)keras_exportz!keras.optimizers.experimental.SGD)v1c                       sB   e Zd ZdZd fdd		Z fd
dZdd Z fddZ  ZS )SGDa5  Gradient descent (with momentum) optimizer.

    Update rule for parameter `w` with gradient `g` when `momentum` is 0:

    ```python
    w = w - learning_rate * g
    ```

    Update rule when `momentum` is larger than 0:

    ```python
    velocity = momentum * velocity - learning_rate * g
    w = w + velocity
    ```

    When `nesterov=True`, this rule becomes:

    ```python
    velocity = momentum * velocity - learning_rate * g
    w = w + momentum * velocity - learning_rate * g
    ```

    Args:
      learning_rate: A `Tensor`, floating point value, or a schedule that is a
        `tf.keras.optimizers.schedules.LearningRateSchedule`, or a callable
        that takes no arguments and returns the actual value to use. The
        learning rate. Defaults to 0.001.
      momentum: float hyperparameter >= 0 that accelerates gradient descent in
        the relevant direction and dampens oscillations. Defaults to 0, i.e.,
        vanilla gradient descent.
      nesterov: boolean. Whether to apply Nesterov momentum.
        Defaults to `False`.
      {{base_optimizer_keyword_args}}

    Usage:

    >>> opt = tf.keras.optimizers.SGD(learning_rate=0.1)
    >>> var = tf.Variable(1.0)
    >>> loss = lambda: (var ** 2)/2.0         # d(loss)/d(var1) = var1
    >>> step_count = opt.minimize(loss, [var]).numpy()
    >>> # Step is `- learning_rate * grad`
    >>> var.numpy()
    0.9

    >>> opt = tf.keras.optimizers.SGD(learning_rate=0.1, momentum=0.9)
    >>> var = tf.Variable(1.0)
    >>> val0 = var.value()
    >>> loss = lambda: (var ** 2)/2.0         # d(loss)/d(var1) = var1
    >>> # First step is `- learning_rate * grad`
    >>> step_count = opt.minimize(loss, [var]).numpy()
    >>> val1 = var.value()
    >>> (val0 - val1).numpy()
    0.1
    >>> # On later steps, step-size increases because of momentum
    >>> step_count = opt.minimize(loss, [var]).numpy()
    >>> val2 = var.value()
    >>> (val1 - val2).numpy()
    0.18

    Reference:
        - For `nesterov=True`, See [Sutskever et al., 2013](
          http://jmlr.org/proceedings/papers/v28/sutskever13.pdf).
    {Gz?        FNGz?Tc                    sf   t  jf ||||||	|
|d| | || _|| _|| _t|ttfrb|dk sZ|dkrbt	dd S )N)nameclipnorm	clipvalueglobal_clipnormuse_emaema_momentumema_overwrite_frequencyjit_compiler      z"`momentum` must be between [0, 1].)
super__init___build_learning_rate_learning_ratemomentumnesterov
isinstanceintfloat
ValueError)selflearning_rater   r   amsgradr   r   r   r   r   r   r   r
   kwargs	__class__ g/var/www/html/django/DPS/env/lib/python3.9/site-packages/keras/optimizers/optimizer_experimental/sgd.pyr   ]   s*    	zSGD.__init__c                    sZ   t  | t| dr | jr dS g | _| jdkrP|D ]}| j| j|dd q4d| _dS )zInitialize optimizer variables.

        SGD optimizer has one variable `momentums`, only set if `self.momentum`
        is not 0.

        Args:
          var_list: list of model variables to build SGD variables on.
        _builtNr   m)model_variablevariable_nameT)r   buildhasattrr%   	momentumsr   appendadd_variable_from_reference)r   var_listvarr!   r#   r$   r)      s    	
z	SGD.buildc                 C   s&  t | j|j}d}| |}| jdkrHt | j|j}| j| j|  }t|t j	rt 	|j
 | |j}|dur|||  || | jr|| |||  q|| n
|| n`|dur|| | ||   | jr|| | ||   n
|| n|| |  dS )z=Update step given gradient and the associated model variable.Nr   )tfcastr   dtype_var_keyr   r+   _index_dictr   IndexedSlicesvaluesindicesassignscatter_addr   
assign_add)r   gradientvariablelrr&   var_keyr   Z	add_valuer#   r#   r$   update_step   s0    




zSGD.update_stepc                    s,   t   }|| | j| j| jd |S )N)r   r   r   )r   
get_configupdate_serialize_hyperparameterr   r   r   )r   configr!   r#   r$   r@      s    
	zSGD.get_config)r   r   FFNNNFr	   NTr   )	__name__
__module____qualname____doc__r   r)   r?   r@   __classcell__r#   r#   r!   r$   r      s"   B            #$r   z{{base_optimizer_keyword_args}})rG   tensorflow.compat.v2compatv2r0   'keras.optimizers.optimizer_experimentalr   keras.utilsr    tensorflow.python.util.tf_exportr   register_keras_serializable	Optimizerr   replacebase_optimizer_keyword_argsr#   r#   r#   r$   <module>   s   
 .