Esempio n. 1
0
def run_2DTFIM(numsteps = 2*10**4, systemsize_x = 5, systemsize_y = 5, Bx = +2, num_units = 50, num_samples = 500, learningrate = 5e-3, seed = 111):

    #Seeding
    tf.reset_default_graph()
    random.seed(seed)  # `python` built-in pseudo-random generator
    np.random.seed(seed)  # numpy pseudo-random generator
    tf.set_random_seed(seed)  # tensorflow pseudo-random generator

    # Intitializing the RNN-----------
    units=[num_units] #list containing the number of hidden units for each layer of the networks (We only support one layer for the moment)

    Nx=systemsize_x #x dim
    Ny=systemsize_y #y dim

    input_dim=2 #Dimension of the Hilbert space for each site (here = 2, up or down)
    numsamples_=20 #only for initialization; later I'll use a much larger value (see below)
    wf=RNNwavefunction(Nx,Ny,units=units,cell=MDRNNcell,seed = seed) #contains the graph with the RNNs

    sampling=wf.sample(numsamples_,input_dim) #call this function once to create the dense layers

    #now initialize everything --------------------
    with wf.graph.as_default():
        samples_placeholder=tf.placeholder(dtype=tf.int32,shape=[numsamples_,Nx,Ny]) #the samples_placeholder are the samples of all of the spins
        global_step = tf.Variable(0, trainable=False)
        learningrate_placeholder=tf.placeholder(dtype=tf.float64,shape=[])
        learning_rate_withexpdecay = tf.train.exponential_decay(learningrate_placeholder, global_step = global_step, decay_steps = 100, decay_rate = 1.0, staircase=True) #For exponential decay of the learning rate (only works if decay_rate < 1.0)
        probs=wf.log_probability(samples_placeholder,input_dim) #The probs are obtained by feeding the sample of spins.
        optimizer=tf.train.AdamOptimizer(learning_rate=learning_rate_withexpdecay) #Using AdamOptimizer
        init=tf.global_variables_initializer()
    # End Intitializing

    #Starting Session------------
    #Activating GPU
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True

    sess=tf.Session(graph=wf.graph, config=config)
    sess.run(init)
    #---------------------------

    with wf.graph.as_default():
        variables_names =[v.name for v in tf.trainable_variables()]
    #     print(variables_names)
        sum = 0
        values = sess.run(variables_names)
        for k,v in zip(variables_names, values):
            v1 = tf.reshape(v,[-1])
            print(k,v1.shape)
            sum +=v1.shape[0]
        print('The sum of params is {0}'.format(sum))


    meanEnergy=[]
    varEnergy=[]

    #Running the training -------------------
    numsamples = 500
    numsteps = 150000
    path=os.getcwd()

    print('Training with numsamples = ', numsamples)
    print('\n')

    Jz = +np.ones((Nx,Ny))

    lr=np.float64(learningrate)
    ending='units'
    for u in units:
        ending+='_{0}'.format(u)
    filename='../Check_Points/2DTFIM/RNNwavefunction_2DVanillaRNN_'+str(Nx)+'x'+ str(Ny) +'_Bx'+str(Bx)+'_lradap'+str(lr)+'_samp'+str(numsamples)+ending+'.ckpt'
    savename = '_2DTFIM'

    with tf.variable_scope(wf.scope,reuse=tf.AUTO_REUSE):
        with wf.graph.as_default():
            Eloc=tf.placeholder(dtype=tf.float64,shape=[numsamples])
            samp=tf.placeholder(dtype=tf.int32,shape=[numsamples,Nx,Ny])
            log_probs_=wf.log_probability(samp,inputdim=2)

            cost = tf.reduce_mean(tf.multiply(log_probs_,tf.stop_gradient(Eloc))) - tf.reduce_mean(tf.stop_gradient(Eloc))*tf.reduce_mean(log_probs_)

            gradients, variables = zip(*optimizer.compute_gradients(cost))

            optstep=optimizer.apply_gradients(zip(gradients,variables),global_step=global_step)
            sess.run(tf.variables_initializer(optimizer.variables()),feed_dict={learning_rate_withexpdecay: lr})

            saver=tf.train.Saver() #define tf saver

    ##Loading previous trainings - Uncomment if you want to load the model----------
    # print("Loading the model")
    # with tf.variable_scope(wf.scope,reuse=tf.AUTO_REUSE):
    #     with wf.graph.as_default():
    #         saver.restore(sess,path+'/'+filename)
    #         meanEnergy=np.load('../Check_Points/2DTFIM/meanEnergy_2DVanillaRNN_'+str(Nx)+'x'+ str(Ny) +'_Bx'+str(Bx)+'_lradap'+str(lr)+'_samp'+str(numsamples)+ending  + savename +'.npy').tolist()
    #         varEnergy=np.load('../Check_Points/2DTFIM/varEnergy_2DVanillaRNN_'+str(Nx)+'x'+ str(Ny) +'_Bx'+str(Bx)+'_lradap'+str(lr)+'_samp'+str(numsamples)+ending  + savename +'.npy').tolist()
    #-----------


    with tf.variable_scope(wf.scope,reuse=tf.AUTO_REUSE):
        with wf.graph.as_default():

            samples_ = wf.sample(numsamples=numsamples,inputdim=2)
            samples = np.ones((numsamples, Nx,Ny), dtype=np.int32)

            samples_placeholder=tf.placeholder(dtype=tf.int32,shape=(None,Nx,Ny))
            log_probs_tensor=wf.log_probability(samples_placeholder,inputdim=2)

            queue_samples = np.zeros((Nx*Ny+1, numsamples, Nx,Ny), dtype = np.int32) #Array to store all the diagonal and non diagonal matrix elements (We create it here for memory efficiency as we do not want to allocate it at each training step)
            log_probs = np.zeros((Nx*Ny+1)*numsamples, dtype=np.float64) #Array to store the log_probs of all the diagonal and non diagonal matrix elements (We create it here for memory efficiency as we do not want to allocate it at each training step)

            for it in range(len(meanEnergy),numsteps+1):

