Although you haven't defined the variables manually, the code snippet above actually contains 15 saveable variables. You can see them using this internal tensorflow function:
from tensorflow.python.ops.variables import _all_saveable_objects
for obj in _all_saveable_objects():
print(obj)
For the code above, it produces the following list:
<tf.Variable 'fully_connected/weights:0' shape=(100, 50) dtype=float32_ref>
<tf.Variable 'fully_connected/biases:0' shape=(50,) dtype=float32_ref>
<tf.Variable 'fully_connected_1/weights:0' shape=(50, 2) dtype=float32_ref>
<tf.Variable 'fully_connected_1/biases:0' shape=(2,) dtype=float32_ref>
<tf.Variable 'Variable:0' shape=() dtype=int32_ref>
<tf.Variable 'beta1_power:0' shape=() dtype=float32_ref>
<tf.Variable 'beta2_power:0' shape=() dtype=float32_ref>
<tf.Variable 'fully_connected/weights/Adam:0' shape=(100, 50) dtype=float32_ref>
<tf.Variable 'fully_connected/weights/Adam_1:0' shape=(100, 50) dtype=float32_ref>
<tf.Variable 'fully_connected/biases/Adam:0' shape=(50,) dtype=float32_ref>
<tf.Variable 'fully_connected/biases/Adam_1:0' shape=(50,) dtype=float32_ref>
<tf.Variable 'fully_connected_1/weights/Adam:0' shape=(50, 2) dtype=float32_ref>
<tf.Variable 'fully_connected_1/weights/Adam_1:0' shape=(50, 2) dtype=float32_ref>
<tf.Variable 'fully_connected_1/biases/Adam:0' shape=(2,) dtype=float32_ref>
<tf.Variable 'fully_connected_1/biases/Adam_1:0' shape=(2,) dtype=float32_ref>
There are variables from both fully_connected
layers and several more coming from Adam optimizer (see this question). Note there're no X
and Y
placeholders in this list, so no need to exclude them. Of course, these tensors exist in the meta graph, but they don't have any value, hence not saveable.
The _all_saveable_objects()
list is what tensorflow saver saves by default, if the variables are not provided explicitly. Hence, the answer to your main question is simple:
saver = tf.train.Saver() # all saveable objects!
with tf.Session() as sess:
tf.global_variables_initializer().run()
saver.save(sess, "...")
There's no way to provide the name for the tf.contrib.layers.fully_connected
function (as a result, it's saved as fully_connected_1/...
), but you're encouraged to switch to tf.layers.dense
, wich has a name
argument. To see why it's a good idea anyway, take a look at this and this discussion.