2017-02-01 4 views
3

Ich habe die folgende Faltung neuronalen Netzwerk (CNN) -Klasse in Tensorflow geschrieben [Ich habe versucht, einige Zeilen Code für die Klarheit wegzulassen.]laden mehrere Modelle in Tensorflow

class CNN: 
def __init__(self, 
       num_filters=16,  # initial number of convolution filters 
      num_layers=5,   # number of convolution layers 
      num_input=2,   # number of channels in input 
      num_output=5,   # number of channels in output 
      learning_rate=1e-4, # learning rate for the optimizer 
      display_step = 5000, # displays training results every display_step epochs 
      num_epoch = 10000,  # number of epochs for training 
      batch_size= 64,  # batch size for mini-batch processing 
      restore_file=None,  # restore file (default: None) 

      ): 

       # define placeholders 
       self.image = tf.placeholder(tf.float32, shape = (None, None, None,self.num_input)) 
       self.groundtruth = tf.placeholder(tf.float32, shape = (None, None, None,self.num_output)) 

       # builds CNN and compute prediction 
       self.pred = self._build() 

       # I have already created a tensorflow session and saver objects 
       self.sess = tf.Session() 
       self.saver = tf.train.Saver() 

       # also, I have defined the loss function and optimizer as 
       self.loss = self._loss_function() 
       self.optimizer = tf.train.AdamOptimizer(learning_rate).minimize(self.loss) 

       if restore_file is not None: 
        print("model exists...loading from the model") 
        self.saver.restore(self.sess,restore_file) 
       else: 
        print("model does not exist...initializing") 
        self.sess.run(tf.initialize_all_variables()) 

def _build(self): 
    #builds CNN 

def _loss_function(self): 
    # computes loss 


# 
def train(self, train_x, train_y, val_x, val_y): 
    # uses mini batch to minimize the loss 
    self.sess.run(self.optimizer, feed_dict = {self.image:sample, self.groundtruth:gt}) 


    # I save the session after n=10 epochs as: 
    if epoch%n==0: 
     self.saver.save(sess,'snapshot',global_step = epoch) 

# finally my predict function is 
def predict(self, X): 
    return self.sess.run(self.pred, feed_dict={self.image:X}) 

Ich habe unabhängig für zwei getrennte Aufgaben zwei CNNs ausgebildet. Jeder dauerte ungefähr 1 Tag. Say, model1 und model2 werden als 'snapshot-model1-10000' und 'snapshot-model2-10000' (mit ihren entsprechenden Meta-Dateien) gespeichert. Ich kann jedes Modell testen und seine Leistung separat berechnen.

Jetzt möchte ich diese beiden Modelle in einem einzigen Skript laden. Ich würde natürlich versuchen, wie unten zu tun:

cnn1 = CNN(..., restore_file='snapshot-model1-10000',..........) 
cnn2 = CNN(..., restore_file='snapshot-model2-10000',..........) 

ich den Fehler auftreten [Die Fehlermeldung ist lang. Ich habe nur einen Ausschnitt kopiert/eingefügt.]

NotFoundError: Tensor name "Variable_26/Adam_1" not found in checkpoint files /home/amitkrkc/codes/A549_models/snapshot-hela-95000 
    [[Node: save_1/restore_slice_85 = RestoreSlice[dt=DT_FLOAT, preferred_shard=-1, _device="/job:localhost/replica:0/task:0/cpu:0"](_recv_save_1/Const_0, save_1/restore_slice_85/tensor_name, save_1/restore_slice_85/shape_and_slice)]] 

Gibt es eine Möglichkeit aus diesen beiden Dateien zwei separate CNNs zu laden? Jeder Vorschlag/Kommentar/Feedback ist willkommen.

Vielen Dank,

Antwort

4

Ja, es gibt. Verwenden Sie separate Grafiken.

g1 = tf.Graph() 
g2 = tf.Graph() 

with g1.as_default(): 
    cnn1 = CNN(..., restore_file='snapshot-model1-10000',..........) 
with g2.as_default(): 
    cnn2 = CNN(..., restore_file='snapshot-model2-10000',..........) 

EDIT:

Wenn Sie sie in derselben Grafik möchten. Sie müssen einige Variablen umbenennen. Eine Idee ist, jedes CNN in separaten Rahmen haben und lassen Sie Schoner Handle-Variablen in diesem Umfang zB:

saver = tf.train.Saver(tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES), scope='model1') 

und in cnn wickeln alle Ihre Konstruktion in -umfang:

with tf.variable_scope('model1'): 
    ... 

EDIT2:

Andere Idee ist das Umbenennen von Variablen, die der Sparer verwaltet (da ich annehme, dass Sie Ihre gespeicherten Checkpoints verwenden möchten, ohne alles neu zu trainieren. Das Speichern erlaubt verschiedene Variablennamen im Graphen und im Checkpoint, siehe Dokumentation zur Initialisierung.

+0

Vielen Dank. Ihr erster Vorschlag funktioniert gut für meinen Fall. – Amit

0

Ich stieß auf das gleiche Problem und konnte das Problem (ohne Umschulung) mit keiner Lösung lösen, die ich im Internet fand. Also habe ich jedes Modell in zwei separate Threads geladen, die mit dem Haupt-Thread kommunizieren. Es ist einfach genug, um den Code zu schreiben, Sie müssen nur vorsichtig sein, wenn Sie die Threads synchronisieren. In meinem Fall erhielt jeder Thread die Eingabe für sein Problem und gab die Ausgabe an den Hauptthread zurück. Es funktioniert ohne sichtbaren Overhead.