#                 print("sampling started")
#                 start = time.time()
                samples=sess.run(samples_)
#                 end = time.time()
#                 print("sampling ended: "+ str(end - start))

                #Estimating local_energies
                local_energies = Ising2D_local_energies(Jz, Bx, Nx, Ny, samples, queue_samples, log_probs_tensor, samples_placeholder, log_probs, sess)

                meanE = np.mean(local_energies)
                varE = np.var(local_energies)

                #adding elements to be saved
                meanEnergy.append(meanE)
                varEnergy.append(varE)

                if it%10==0:                
                   print('mean(E): {0}, var(E): {1}, #samples {2}, #Step {3} \n\n'.format(meanE,varE,numsamples, it))
              
            #Comment if you dont want to save or if saving is not working
                if it>=5000 and varE <= np.min(varEnergy): #5000 can be changed to suite your chosen number of iterations and to avoid slow down by saving the model too often during the initial phase of fast convergence
                  #Saving the performances if the model is better
                  saver.save(sess,path+'/'+filename)

            #Comment if you dont want to save or if saving is not working
                if it%10==0:
                  #Saving the performances
                  np.save('../Check_Points/2DTFIM/meanEnergy_2DVanillaRNN_'+str(Nx)+'x'+ str(Ny) +'_Bx'+str(Bx)+'_lradap'+str(lr)+'_samp'+str(numsamples)+ending  + savename +'.npy', meanEnergy)
                  np.save('../Check_Points/2DTFIM/varEnergy_2DVanillaRNN_'+str(Nx)+'x'+ str(Ny) +'_Bx'+str(Bx)+'_lradap'+str(lr)+'_samp'+str(numsamples)+ending + savename +'.npy', varEnergy)

                #lr_adaptation
                lr_ = lr*(1+it/5000)**(-1)
                #Optimize
                sess.run(optstep,feed_dict={Eloc:local_energies,samp:samples,learningrate_placeholder: lr_})
    return meanEnergy, varEnergy
