Skip to main content
 首页 » 编程设计

python之Tensorflow:使用 sparse_placeholder 恢复模型

2024年08月19日36cmt

我需要保存和恢复使用 sparse_placeholder 的模型,但是我收到一条错误消息: KeyError:“名称‘w1:0’指的是一个不存在的张量。运算‘w1’在图中不存在。”

这里有一个简单的方法来重现我在需要恢复包含 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() 

这里我们可以看到一个类似的图,其中使用了正态张量:

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() 

有没有人知道如何修复它?

作为解决方法,我可以将数据作为普通张量传递,并在图中更改为 sparse_tensor。但是,它需要进行不必要的转换。

请您参考如下方法:

Tensorflow 单独保存稀疏占位符的索引、值和形状。它相应地为它们添加后缀,因此名为 w1 的 SparsePlaceholder 变成了 3 个名为 w1/indices、w1/values 和 w1/shape< 的占位符 在保存的图表中。

我稍微修改了你的例子,让它变得更清晰:

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()