Python 在TensorFlow中将计算值缓存为常量
假设我想用闭式解计算TensorFlow中的最小二乘系数。通常,我会这样做Python 在TensorFlow中将计算值缓存为常量,python,numpy,constants,linear-regression,tensorflow,Python,Numpy,Constants,Linear Regression,Tensorflow,假设我想用闭式解计算TensorFlow中的最小二乘系数。通常,我会这样做 beta_hat = tf.matmul( tf.matmul(tf.matrix_inverse(tf.matmul(tf.transpose(X), X)), tf.transpose(X)), y ) 其中,X和y分别是对应于协变量和目标变量的TensorFlow占位符 如果我想进行预测,我会这样做 y_pred = tf.matmul(X, beta_hat) 如果我被处决 sess.r
beta_hat = tf.matmul(
tf.matmul(tf.matrix_inverse(tf.matmul(tf.transpose(X), X)), tf.transpose(X)), y
)
其中,X
和y
分别是对应于协变量和目标变量的TensorFlow占位符
如果我想进行预测,我会这样做
y_pred = tf.matmul(X, beta_hat)
如果我被处决
sess.run(y_pred, feed_dict={X: data_X})
我当然会得到一个错误,我没有为占位符y
提供必要的值。我希望在计算后能够灵活地将beta_hat
视为常数(这样我就不需要为预测的新协变量矩阵定义新的占位符)。实现这一目标的一个方法是
# Make it constant.
beta_hat = sess.run(beta_hat, feed_dict={X: data_X, y: data_y})
y_pred = tf.matmul(X, beta_hat)
我想知道是否有更优雅的方法将张量视为常数,这样我既不需要执行会话并获取常数,也不需要为用于预测的传入数据创建单独的占位符
下面是一些示例代码,演示了我所描述的环境
import numpy as np
import tensorflow as tf
n, k = 100, 5
X = tf.placeholder(dtype=tf.float32, shape=[None, k])
y = tf.placeholder(dtype=tf.float32, shape=[None, 1])
beta = np.random.normal(size=(k, ))
data_X = np.random.normal(size=(n, k))
data_y = data_X.dot(beta)
data_y += np.random.normal(size=data_y.shape) / 3.0
data_y = np.atleast_2d(data_y).T
# Convert to 32-bit precision.
data_X, data_y = np.float32(data_X), np.float32(data_y)
# Compute the least squares solution.
beta_hat = tf.matmul(
tf.matmul(tf.matrix_inverse(tf.matmul(tf.transpose(X), X)),
tf.transpose(X)), y
)
# Launch the graph
sess = tf.Session()
sess.run(tf.initialize_all_variables())
print "True beta: {}".format(beta)
print "Est. beta: {}".format(
sess.run(beta_hat, feed_dict={X: data_X, y: data_y}).ravel()
)
# # This would error.
# y_pred = tf.matmul(X, beta_hat)
# print "Predictions:"
# print sess.run(y_pred, feed_dict={X: data_X})
# Make it constant.
beta_hat = sess.run(beta_hat, feed_dict={X: data_X, y: data_y})
# This will no longer error.
y_pred = tf.matmul(X, beta_hat)
print "Predictions:"
print sess.run(y_pred, feed_dict={X: data_X})
也许与直觉相反,在后续步骤中将
beta_hat
重新用作常数的最简单方法是将其指定给:
mrry确实提出了一个优雅的解决方案。如果你确实想要的话,你应该考虑把他的答案标记为正确。 然而,我认为这是一个很好的地方来澄清我认为是关于占位符的混乱来源。。。这不一定是针对提出问题的人的,但我相信这对很多无意中发现这个问题的初学者来说是有意义的
占位符应被视为类似于函数输入。首先,让我们回顾一下它在Python中是如何工作的,然后我将在Tensorflow中展示等价的形式 如果我想有一个函数来计算给定各种输入的输出,
x
和y
,那么我可以这样做
def f(x,y):
# For example...
return x * y
具体来说,我可以使用x
和y
的不同值调用此函数:
f(1,3) = 3
f(1,4) = 4
f(2,3) = 6
f(2,4) = 8
但是,在我的特殊情况下,我可能有一个固定值y
。所以在我的例子中,将y
作为参数传递是没有意义的。相反,我想将我的y
值烘焙到函数中,然后改变x
。为此,我可以简单地捕获y
的外部值:
y = 3
def g(x):
return x * y
现在每当我调用g
,y
的固定值为3:
g(1) = 3
g(2) = 6
类似地,如果我还知道x
是固定的,我可以捕获x
的外部值:
x = 2
def h():
return g(x)
现在,当我调用h
时,我隐式地调用h()=g(2)=f(2,3)
这很好,但问题是每次我调用h
,它都会重复乘法,因为它相当于调用f(2,3)
。因此,为了提高性能,我可以对表达式求值,然后使用一个只返回此预计算值的函数:
val = h()
def h23():
return val
无论我调用了多少次h23
,乘法只执行一次(在val=h()
行上)
Tensorflow有类似的概念
如果您想拥有一个可以改变两个输入的函数,则应为两个实例创建占位符对象,并在会话中运行时将值传递给提要字典中的函数:
dtype = tf.float64
shape = ()
x = tf.placeholder( dtype, shape )
y = tf.placeholder( dtype, shape )
fxy = f(x,y)
with tf.Session() as sess:
print( sess.run( fxy, {x:1,y:3} ) )
print( sess.run( fxy, {x:1,y:4} ) )
print( sess.run( fxy, {x:2,y:3} ) )
print( sess.run( fxy, {x:2,y:4} ) )
但是,如果我的一个值没有更改,那么我可以直接将其初始化为常量,并使用该值“烘焙到其中”创建一个新函数:
关键的一点是,现在我不需要在提要字典中传递y
的值。它是常量,并在表达式gx
中捕获类似地,如果
x
也是一个常数,那么我应该这样声明:
x = tf.constant(2)
h = f(x,y)
with tf.Session() as sess:
print( sess.run( h ) )
正如您所看到的,由于我所有的变量都是常量,所以我根本不需要提要字典。这是Tensorflow,相当于调用不带参数的函数,如h()
但是,与前面一样,当我调用h
时,每次可能都需要重新计算图形。所以我有两个选择
fxy = tf.constant( f(2,3) )
现在我已经在Tensorflow之外预先计算了函数的值,然后将该值包装为常量,以便在其他Tensorflow函数中使用
相反,如果函数使用了一些复杂的张紧流内蕴,或者如果函数占用了很长时间,并且您认为在TysFoeSoT中计算机的速度会更快,则只考虑选项2:
with tf.Session() as sess:
fxy = tf.constant( sess.run( h ) )
要了解这里发生了什么,回想一下
h = f( tf.constant(1), tf.constant(3) )
因此我不需要传递提要dict。代码段sess.run(h)
在tensorflow内部运行乘法,并将其作为Numpy数组返回。最后,我用tf.constant包装该值,以便在其他Tensorflow函数中使用它 拉威尔==评估?(或该功能是否有文档记录?)
with tf.Session() as sess:
fxy = tf.constant( sess.run( h ) )
h = f( tf.constant(1), tf.constant(3) )