def run_1DTFIM(numsteps = 10**4, systemsize = 20, num_units = 50, Bx = 1, num_layers = 1, numsamples = 500, learningrate = 5e-3, seed = 111):

    #Seeding ---------------------------------------------
    tf.reset_default_graph()
    random.seed(seed)  # `python` built-in pseudo-random generator
    np.random.seed(seed)  # numpy pseudo-random generator
    tf.set_random_seed(seed)  # tensorflow pseudo-random generator

    #End Seeding ---------------------------------------------

    # System size
    N = systemsize
    
    Jz = +np.ones(N) #Ferromagnetic coupling

    #Learning rate
    lr=np.float64(learningrate)

    # Intitializing the RNN-----------
    units=[num_units]*num_layers #list containing the number of hidden units for each layer of the networks

    input_dim=2 #Dimension of the Hilbert space for each site (here = 2, up or down)
    numsamples_=20 #only for initialization; later I'll use a much larger value (see below)

    wf=RNNwavefunction(N,units=units,cell=tf.contrib.cudnn_rnn.CudnnCompatibleGRUCell, seed = seed) #contains the graph with the RNNs
    sampling=wf.sample(numsamples_,input_dim) #call this function once to create the dense layers

    #now initialize everything --------------------
    with wf.graph.as_default():
        samples_placeholder=tf.placeholder(dtype=tf.int32,shape=[numsamples_,N]) #the samples_placeholder are the samples of all of the spins
        global_step = tf.Variable(0, trainable=False)
        learningrate_placeholder=tf.placeholder(dtype=tf.float64,shape=[])
        learning_rate_withexpdecay = tf.train.exponential_decay(learningrate_placeholder, global_step = global_step, decay_steps = 100, decay_rate = 1.0, staircase=True) #For exponential decay of the learning rate (only works if decay_rate < 1.0)
        probs=wf.log_probability(samples_placeholder,input_dim) #The probs are obtained by feeding the sample of spins.
        optimizer=tf.train.AdamOptimizer(learning_rate=learning_rate_withexpdecay) #Using AdamOptimizer
        init=tf.global_variables_initializer()
    # End Intitializing ----------------------------

    #Starting Session------------
    #Activating GPU
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True

    sess=tf.Session(graph=wf.graph, config=config)
    sess.run(init)
    #---------------------------

    #Counting the number of parameters
    with wf.graph.as_default():
        variables_names =[v.name for v in tf.trainable_variables()]
    #     print(variables_names)
        sum = 0
        values = sess.run(variables_names)
        for k,v in zip(variables_names, values):
            v1 = tf.reshape(v,[-1])
            print(k,v1.shape)
            sum +=v1.shape[0]
        print('The number of params is {0}'.format(sum))

    #Building the graph -------------------

    path=os.getcwd()

    ending='_units'
    for u in units:
        ending+='_{0}'.format(u)

    filename='/../Check_Points/1DTFIM/RNNwavefunction_N'+str(N)+'_samp'+str(numsamples)+'_Jz1Bx'+str(Bx)+'_GRURNN_OBC'+ending + '.ckpt'
    savename = '_TFIM'

    with tf.variable_scope(wf.scope,reuse=tf.AUTO_REUSE):
        with wf.graph.as_default():
            Eloc=tf.placeholder(dtype=tf.float64,shape=[numsamples])
            samp=tf.placeholder(dtype=tf.int32,shape=[numsamples,N])
            log_probs_=wf.log_probability(samp,inputdim=2)

            #now calculate the fake cost function to enjoy the properties of automatic differentiation
            # Eloc is not differentiated since it is defined as a placeholder, so there is no need to use tf.stop_gradient
            cost = tf.reduce_mean(tf.multiply(log_probs_,Eloc)) - tf.reduce_mean(Eloc)*tf.reduce_mean(log_probs_)

            #Calculate Gradients---------------

            gradients, variables = zip(*optimizer.compute_gradients(cost))

            #End calculate Gradients---------------

            optstep=optimizer.apply_gradients(zip(gradients,variables), global_step = global_step)
            sess.run(tf.variables_initializer(optimizer.variables()))
            saver=tf.train.Saver()
    #----------------------------------------------------------------

    meanEnergy=[]
    varEnergy=[]

    #Loading previous trainings (uncomment if you wanna restore a previous session)----------
    # path=os.getcwd()
    # ending='_units'
    # for u in units:
    #     ending+='_{0}'.format(u)
    # savename = '_TFIM'
    # with tf.variable_scope(wf.scope,reuse=tf.AUTO_REUSE):
    #     with wf.graph.as_default():
    #         saver.restore(sess,path+filename)
    #         meanEnergy=np.load('../Check_Points/1DTFIM/meanEnergy_N'+str(N)+'_samp'+str(numsamples)+'_Jz'+str(Jz[0])+'_Bx'+str(Bx)+'_GRURNN_OBC'+ savename + ending + '.npy').tolist()
    #         varEnergy=np.load('../Check_Points/1DTFIM/varEnergy_N'+str(N)+'_samp'+str(numsamples)+'_Jz'+str(Jz[0])+'_Bx'+str(Bx)+'_GRURNN_OBC'+ savename + ending + '.npy').tolist()
    #------------------------------------

    with tf.variable_scope(wf.scope,reuse=tf.AUTO_REUSE):
        with wf.graph.as_default():


          samples_ = wf.sample(numsamples=numsamples,inputdim=2)
          samples = np.ones((numsamples, N), dtype=np.int32)

          samples_placeholder=tf.placeholder(dtype=tf.int32,shape=(None,N))
          log_probs_tensor=wf.log_probability(samples_placeholder,inputdim=2)

          queue_samples = np.zeros((N+1, numsamples, N), dtype = np.int32) #Array to store all the diagonal and non diagonal matrix elements (We create it here for memory efficiency as we do not want to allocate it at each training step)
          log_probs = np.zeros((N+1)*numsamples, dtype=np.float64) #Array to store the log_probs of all the diagonal and non diagonal matrix elements (We create it here for memory efficiency as we do not want to allocate it at each training step)


          for it in range(len(meanEnergy),numsteps+1):

              samples=sess.run(samples_)
                
              #Estimating local_energies
              local_energies = Ising_local_energies(Jz, Bx, samples, queue_samples, log_probs_tensor, samples_placeholder, log_probs, sess)

              meanE = np.mean(local_energies)
              varE = np.var(local_energies)

              #adding elements to be saved
              meanEnergy.append(meanE)
              varEnergy.append(varE)

              if it%10==0:
                  print('mean(E): {0}, var(E): {1}, #samples {2}, #Step {3} \n\n'.format(meanE,varE,numsamples, it))

             #Comment if you don't want to save
              if it%500==0: 
                  #Saving the model
                  saver.save(sess,path+'/'+filename)

              sess.run(optstep,feed_dict={Eloc:local_energies,samp:samples,learningrate_placeholder: lr})

             #Comment if you don't want to save
              if it%10==0:
                  #Saving the performances
                  np.save('../Check_Points/1DTFIM/meanEnergy_N'+str(N)+'_samp'+str(numsamples)+'_Jz'+str(Jz[0])+'_Bx'+str(Bx)+'_GRURNN_OBC'+ savename + ending + '.npy',meanEnergy)
                  np.save('../Check_Points/1DTFIM/varEnergy_N'+str(N)+'_samp'+str(numsamples)+'_Jz'+str(Jz[0])+'_Bx'+str(Bx)+'_GRURNN_OBC'+ savename + ending + '.npy',varEnergy)
    
    return meanEnergy, varEnergy
