import tensorflow as tf

        saver = tf.train.Saver()

    #-----------------Initialize the cost and gradients---------------------------------------------------------

    costs = [] #store the cost for different opochs
    cost = obj([an,hn], betan, Y, activation)

    #-----------------Initialize the optimizer-----------------------------------------------------------------
    # Implement an exponential learning rate decay every 1000 epochs

    #Implement a dynamical learning rate
    global_step = tf.Variable(0., trainable=False)
    rate = tf.train.exponential_decay(starter_learning, global_step, 500, 0.9) #exponential learning rate decay
    #rate = starter_learning

    tvars = tf.trainable_variables() #list of trainable variables
    Npar= flatten(tvars).get_shape()[1] #total number of paramters in the network

    print('there are:', Npar,'parameters in the network')

    optimizer  = tf.train.AdamOptimizer(learning_rate = rate)   #Initialize Adam optimizer

    grads_var = optimizer.compute_gradients(cost, tvars ) #Get gradients layer by layer. Note that this function returns the pair (grads, var)
    grads = [grads_var[i][0] for i in range(len(grads_var))] #extract the gradients

    min   = optimizer.apply_gradients(grads_and_vars= grads_var, global_step= global_step)    #Apply the gradients to look for critical points

    gradients_and_par = [] #store gradients and training paramters for different epochs
    hessians = [] #store the hessian for different epochs
    residuals= [] #store the value of the residuals for different epochs
