如何在张量流中恢复保存的BiRNN模型,以便将所有输出神经元正确捆绑到相应的输出类



我在张量流中正确恢复保存的模型时遇到了问题。我使用以下代码在张量流中创建了双向 RNN 模型:

batchX_placeholder = tf.placeholder(tf.float32, [None, timesteps, 1],
                                    name="batchX_placeholder")])
batchY_placeholder = tf.placeholder(tf.float32, [None, num_classes],
                                    name="batchY_placeholder")
weights = tf.Variable(np.random.rand(2*STATE_SIZE, num_classes),
                      dtype=tf.float32, name="weights")
biases = tf.Variable(np.zeros((1, num_classes)), dtype=tf.float32,
                     name="biases")
logits = BiRNN(batchX_placeholder, weights, biases)
with tf.name_scope("prediction"):
    prediction = tf.nn.softmax(logits)
loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
logits=logits, labels=batchY_placeholder))
lr = tf.Variable(learning_rate, trainable=False, dtype=tf.float32,
                 name='lr')
optimizer = tf.train.AdamOptimizer(learning_rate=lr)
train_op = optimizer.minimize(loss_op)
init_op = tf.initialize_all_variables()
saver = tf.train.Saver()

BiRNN的架构使用以下功能创建:

def BiRNN(x, weights, biases):
    # Unstack to get a list of 'time_steps' tensors of shape (batch_size,
    # num_input)
    x = tf.unstack(x, time_steps, 1)
    # Forward and Backward direction cells
    lstm_fw_cell = rnn.BasicLSTMCell(STATE_SIZE, forget_bias=1.0)
    lstm_bw_cell = rnn.BasicLSTMCell(STATE_SIZE, forget_bias=1.0)
    outputs, _, _ = rnn.static_bidirectional_rnn(lstm_fw_cell,
        lstm_bw_cell, x, dtype=tf.float32)
    # Linear activation, using rnn inner loop last output
    return tf.matmul(outputs[-1], weights) + biases

然后我训练一个模型,并在每 200 个步骤后保存它:

with tf.Session() as sess:
    sess.run(init_op)
    current_step = 0
    for batch_x, batch_y in get_minibatch():
        sess.run(train_op, feed_dict={batchX_placeholder: batch_x,
                                      batchY_placeholder: batch_y})
        current_step += 1
        if current_step % 200 == 0:
            saver.save(sess, os.path.join(model_dir, "model")

为了在推理模式下运行保存的模型,我在"model.meta"文件中使用了保存的张量流图:

graph = tf.get_default_graph()
saver = tf.train.import_meta_graph(os.path.join(model_dir, "model.meta"))
sess = tf.Session()
saver.restore(sess, tf.train.latest_checkpoint(model_dir)
weights = graph.get_tensor_by_name("weights:0")
biases = graph.get_tensor_by_name("biases:0")
batchX_placeholder = graph.get_tensor_by_name("batchX_placeholder:0")
batchY_placeholder = graph.get_tensor_by_name("batchY_placeholder:0")
logits = BiRNN(batchX_placeholder, weights, biases)
prediction = graph.get_operation_by_name("prediction/Softmax")
argmax_pred = tf.argmax(prediction, 1)
init = tf.global_variables_initializer()
sess.run(init)
for x_seq, y_gt in get_sequence():
    _, y_pred = sess.run([prediction, argmax_pred],
                    feed_dict={batchX_placeholder: [x_seq]],
                               batchY_placeholder: [[0.0, 0.0]]})
    print("Y ground true: " + str(y_gt) + ", Y pred: " + str(y_pred[0]))

当我在推理模式下运行代码时,每次启动它时都会得到不同的结果。似乎来自softmax层的输出神经元随机捆绑了不同的输出类。

所以,我的问题是:我怎样才能在张量流中保存然后正确恢复模型,以便所有神经元与相应的输出类正确捆绑在一起?

没有必要

打电话给tf.global_variables_initializer(),我认为那是你的问题。

我删除了一些操作:logitsweightsbiases,因为您不需要它们,所有这些都已经加载,请使用graph.get_tensor_by_name来获取它们。

对于prediction,获取张量而不是运算。(见这个答案):

这是代码:

graph = tf.get_default_graph()
saver = tf.train.import_meta_graph(os.path.join(model_dir, "model.meta"))
sess = tf.Session()
saver.restore(sess, tf.train.latest_checkpoint(model_dir))
batchX_placeholder = graph.get_tensor_by_name("batchX_placeholder:0")
batchY_placeholder = graph.get_tensor_by_name("batchY_placeholder:0")
prediction = graph.get_tensor_by_name("prediction/Softmax:0")
argmax_pred = tf.argmax(prediction, 1)

编辑1:我注意到我不清楚为什么你会得到不同的结果。

当我在推理模式下运行代码时,我得到不同的结果 每次我启动它时。

请注意,尽管您使用了已加载模型中的权重,但您将再次创建BiRNN,并且BasicLSTMCell还具有未从加载的模型中设置的权重和其他变量,因此需要初始化它们(使用新的随机值),从而再次生成未经训练的模型。

相关内容

最新更新