tensorflow: guardando y restaurando sesión

Estoy tratando de implementar una sugerencia de respuestas: Tensorflow: ¿cómo guardar / restaurar un modelo?

Tengo un objeto que envuelve un modelo tensorflow en un estilo sklearn .

 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.restre(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 

Cuando corro

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

Me sale de salida

 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 

Sin embargo, cuando bash recuperar los parámetros (incluso sin matar el objeto): tfl.fit( train_X, train_Y , load = True)

Obtengo resultados extraños. En primer lugar, el valor cargado no corresponde al guardado.

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

¿Cuál es la forma correcta de cargar, y probablemente inspeccionar primero las variables guardadas?

TL; DR: Debes intentar volver a trabajar esta clase para que self.create_network() se llame (i) solo una vez, y (ii) antes de que se construya tf.train.Saver() .

Hay dos problemas sutiles aquí, que se deben a la estructura del código y al comportamiento predeterminado del constructor tf.train.Saver . Cuando construye un protector sin argumentos (como en su código), recostack el conjunto actual de variables en su progtwig y agrega operaciones al gráfico para guardarlas y restaurarlas. En su código, cuando llame a tflasso() , construirá un protector y no habrá variables (porque aún no se ha llamado a create_network() ). Como resultado, el punto de control debe estar vacío.

El segundo problema es que, de forma predeterminada, el formato de un punto de control guardado es un mapa de la propiedad de name de una variable a su valor actual. Si crea dos variables con el mismo nombre, serán automáticamente “uniquified” por TensorFlow:

 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. 

La consecuencia de esto es que, cuando llama a self.create_network() en la segunda llamada a tfl.fit() , todas las variables tendrán nombres diferentes de los nombres que están almacenados en el punto de control, o lo hubieran sido si el ahorrador Se había construido después de la red. (Puede evitar este comportamiento pasando un diccionario Variable nombre al constructor de ahorro, pero esto suele ser bastante incómodo).

Hay dos soluciones principales:

  1. En cada llamada a tflasso.fit() , crea de nuevo todo el modelo, definiendo un nuevo tf.Graph , luego, en ese gráfico, construyes la red y creas un tf.train.Saver .

  2. RECOMENDADO Cree la red, luego tf.train.Saver en el constructor tflasso , y reutilice este gráfico en cada llamada a tflasso.fit() . Tenga en cuenta que es posible que necesite hacer un poco más de trabajo para reorganizar las cosas (en particular, no estoy seguro de lo que hace con self.X y self.xlen ), pero debería ser posible lograr esto con los marcadores de posición y la alimentación.