在tensorflow中恢复使用可变输入长度训练的模型会导致InvalidArgumentError

时间:2017-07-05 15:45:35

标签: tensorflow restore

我对tensorflow很新,目前正在尝试不同复杂程度的模型。我有一个包的保存和恢复功能的问题。据我所知,我应该能够恢复训练有素的图形并在稍后的某个时候使用一些新的输入来运行它。但是,当我尝试这样做时,我收到以下错误。:

  

InvalidArgumentError(参见上面的回溯):Shape [-1,10]具有负尺寸        [[Node:Placeholder = Placeholderdtype = DT_FLOAT,shape = [?,10],_ device =“/ job:localhost / replica:0 / task:0 / cpu:0”]]

我对该消息的理解是,恢复的图形不喜欢任意一个维度,这对于我事先不知道输入量有多大的实际情况是必要的。可以在下面找到作为最小示例的代码片段,产生上述错误。我知道如何单独恢复每个张量,但是当模型变得复杂时,这很快就会变得不切实际。我感谢任何帮助,并在我的问题愚蠢的时候道歉。

import numpy as np
import tensorflow as tf

def generate_random_input():
    alist = []
    for _ in range(10):
        alist.append(np.random.uniform(-1, 1, 100))
    return np.array(alist).T
def generate_random_target():
    return np.random.uniform(-1, 1, 100)

x = tf.placeholder('float', [None, 10])
y = tf.placeholder('float')

# the model 
w1 = tf.get_variable('w1', [10, 1], dtype=tf.float32, initializer=tf.contrib.layers.xavier_initializer(seed=1))
b1 = tf.get_variable('b1', [1], dtype=tf.float32, initializer=tf.contrib.layers.xavier_initializer(seed=1))

result = tf.add(tf.matmul(x, w1), b1, name='result')

loss = tf.reduce_mean(tf.losses.mean_squared_error(predictions=result, labels=y))
optimizer = tf.train.AdamOptimizer(0.03).minimize(loss)
saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    sess.run([optimizer, loss], feed_dict={x: generate_random_input(), y: generate_random_target()})
    saver.save(sess, 'file_name')

# now load the model in another session:
sess2 = tf.Session()
saver = tf.train.import_meta_graph('file_name.meta')
saver.restore(sess2, tf.train.latest_checkpoint('./'))
graph = tf.get_default_graph()
pred = graph.get_operation_by_name('result')
test_result = sess2.run(pred, feed_dict={x: generate_random_input()})

2 个答案:

答案 0 :(得分:0)

在最后一行中,您没有使用数据feed_dict label_palceholder。因此在占位符中,[-1]维度仍为-1,而不是批处理大小。这就是原因。

答案 1 :(得分:0)

我遇到与你完全相同的问题。我正在导入和测试一堆具有不同图层大小的不同CNN并测试各种数据集。您可以将模型创建粘贴到这样的函数中,然后在其他代码中重新创建它:

def create_model():
    x = tf.placeholder('float', [None, 10])
    y = tf.placeholder('float')   
    w1 = tf.get_variable('w1', [10, 1], dtype=tf.float32, initializer=tf.contrib.layers.xavier_initializer(seed=1))
    b1 = tf.get_variable('b1', [1], dtype=tf.float32, initializer=tf.contrib.layers.xavier_initializer(seed=1))
    result = tf.add(tf.matmul(x, w1), b1, name='result')
    return x, y, result

x, y, result = create_model()
loss = tf.reduce_mean(tf.losses.mean_squared_error(predictions=result, labels=y))
optimizer = tf.train.AdamOptimizer(0.03).minimize(loss)
saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    sess.run([optimizer, loss], feed_dict={x: generate_random_input(), y: generate_random_target()})
    saver.save(sess, 'file_name')

# now load the model in another session:
sess2 = tf.Session()
# This stuff is optional if everything is the same scope
x, y, result = create_model()
saver = tf.train.Saver()
# loss = ... if you want loss
# Now just restore the weights and run
saver.restore(sess, 'file_name')
test_result = sess2.run(pred, feed_dict={x: generate_random_input()})

如果我想要导入许多具有不同维度的复杂架构,这有点单调乏味。对于我们的情况,我不知道是否有任何其他方法来恢复整个模型,而不是在第二次会话中首先重新创建该架构。