我一般来说对神经网络和张量流还比较陌生。 在我学习的课程中,我们构建了一个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中经过适当训练的变量)时,行为正常且稳定,符合预期。
答案 0 :(得分:1)
您应该将经过训练的砝码保存在内存中。通常,forward_propagation
和predict
是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