2015-12-28 23 views
8

restore: Tensorflow: how to save/restore a model?tensorflow: kaydetme ve Cevapları gelen bir öneri uygulamak çalışıyorum oturumu

Ben sklearn tarzında bir tensorflow modeli sarar bir nesne var.

import tensorflow as tf 
class tflasso(): 
    saver = tf.train.Saver() 
    def __init__(self, 
       learning_rate = 2e-2, 
       training_epochs = 5000, 
        display_step = 50, 
        BATCH_SIZE = 100, 
        ALPHA = 1e-5, 
        checkpoint_dir = "./", 
      ): 
     ... 

    def _create_network(self): 
     ... 


    def _load_(self, sess, checkpoint_dir = None): 
     if checkpoint_dir: 
      self.checkpoint_dir = checkpoint_dir 

     print("loading a session") 
     ckpt = tf.train.get_checkpoint_state(self.checkpoint_dir) 
     if ckpt and ckpt.model_checkpoint_path: 
      self.saver.restore(sess, ckpt.model_checkpoint_path) 
     else: 
      raise Exception("no checkpoint found") 
     return 

    def fit(self, train_X, train_Y , load = True): 
     self.X = train_X 
     self.xlen = train_X.shape[1] 
     # n_samples = y.shape[0] 

     self._create_network() 
     tot_loss = self._create_loss() 
     optimizer = tf.train.AdagradOptimizer(self.learning_rate).minimize(tot_loss) 

     # Initializing the variables 
     init = tf.initialize_all_variables() 
     " training per se" 
     getb = batchgen(self.BATCH_SIZE) 

     yvar = train_Y.var() 
     print(yvar) 
     # Launch the graph 
     NUM_CORES = 3 # Choose how many cores to use. 
     sess_config = tf.ConfigProto(inter_op_parallelism_threads=NUM_CORES, 
                  intra_op_parallelism_threads=NUM_CORES) 
     with tf.Session(config= sess_config) as sess: 
      sess.run(init) 
      if load: 
       self._load_(sess) 
      # Fit all training data 
      for epoch in range(self.training_epochs): 
       for (_x_, _y_) in getb(train_X, train_Y): 
        _y_ = np.reshape(_y_, [-1, 1]) 
        sess.run(optimizer, feed_dict={ self.vars.xx: _x_, self.vars.yy: _y_}) 
       # Display logs per epoch step 
       if (1+epoch) % self.display_step == 0: 
        cost = sess.run(tot_loss, 
          feed_dict={ self.vars.xx: train_X, 
            self.vars.yy: np.reshape(train_Y, [-1, 1])}) 
        rsq = 1 - cost/yvar 
        logstr = "Epoch: {:4d}\tcost = {:.4f}\tR^2 = {:.4f}".format((epoch+1), cost, rsq) 
        print(logstr) 
        self.saver.save(sess, self.checkpoint_dir + 'model.ckpt', 
         global_step= 1+ epoch) 

      print("Optimization Finished!") 
     return self 

Ben çalıştırdığınızda:

tfl = tflasso() 
tfl.fit(train_X, train_Y , load = False) 

Ben çıkışı olsun: Ben parametreleri kurtarmak çalıştıklarında, Ancak

Epoch: 50 cost = 38.4705 R^2 = -1.2036 
    b1: 0.118122 
Epoch: 100 cost = 26.4506 R^2 = -0.5151 
    b1: 0.133597 
Epoch: 150 cost = 22.4330 R^2 = -0.2850 
    b1: 0.142261 
Epoch: 200 cost = 20.0361 R^2 = -0.1477 
    b1: 0.147998 

(hatta nesneyi öldürmeden): tfl.fit(train_X, train_Y , load = True)

Tuhaf sonuçlar alıyorum. Her şeyden önce, yüklenen değer kaydedilene uymuyor.

