需要帮助来了解tf.contrib.layers.fully_connected训练的权重

时间:2019-08-05 02:00:24

标签: tensorflow

我一般来说对神经网络和张量流还比较陌生。 在我学习的课程中,我们构建了一个cnn。用简单的术语来说,我认为我可以传达一些精简语句所发生的事情:

在第一个tf.session()中,训练网络并将参数存储到python字典中。在Tensorboard培训期间,我监控成本和测试/培训的准确性,并且得到非常合理的结果。

def forward_propagation(X, parameters):
    ....
    model layers...
    ....
    z_out = tf.contrib.layers.fully_connected(P2, 6, activation_fn=None)

    return z_out

def model(X_train, Y_train,...):
    ....
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer()
        ....
        loop thru epochs and mini-batches...
        optimize parameters...
        parameters = sess.run(parameters)
    ....

    return parameters # python dict

然后在第二个tf会话中,使用来自第一个tf会话的训练参数进行预测。

def predict(X, parameters):

    x = tf.placeholder("float", shape=(None, 64, 64, 3))
    z3 = forward_propagation(x, parameters)
    a3 = tf.nn.softmax(z3, axis=1)
    p = tf.argmax(a3, axis=1)

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        prediction = sess.run(p, feed_dict = {x: X})

    return prediction

但是第二个会话需要sess.run(tf.global_variables_initializer()),否则tf.contrib.layers.fully_connected()会在没有它的情况下引发错误。结果,返回的预测将随机化,并且每次运行都会更改。我强烈怀疑砝码是随机的或未正确装入。

当我运行命令tf.trainable_variables()时,我得到以下输出:

    [<tf.Variable 'W1:0' shape=(4, 4, 3, 8) 
    dtype=float32_ref>,
     <tf.Variable 'W2:0' shape=(2, 2, 8, 16) 
    dtype=float32_ref>,
     <tf.Variable 'fully_connected/weights:0' shape=(64, 6) 
    dtype=float32_ref>,
     <tf.Variable 'fully_connected/biases:0' shape=(6,) 
    dtype=float32_ref>]

似乎权重和偏见是变量。

所以我的问题本质上是这样的:即使执行全局变量初始值设定项,如何才能获得函数tf.contrib.layers.fully_connected(P2,6,activation_fn = None)正确加载权重或作出响应?我是严重错过了一个过程还是步骤?

我验证了问题出在完全连接的函数上,因为当我删除此层并仅实现z_out = tf.matmul(P2,W3)+ b3(其中W3和b3是参数dict中经过适当训练的变量)时,行为正常且稳定,符合预期。

2 个答案:

答案 0 :(得分:1)

您应该将经过训练的砝码保存在内存中。通常,forward_propagationpredict是python类的一些方法,并且model可以包装在该类的__init__()中。此外,将tensorflow变量保留为类属性,例如:self.z_out = tf.contrib.layers.fully_connected(P2, 6, activation_fn=None)

然后,当您调用predict时,您将调用forward_propagation(x, parameters),它将重用已经初始化和训练的self.z_out层。这样您就不会抛出任何错误。

现在,当您调用forward_propagation并希望初始化这些层时,当前的代码只是重新定义了新的层。请注意,您应该将所有图层保留在对象中,而不仅仅是最后一层(此处是卷积图层)。

答案 1 :(得分:0)

我知道了。我需要在培训课程结束时添加tf.train.Saver()。save。然后在预测会话期间,我需要添加tf.train.Saver()。restore。我还发现,需要在训练开始之前以及恢复变量之前重置图,以确保状态良好。

def model(X_train, Y_train,...):
    ....

    tf.reset_default_graph()

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer()
        ....
        loop thru epochs and mini-batches...
        optimize parameters...
        parameters = sess.run(parameters)
        save_path = tf.train.Saver().save(sess, "/tmp/model.ckpt")
        print (f"Variables saved in path: {save_path}")
    ....

然后在预测期间:

def predict(X, parameters):

    tf.reset_default_graph()

    x = tf.placeholder("float", shape=(None, 64, 64, 3))
    z3 = forward_propagation(x, parameters)
    a3 = tf.nn.softmax(z3, axis=1)
    p = tf.argmax(a3, axis=1)

    with tf.Session() as sess:
        tf.train.Saver().restore(sess, "/tmp/model.ckpt")
        prediction = sess.run(p, feed_dict = {x: X})

    return prediction