
    6bik                         S r SSKJs  Jr  SSKJr  SSKJr  SSK	J
r
  \" 5       \
" SSS/ S	9 " S
 S\R                  5      5       5       r\R                   R                  S\R                  5      \l         g)zSGD optimizer implementation.    N)	optimizer)register_keras_serializable)keras_exportz!keras.optimizers.experimental.SGDzkeras.optimizers.SGDz)keras.dtensor.experimental.optimizers.SGD)v1c                   f   ^  \ rS rSrSr            SU 4S jjrU 4S jrS rU 4S jrSr	U =r
$ )	SGD   a1  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
        `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
>>> opt.minimize(loss, [var])
>>> # Step is `- learning_rate * grad`
>>> var.numpy()
0.9

>>> opt = tf.keras.optimizers.SGD(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`
>>> opt.minimize(loss, [var])
>>> val1 = var.value()
>>> (val0 - val1).numpy()
0.1
>>> # On later steps, step-size increases because of momentum
>>> opt.minimize(loss, [var])
>>> val2 = var.value()
>>> (val1 - val2).numpy()
0.18

Reference:
    - For `nesterov=True`, See [Sutskever et al., 2013](
      http://proceedings.mlr.press/v28/sutskever13.pdf).
c                    > [         TU ]  " SUUUUUUU	U
US.	UD6  U R                  U5      U l        X l        X0l        [        U[        [        45      (       a  US:  d  US:  a  [        S5      eg g )N)	nameweight_decay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   r   r   r   r   r   r   r   r   r   kwargs	__class__s                 U/home/james-whalen/.local/lib/python3.13/site-packages/tf_keras/src/optimizers/sgd.pyr   SGD.__init__b   s      	 	
%+%$;#	
 	
 #77F  he--qLHqLABB ) .    c                    > [         TU ]  U5        [        U S5      (       a  U R                  (       a  g/ U l        U H,  nU R                  R                  U R                  USS95        M.     SU l        g)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.
_builtNm)model_variablevariable_nameT)r   buildhasattrr(   	momentumsappendadd_variable_from_reference)r    var_listvarr#   s      r$   r,   	SGD.build   sk     	h4""t{{CNN!!00#&c 1   r&   c                    [         R                  " U R                  UR                  5      nSnU R	                  U5      n[         R                  " U R
                  UR                  5      nU R                  U R                  U      n[        U[         R                  5      (       a  [         R                  " UR                  * U-  UR                  5      nUbl  UR                  XF-  5        UR                  U5        U R                  (       a%  UR                  U5        UR                  XF-  5        gUR                  U5        gUR                  U5        gUbX  UR                  U* U-  XF-  -   5        U R                  (       a  UR                  U* U-  XF-  -   5        gUR                  U5        gUR                  U* U-  5        g)z=Update step given gradient and the associated model variable.N)tfcastr!   dtype_var_keyr   r.   _index_dictr   IndexedSlicesvaluesindicesassignscatter_addr   
assign_add)r    gradientvariablelrr)   var_keyr   	add_values           r$   update_stepSGD.update_step   sb   WWT''8--)774==(..9NN4++G45 h 0 011(( 2%x'7'7I }&i(==((3''5''*$$Y/ }(R!,67==''	B(EF''*##XIN3r&   c                    > [         TU ]  5       nUR                  U R                  U R                  5      U R
                  U R                  S.5        U$ )N)r!   r   r   )r   
get_configupdate_serialize_hyperparameterr   r   r   )r    configr#   s     r$   rH   SGD.get_config   sO    #%!%!?!?''" !MM MM	
 r&   )r(   r   r   r.   r   )g{Gz?g        FNNNNFgGz?NTr   )__name__
__module____qualname____firstlineno____doc__r   r,   rE   rH   __static_attributes____classcell__)r#   s   @r$   r   r      sK    >D  $"CH*!4F r&   r   z{{base_optimizer_keyword_args}})rQ   tensorflow.compat.v2compatv2r5   tf_keras.src.optimizersr   'tf_keras.src.saving.object_registrationr    tensorflow.python.util.tf_exportr   	Optimizerr   replacebase_optimizer_keyword_argsr   r&   r$   <module>r]      s    $ ! ! - O : '/		i)

 i iX kk!!%y'L'Lr&   