loading a session 
loaded b1: 0.1   <------- Loaded another value than saved 
Epoch: 50 cost = 30.8483 R^2 = -0.7670 
    b1: 0.137484 

Yüklemenin doğru yolu nedir ve muhtemelen önce kaydedilen değişkenleri inceleyin?

+0

tensorflow dokümantasyon oldukça basit örneklerden yoksun, sen örnekleri klasörlerde kazmak ve çoğunlukla kendi – diffeomorphism

cevap

10

TL; DR: Sadece bir kez self.create_network() (i) adı verilir, böylece bu sınıfı yeniden işleme çalışmalısınız, ve (ii) tf.train.Saver() önce inşa edilmiştir.

Kod yapısı ve tf.train.Saver constructor'un varsayılan davranışı nedeniyle iki ince sorun vardır. Argüman içermeyen bir koruyucuyu (kodunuzda olduğu gibi) oluşturduğunuzda, programınızdaki geçerli değişken kümesini toplar ve bunları kaydetmek ve geri yüklemek için grafiğe ops ekler. Kodunuzda, tflasso()'u aradığınızda, bir koruyucu oluşturur ve değişken olmaz (çünkü create_network() henüz çağrılmamıştır). Sonuç olarak, kontrol noktası boş olmalıdır.

İkinci sorun, — varsayılan olarak — varsayılan olarak kaydedilen bir denetim noktasının biçimi, geçerli değerine göre name property of a variable adresindeki bir haritadır. Aynı ada sahip iki değişken oluşturmak, bunlar TensorFlow tarafından otomatik olarak "uniquified" olacaktır:

v = tf.Variable(..., name="weights") 
assert v.name == "weights" 
w = tf.Variable(..., name="weights") 
assert v.name == "weights_1" # The "_1" is added by TensorFlow. 

Bunun sonucu size tfl.fit() ikinci çağrısında self.create_network() çağırdığınızda, değişkenler hepsine sahip olacak, yani — kontrol noktasında saklanan isimlerden farklı isimler veya koruyucudan sonra şebekeden yapılmış olsaydı. (Sen koruyucu yapıcı bir name- Variable sözlüğünü geçirerek bu davranıştan kaçınmak, ancak bu genellikle oldukça garip.) Iki ana geçici çözümler vardır

: tflasso.fit() yapılan her çağrı olarak

  1. oluşturmak tüm model, yeni bir tf.Graph tanımlayarak, ardından ağı oluşturan ve tf.train.Saver'u yaratan grafikte yeniden.

  2. ÖNERİLEN ağı, tflasso yapıcı sonra tf.train.Saver oluşturun ve tflasso.fit() yapılan her çağrı bu grafiği yeniden kullanın.Bazı şeyleri yeniden düzenlemek için daha fazla çalışma yapmanız gerekebileceğini unutmayın (özellikle, self.X ve self.xlen ile ne yaptığınızdan emin değilim), ancak bunu placeholders ile elde etmek ve beslemek mümkün olmalıdır.

+0

teşekkür üzerinde bir anlam çıkarmaya gerek! 'Self.vars.xx = tf.placeholder ("float", şekil = [Yok self.xlen:' xlen' X' 'giriş boyutu (tutucu init ayarlamak için self._create_network() '' içinde kullanılan ]) '). Söylediklerinden, tercih edilen yol, xlen'i başlatıcıya aktarmaktır. –

+0

Nesnenin yeniden başlatılması sırasında eski tf değişkenlerini tanımlayıcı/temizle sıfırlamanın bir yolu var mı? –

+1

Bunu yapmak için, yeni bir 'tf.Graph' oluşturmalı ve (i) ağı oluşturmadan önce (ii) bir' Saver' oluşturmalısınız. . Eğer) (a 'tf.Graph ile() as_default içinde()' tflasso.fit 'gövdesini sarın edin:' blok ve bu bloğun içine 'Saver' inşaat taşımak, isimler her zaman size aynı olmalıdır fit() işlevini çağırın. – mrry