title: How does Tensorflow manage graphs?
body: <p>I have realized that there is some funky stuff going on with the way Tensorflow seems to be managing graphs.</p>
  
  <p>Since building (and rebuilding) models is so tedious, I decided to wrap my custom model in a class so I could easily re-instantiate it elsewhere.</p>
  
  <p>When I was training and testing the code (in the original place) it would work fine, however in the code where I loaded the graph's variables I would get all sorts of weird errors - variable redefinitions and everything else. This (from my last question about a similar thing) was the hint that everything was being called twice.</p>
  
  <p>After doing a TON of tracing, it came down to the way I was using the loaded code. It was being used from within a class that had a structure like so</p>
  
  <pre><code>class MyModelUser(object):
      def forecast(self):
         # .. build the model in the same way as in the training code
         # load the model checkpoint
         # call the "predict" function on the model
         # manipulate the prediction and return it
  </code></pre>
  
  <p>And then in some code that uses <code>MyModelUser</code>I had</p>
  
  <pre><code>def test_the_model(self):
     model_user = MyModelUser()
     print(model_user.forecast())  # 1
     print(model_user.forecast())  # 2
  </code></pre>
  
  <p>and I (obviously) expected to see two forecasts when this was called. Instead, the first forecast was called and worked as expected, but the second call threw a <em>TON</em> of variable reuse ValueError an example of one of these was:</p>
  
  <pre><code>ValueError: Variable weight_def/weights already exists, disallowed. Did you mean to set reuse=True in VarScope?
  </code></pre>
  
  <p>I managed to quell the errors by adding a series of try/except blocks that used <code>get_variable</code> to create the variable, and then on exception, called <code>reuse_variables</code> on the scope and then <code>get_variable</code> without anything but the name. This brought on a new set of nasty errors, one of which was:</p>
  
  <pre><code>tensorflow.python.framework.errors.NotFoundError: Tensor name "weight_def/weights/Adam_1" not found in checkpoint files
  </code></pre>
  
  <p>On a whim I said "what if I move the modeling building code to <code>__init__</code> so its only built once?"</p>
  
  <p>My new model user:</p>
  
  <pre><code>class MyModelUser(object):
      def __init__(self):
         # ... build the model in the same way as in the training code
         # load the model checkpoint
  
  
      def forecast(self):
         # call the "predict" function on the model
         # manipulate the prediction and return it
  </code></pre>
  
  <p>and now:</p>
  
  <pre><code>def test_the_model(self):
     model_user = MyModelUser()
     print(model_user.forecast())  # 1
     print(model_user.forecast())  # 2
  </code></pre>
  
  <p>Works as expected, printing two forecasts with no errors. This leads me to believe I can also get rid of the variable reuse stuff.</p>
  
  <p>My question is this:</p>
  
  <p>Why did this fix it? In theory, the graph should be reinstanced every single time in the original predict method, so it shouldn't be creating more than one graph. Does Tensorflow persist the graph even after the function completes? Is this why moving the creation code to <code>__init__</code> worked? This has left me hopelessly confused.</p>