GP + Tensorflow 训练
GP + Tensorflow training
我正在尝试同时训练 GPR 模型和 tensorflow 模型。训练部分没有问题。但是对于使用经过训练的模型进行预测,我在 tf.placeholder 操作中收到类型错误。
pred, uncp=sess.run([my, yv], feed_dict={X:xtr})
代码类似于 https://gpflow.readthedocs.io/en/master/notebooks/advanced_usage.html
中的第二个示例
import numpy as np
import tensorflow as tf
import gpflow
float_type = gpflow.settings.float_type
gpflow.reset_default_graph_and_session()
def cnn_fn(x, output_dim):
out= tf.layers.dense(inputs=x, units=output_dim, activation=tf.nn.relu)
print(out)
return out
N = 150
xtr = np.random.rand(N,1)
ytr = np.sin(12*xtr) + 0.66*np.cos(25*xtr) + np.random.randn(N,1)*0.1 + 3
xtr = np.random.rand(N,28)
print(xtr.shape, ytr.shape)
nepoch=50
gp_dim=xtr.shape[1]
print(gp_dim)
minibatch_size = 16
X = tf.placeholder(tf.float32, [None, gp_dim])
Y = tf.placeholder(tf.float32, [None, 1])
with tf.variable_scope('cnn'):
f_X = tf.cast(cnn_fn(X, gp_dim), dtype=float_type)
k = gpflow.kernels.Matern52(gp_dim)
gp_model = gpflow.models.GPR(f_X, tf.cast(Y, dtype=float_type), k)
loss = -gp_model.likelihood_tensor
m, v = gp_model._build_predict(f_X)
my, yv = gp_model.likelihood.predict_mean_and_var(m, v)
with tf.variable_scope('adam'):
opt_step = tf.train.AdamOptimizer(0.001).minimize(loss)
tf_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='adam')
tf_vars += tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='cnn')
## initialize
sess = tf.Session()
sess.run(tf.variables_initializer(var_list=tf_vars))
gp_model.initialize(session=sess)
for i in range(nepoch):
shind=np.array(range(len(xtr)))
np.random.shuffle(shind)
for j in range(int(len(xtr)/minibatch_size)):
ind=shind[j*minibatch_size: (j+1)*minibatch_size]
sess.run(opt_step, feed_dict={X:xtr[ind], Y:ytr[ind]})
执行上面的代码运行良好。但是添加以下行会出错:
pred, uncp=sess.run([my, yv], feed_dict={X:xtr})
出现以下错误:
<ipython-input-25-269715087df2> in <module>
----> 1 pred, uncp=sess.run([my, yv], feed_dict={X:xtr})
[...]
InvalidArgumentError: You must feed a value for placeholder tensor 'Placeholder_1' with dtype float and shape [?,1]
[[node Placeholder_1 (defined at <ipython-input-24-39ccf45cd248>:2) = Placeholder[dtype=DT_FLOAT, shape=[?,1], _device="/job:localhost/replica:0/task:0/device:GPU:0"]()]]
您的代码失败的原因是您实际上没有向其中一个占位符输入值。如果你真的给他们起名字,这更容易发现:
X = tf.placeholder(tf.float32, [None, gp_dim], name='X')
Y = tf.placeholder(tf.float32, [None, 1], name='Y')
Tensorflow 要求整个计算图 well-defined、 并且您使用的 GPR
模型取决于 X
和 Y
。如果你 运行 以下行,它工作正常:
pred, uncp = sess.run([my, yv], feed_dict={X: xtr, Y: ytr})
更新:正如user1018464在评论中指出的那样,您使用的是GPR
模型,其中预测直接取决于训练数据(例如,参见 http://www.gaussianprocess.org/gpml/chapters/RW2.pdf 第 16 页的等式 (2.22) 和 (2.23))。因此,您需要同时传入 xtr
和 ytr
才能进行预测。
其他模型,例如 SVGP
通过 "inducing features" 表示函数,通常 "pseudo input/output" 对汇总数据,在这种情况下,您不需要输入原始输入完全没有价值(我第一次回答时弄错了)。
您可以按如下方式设置模型:
gp_model = gpflow.models.SVGP(f_X, tf.cast(Y, dtype=float_type), k, gpflow.likelihoods.Gaussian(), xtr.copy(), num_data=N)
然后 pred, uncp=sess.run([my, yv], feed_dict={X:xtr})
按预期工作。
如果想在不同的点Xtest
进行预测,需要单独设置占位符,并复用cnn(注意variable_scope中的reuse=True
与名称),如笔记本的示例 2 所示:
Xtest = tf.placeholder(tf.float32, [None, Mnist.input_dim], name='Xtest')
with tf.variable_scope('cnn', reuse=True):
f_Xtest = tf.cast(cnn_fn(Xtest, gp_dim), dtype=float_type)
像以前一样使用 f_X
设置模型,但在对 _build_predict
的调用中使用 f_Xtest
:
m, v = gp_model._build_predict(f_Xtest)
my, yv = gp_model.likelihood.predict_mean_and_var(m, v)
现在您需要将 X
、Y
、 和 Xtest
都传入会话的 运行() :
pred, uncp = sess.run([my, yv], feed_dict={X: xtr, Y: Ytr, Xtest: xtest})
其中 xtest
是包含您要预测的点的 numpy 数组。
GPflow 为您管理 TensorFlow 会话,当您单独使用 GPflow 时,您无需创建自己的 TF 会话。在你的情况下,tf.layers.dense
新变量,应该初始化,我建议使用由 GPflow 创建的会话。本质上,您需要替换这些行
## initialize
sess = tf.Session()
sess.run(tf.variables_initializer(var_list=tf_vars))
gp_model.initialize(session=sess)
与:
sess = gpflow.get_default_session()
sess.run(tf.variables_initializer(var_list=tf_vars)
或使用默认会话上下文包装您的代码:
with tf.Session() as session:
... build and run
我正在尝试同时训练 GPR 模型和 tensorflow 模型。训练部分没有问题。但是对于使用经过训练的模型进行预测,我在 tf.placeholder 操作中收到类型错误。
pred, uncp=sess.run([my, yv], feed_dict={X:xtr})
代码类似于 https://gpflow.readthedocs.io/en/master/notebooks/advanced_usage.html
中的第二个示例import numpy as np
import tensorflow as tf
import gpflow
float_type = gpflow.settings.float_type
gpflow.reset_default_graph_and_session()
def cnn_fn(x, output_dim):
out= tf.layers.dense(inputs=x, units=output_dim, activation=tf.nn.relu)
print(out)
return out
N = 150
xtr = np.random.rand(N,1)
ytr = np.sin(12*xtr) + 0.66*np.cos(25*xtr) + np.random.randn(N,1)*0.1 + 3
xtr = np.random.rand(N,28)
print(xtr.shape, ytr.shape)
nepoch=50
gp_dim=xtr.shape[1]
print(gp_dim)
minibatch_size = 16
X = tf.placeholder(tf.float32, [None, gp_dim])
Y = tf.placeholder(tf.float32, [None, 1])
with tf.variable_scope('cnn'):
f_X = tf.cast(cnn_fn(X, gp_dim), dtype=float_type)
k = gpflow.kernels.Matern52(gp_dim)
gp_model = gpflow.models.GPR(f_X, tf.cast(Y, dtype=float_type), k)
loss = -gp_model.likelihood_tensor
m, v = gp_model._build_predict(f_X)
my, yv = gp_model.likelihood.predict_mean_and_var(m, v)
with tf.variable_scope('adam'):
opt_step = tf.train.AdamOptimizer(0.001).minimize(loss)
tf_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='adam')
tf_vars += tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='cnn')
## initialize
sess = tf.Session()
sess.run(tf.variables_initializer(var_list=tf_vars))
gp_model.initialize(session=sess)
for i in range(nepoch):
shind=np.array(range(len(xtr)))
np.random.shuffle(shind)
for j in range(int(len(xtr)/minibatch_size)):
ind=shind[j*minibatch_size: (j+1)*minibatch_size]
sess.run(opt_step, feed_dict={X:xtr[ind], Y:ytr[ind]})
执行上面的代码运行良好。但是添加以下行会出错:
pred, uncp=sess.run([my, yv], feed_dict={X:xtr})
出现以下错误:
<ipython-input-25-269715087df2> in <module>
----> 1 pred, uncp=sess.run([my, yv], feed_dict={X:xtr})
[...]
InvalidArgumentError: You must feed a value for placeholder tensor 'Placeholder_1' with dtype float and shape [?,1]
[[node Placeholder_1 (defined at <ipython-input-24-39ccf45cd248>:2) = Placeholder[dtype=DT_FLOAT, shape=[?,1], _device="/job:localhost/replica:0/task:0/device:GPU:0"]()]]
您的代码失败的原因是您实际上没有向其中一个占位符输入值。如果你真的给他们起名字,这更容易发现:
X = tf.placeholder(tf.float32, [None, gp_dim], name='X')
Y = tf.placeholder(tf.float32, [None, 1], name='Y')
Tensorflow 要求整个计算图 well-defined、 并且您使用的 GPR
模型取决于 X
和 Y
。如果你 运行 以下行,它工作正常:
pred, uncp = sess.run([my, yv], feed_dict={X: xtr, Y: ytr})
更新:正如user1018464在评论中指出的那样,您使用的是GPR
模型,其中预测直接取决于训练数据(例如,参见 http://www.gaussianprocess.org/gpml/chapters/RW2.pdf 第 16 页的等式 (2.22) 和 (2.23))。因此,您需要同时传入 xtr
和 ytr
才能进行预测。
其他模型,例如 SVGP
通过 "inducing features" 表示函数,通常 "pseudo input/output" 对汇总数据,在这种情况下,您不需要输入原始输入完全没有价值(我第一次回答时弄错了)。
您可以按如下方式设置模型:
gp_model = gpflow.models.SVGP(f_X, tf.cast(Y, dtype=float_type), k, gpflow.likelihoods.Gaussian(), xtr.copy(), num_data=N)
然后 pred, uncp=sess.run([my, yv], feed_dict={X:xtr})
按预期工作。
如果想在不同的点Xtest
进行预测,需要单独设置占位符,并复用cnn(注意variable_scope中的reuse=True
与名称),如笔记本的示例 2 所示:
Xtest = tf.placeholder(tf.float32, [None, Mnist.input_dim], name='Xtest')
with tf.variable_scope('cnn', reuse=True):
f_Xtest = tf.cast(cnn_fn(Xtest, gp_dim), dtype=float_type)
像以前一样使用 f_X
设置模型,但在对 _build_predict
的调用中使用 f_Xtest
:
m, v = gp_model._build_predict(f_Xtest)
my, yv = gp_model.likelihood.predict_mean_and_var(m, v)
现在您需要将 X
、Y
、 和 Xtest
都传入会话的 运行() :
pred, uncp = sess.run([my, yv], feed_dict={X: xtr, Y: Ytr, Xtest: xtest})
其中 xtest
是包含您要预测的点的 numpy 数组。
GPflow 为您管理 TensorFlow 会话,当您单独使用 GPflow 时,您无需创建自己的 TF 会话。在你的情况下,tf.layers.dense
新变量,应该初始化,我建议使用由 GPflow 创建的会话。本质上,您需要替换这些行
## initialize
sess = tf.Session()
sess.run(tf.variables_initializer(var_list=tf_vars))
gp_model.initialize(session=sess)
与:
sess = gpflow.get_default_session()
sess.run(tf.variables_initializer(var_list=tf_vars)
或使用默认会话上下文包装您的代码:
with tf.Session() as session:
... build and run