Hamid Zafar
Hamid Zafar

Reputation: 43

Tensorflow: Restore model with sparse_placeholder

I need to save and restore a model that uses sparse_placeholder, however I'm getting an error message: KeyError: "The name 'w1:0' refers to a Tensor which does not exist. The operation, 'w1', does not exist in the graph."

Here is a simplistic way to reproduce the error I'm getting when I need to restore a model in which there is a sparse_tensor:

import tensorflow as tf
import numpy as np


def train_sparse():
    w1 = tf.sparse_placeholder(tf.float64, shape=None, name="w1")
    b1 = tf.Variable(np.ones((2, 2)) * 1.0, name="bias")
    operation = tf.sparse_tensor_dense_matmul(w1, b1, name="op1")

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        saver = tf.train.Saver()
        w1_value = tf.SparseTensorValue([[1, 1]], [5], [2, 2])
        print sess.run(operation, {w1: w1_value})
        saver.save(sess, 'my_test_model')


def test_sparse():
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph('my_test_model.meta')
        saver.restore(sess, tf.train.latest_checkpoint('./'))
        print(sess.run('bias:0'))
        graph = tf.get_default_graph()
        op_to_restore = graph.get_tensor_by_name("op1/SparseTensorDenseMatMul:0")
        w1 = graph.get_tensor_by_name("w1:0")
        w1_value = tf.SparseTensorValue([[1, 1]], [5], [2, 2])

        print sess.run(op_to_restore, {w1: w1_value})

if __name__ == "__main__":
    train_sparse()
    test_sparse()

Here we can see a similar graph in which normal tensor has been used:

import tensorflow as tf
import numpy as np

def train():
    w1 = tf.placeholder(tf.float64, shape=None, name="w1")
    b1 = tf.Variable(np.ones((2, 2)) * 1.0, name="bias")
    operation = tf.matmul(w1, b1, name="op1")

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        saver = tf.train.Saver()
        w1_value = [[0, 0], [0, 5]]
        print sess.run(operation, {w1: w1_value})
        saver.save(sess, 'my_test_model')


def test():
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph('my_test_model.meta')
        saver.restore(sess, tf.train.latest_checkpoint('./'))
        print(sess.run('bias:0'))
        graph = tf.get_default_graph()
        op_to_restore = graph.get_tensor_by_name("op1:0")
        w1 = graph.get_tensor_by_name("w1:0")
        w1_value = [[0, 0], [0, 5]]

        print sess.run(op_to_restore, {w1: w1_value})


if __name__ == "__main__":
    train()
    test()

Does anyone have an idea how to fix it?

As a work around, I am able to pass the data as normal tensor, and change to sparse_tensor in the graph. However, it required unnecessary conversions.

Upvotes: 2

Views: 678

Answers (1)

TTS
TTS

Reputation: 108

Tensorflow saves indices, values and shape of the sparse placeholder separate. It suffixes them accordingly, so a SparsePlaceholder named w1 becomes 3 placeholders named w1/indices, w1/values and w1/shape in the saved graph.

I altered your example a bit so it gets a bit clearer:

import tensorflow as tf
import numpy as np


def train_sparse():
    w1 = tf.sparse_placeholder(tf.float64, shape=None, name="w1")
    b1 = tf.Variable(np.ones((2, 2)) * 1.0, name="bias")
    operation = tf.sparse_tensor_dense_matmul(w1, b1, name="op1")

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        saver = tf.train.Saver()
        w1_value = tf.SparseTensorValue([[1, 1]], [5], [2, 2])
        print sess.run(operation, {w1: w1_value})
        saver.save(sess, 'my_test_model')

def test_sparse():
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph('my_test_model.meta')
        saver.restore(sess, tf.train.latest_checkpoint('./'))
        print(sess.run('bias:0'))
        graph = tf.get_default_graph()
        op_to_restore = graph.get_tensor_by_name("op1/SparseTensorDenseMatMul:0")

        # NEW PART 

        w1_indices = graph.get_tensor_by_name("w1/indices:0")
        w1_indices_value = [[1,1]]

        w1_size = graph.get_tensor_by_name("w1/indices:0")
        w1_size_value = [5]

        w1_values = graph.get_tensor_by_name("w1/values:0")
        w1_values_value = [5]

        w1_shape = graph.get_tensor_by_name("w1/shape:0")
        w1_shape_value = [2,2]

        print sess.run(op_to_restore, {w1_indices: w1_indices_value,
                                       w1_values: w1_values_value,
                                       w1_shape: w1_shape_value})

if __name__ == "__main__":
    train_sparse()
    test_sparse()

Upvotes: 3

Related Questions