class_docstr: M = b1 * M + (1-b1) * G
  V = b2 * V + (1-b2) * G^2
  M_hat = M / (1 - beta1**t)
  V_hat = V / (1 - beta2**t)
  W = W - r * M_hat / sqrt(V_hat)
  
  https://paperswithcode.com/method/adam
code: def compile(self, weights):
      for W in weights:
          self.Vs[id(W)] = [
              tfe.define_private_variable(
                  np.zeros(list(map(int, W[i].shape.as_list()))),
                  apply_scaling=True,
                  share_type=W[i].share_type,
                  factory=W[i].backing_dtype,
              )
              for i in range(len(W))
          ]
          self.Ms[id(W)] = [
              tfe.define_private_variable(
                  np.zeros(list(map(int, W[i].shape.as_list()))),
                  apply_scaling=True,
                  share_type=W[i].share_type,
                  factory=W[i].backing_dtype,
              )
              for i in range(len(W))
          ]
          factory = W[0].backing_dtype if len(W) > 0 else None
          self.beta1_pow[id(W)] = tfe.define_public_variable(
              np.array(1), apply_scaling=True, factory=factory
          )
          self.beta2_pow[id(W)] = tfe.define_public_variable(
              np.array(1), apply_scaling=True, factory=factory
          )
  
file_path: tf-encrypted/tf_encrypted/keras/optimizers.py
imports: import numpy
  import tensorflow
  import tf_encrypted
label_desc: Use image node_id 2 for calling the Adam obj's underlying member method code with example usage: obj.compile(weights) without return types