def run_2DTFIM(numsteps=2 * 10**4,
               systemsize_x=5,
               systemsize_y=5,
               Bx=+2,
               num_units=50,
               num_layers=1,
               numsamples=500,
               learningrate=1e-3,
               seed=333):

    #Seeding
    tf.reset_default_graph()
    random.seed(seed)  # `python` built-in pseudo-random generator
    np.random.seed(seed)  # numpy pseudo-random generator
    tf.set_random_seed(seed)  # tensorflow pseudo-random generator

    # Intitializing the RNN-----------
    units = [
        num_units
    ] * num_layers  #list containing the number of hidden units for each layer of the networks

    Nx = systemsize_x  #x dim
    Ny = systemsize_y  #y dim

    input_dim = 2  #Dimension of the Hilbert space for each site (here = 2, up or down)
    numsamples_ = 20  #only for initialization; later I'll use a much larger value (see below)

    wf = RNNwavefunction(Nx,
                         Ny,
                         units=units,
                         cell=tf.contrib.cudnn_rnn.CudnnCompatibleGRUCell
                         )  #contains the graph with the RNNs
    sampling = wf.sample(
        numsamples_,
        input_dim)  #call this function once to create the dense layers

    #now initialize everything --------------------
    with wf.graph.as_default():
        #We map a 2D configuration into a 1D configuration
        samples_placeholder = tf.placeholder(
            dtype=tf.int32, shape=[
                numsamples_, Nx * Ny
            ])  #the samples_placeholder are the samples of all of the spins
        global_step = tf.Variable(0, trainable=False)
        learningrate_placeholder = tf.placeholder(dtype=tf.float64, shape=[])
        learning_rate_withexpdecay = tf.train.exponential_decay(
            learningrate_placeholder,
            global_step=global_step,
            decay_steps=100,
            decay_rate=1.0,
            staircase=True
        )  #For exponential decay of the learning rate (only works if decay_rate < 1.0)
        probs = wf.log_probability(
            samples_placeholder,
            input_dim)  #The probs are obtained by feeding the sample of spins.
        optimizer = tf.train.AdamOptimizer(
            learning_rate=learning_rate_withexpdecay)  #Using AdamOptimizer
        init = tf.global_variables_initializer()
    # End Intitializing ----------------------------

    #Starting Session------------
    #Activating GPU
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True

    sess = tf.Session(graph=wf.graph, config=config)
    sess.run(init)
    #---------------------------

    #Building the graph -------------------

    path = os.getcwd()

    print('Training with numsamples = ', numsamples)
    print('\n')

    Jz = +np.ones((Nx, Ny))  #Ferromagnetic couplings

    lr = np.float64(learningrate)

    ending = 'units'
    for u in units:
        ending += '_{0}'.format(u)
    filename = '../Check_Points/2DTFIM/RNNwavefunction_GRURNN_' + str(
        Nx) + 'x' + str(Ny) + '_Bx' + str(Bx) + '_lradap' + str(
            lr) + '_samp' + str(numsamples) + ending + '.ckpt'
    savename = '_2DTFIM'

    with tf.variable_scope(wf.scope, reuse=tf.AUTO_REUSE):
        with wf.graph.as_default():
            Eloc = tf.placeholder(dtype=tf.float64, shape=[numsamples])
            samp = tf.placeholder(dtype=tf.int32, shape=[numsamples, Nx * Ny])
            log_probs_ = wf.log_probability(samp, inputdim=2)

            #now calculate the fake cost function to enjoy the properties of automatic differentiation
            cost = tf.reduce_mean(
                tf.multiply(
                    log_probs_, tf.stop_gradient(Eloc))) - tf.reduce_mean(
                        tf.stop_gradient(Eloc)) * tf.reduce_mean(log_probs_)

            #Calculate Gradients---------------
            gradients, variables = zip(*optimizer.compute_gradients(cost))
            #End calculate Gradients---------------

            optstep = optimizer.apply_gradients(zip(gradients, variables),
                                                global_step=global_step)
            sess.run(tf.variables_initializer(optimizer.variables()),
                     feed_dict={learning_rate_withexpdecay: lr})

            saver = tf.train.Saver()  #define tf saver

    #--------------------------

    meanEnergy = []
    varEnergy = []

    #Loading previous trainings (uncomment if you wanna restore a previous session)----------
    # print("Loading the model")
    # path=os.getcwd()
    # ending='units'
    # for u in units:
    #     ending+='_{0}'.format(u)
    # savename = '_2DTFIM'
    # with tf.variable_scope(wf.scope,reuse=tf.AUTO_REUSE):
    #     with wf.graph.as_default():
    #         saver.restore(sess,path+'/'+filename)
    #         meanEnergy=np.load('../Check_Points/2DTFIM/meanEnergy_GRURNN_'+str(Nx)+'x'+ str(Ny) +'_Bx'+str(Bx)+'_lradap'+str(lr)+'_samp'+str(numsamples)+ending  + savename +'.npy').tolist()
    #         varEnergy=np.load('../Check_Points/2DTFIM/varEnergy_GRURNN_'+str(Nx)+'x'+ str(Ny) +'_Bx'+str(Bx)+'_lradap'+str(lr)+'_samp'+str(numsamples)+ending  + savename +'.npy').tolist()
    #-----------

    with tf.variable_scope(wf.scope, reuse=tf.AUTO_REUSE):
        with wf.graph.as_default():

            samples_ = wf.sample(numsamples=numsamples, inputdim=2)
            samples = np.ones((numsamples, Nx * Ny), dtype=np.int32)

            samples_placeholder = tf.placeholder(dtype=tf.int32,
                                                 shape=(None, Nx * Ny))
            log_probs_tensor = wf.log_probability(samples_placeholder,
                                                  inputdim=2)

            queue_samples = np.zeros(
                (Nx * Ny + 1, numsamples, Nx * Ny), dtype=np.int32
            )  #Array to store all the diagonal and non diagonal matrix elements (We create it here for memory efficiency as we do not want to allocate it at each training step)
            log_probs = np.zeros(
                (Nx * Ny + 1) * numsamples, dtype=np.float64
            )  #Array to store the log_probs of all the diagonal and non diagonal matrix elements (We create it here for memory efficiency as we do not want to allocate it at each training step)

            for it in range(len(meanEnergy), numsteps + 1):

                #                 print("sampling started")
                #                 start = time.time()

                samples = sess.run(samples_)

                #                 end = time.time()
                #                 print("sampling ended: "+ str(end - start))

                #Estimating local_energies
                local_energies = Ising2D_local_energies(
                    Jz, Bx, Nx, Ny, samples, queue_samples, log_probs_tensor,
                    samples_placeholder, log_probs, sess)

                meanE = np.mean(local_energies)
                varE = np.var(local_energies)

                #adding elements to be saved
                meanEnergy.append(meanE)
                varEnergy.append(varE)

                if it % 10 == 0:
                    print(
                        'mean(E): {0}, var(E): {1}, #samples {2}, #Step {3} \n\n'
                        .format(meanE, varE, numsamples, it))

                #Comment if you don't want to save if saving gives you errors
                if it >= 1000 and varE <= np.min(
                        varEnergy
                ):  #We do it>100 to start saving the model after we get close to convergence to avoid slowing down due to too many saves initially
                    #Saving the performances if the model is better
                    saver.save(sess, path + '/' + filename)

                #Comment if you don't want to save if saving gives you errors
                if it % 10 == 0:
                    #Saving the performances
                    np.save(
                        '../Check_Points/2DTFIM/meanEnergy_GRURNN_' + str(Nx) +
                        'x' + str(Ny) + '_Bx' + str(Bx) + '_lradap' + str(lr) +
                        '_samp' + str(numsamples) + ending + savename + '.npy',
                        meanEnergy)
                    np.save(
                        '../Check_Points/2DTFIM/varEnergy_GRURNN_' + str(Nx) +
                        'x' + str(Ny) + '_Bx' + str(Bx) + '_lradap' + str(lr) +
                        '_samp' + str(numsamples) + ending + savename + '.npy',
                        varEnergy)

                #lr decay
                lr_ = 1 / ((1 / lr) + (it / 10))
                #Optimization step
                sess.run(optstep,
                         feed_dict={
                             Eloc: local_energies,
                             samp: samples,
                             learningrate_placeholder: lr_
                         })

    return meanEnergy, varEnergy