问题
我应该如何“告诉” tf 某个成本函数源自 NN?
(简短)回答
这可以通过简单地配置优化器来最小化(或最大化)张量来完成。例如,如果我有这样的损失函数
loss = tf.reduce_sum( tf.square( y0 - y_out ) )
其中 y0 是 ground truth(或期望的输出),y_out 是计算的输出,然后我可以通过像这样定义我的训练函数来最小化损失
train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
这告诉Tensorflow,在计算train时,是对loss应用梯度下降来最小化它,而loss是使用y0和y_out计算的,所以梯度下降也会影响那些(如果它们是可训练的变量)等等。
变量 y0、y_out、loss 和 train 不是标准的 Python 变量,而是描述计算图。 Tensorflow 在应用梯度下降时使用有关该计算图的信息来展开它。
具体如何做到这一点超出了这个答案的范围。 Here 和 here 是了解更多细节的两个很好的起点。
代码示例
让我们来看一个代码示例。首先是代码。
### imports
import tensorflow as tf
### constant data
x = [[0.,0.],[1.,1.],[1.,0.],[0.,1.]]
y_ = [[0.],[0.],[1.],[1.]]
### induction
# 1x2 input -> 2x3 hidden sigmoid -> 3x1 sigmoid output
# Layer 0 = the x2 inputs
x0 = tf.constant( x , dtype=tf.float32 )
y0 = tf.constant( y_ , dtype=tf.float32 )
# Layer 1 = the 2x3 hidden sigmoid
m1 = tf.Variable( tf.random_uniform( [2,3] , minval=0.1 , maxval=0.9 , dtype=tf.float32 ))
b1 = tf.Variable( tf.random_uniform( [3] , minval=0.1 , maxval=0.9 , dtype=tf.float32 ))
h1 = tf.sigmoid( tf.matmul( x0,m1 ) + b1 )
# Layer 2 = the 3x1 sigmoid output
m2 = tf.Variable( tf.random_uniform( [3,1] , minval=0.1 , maxval=0.9 , dtype=tf.float32 ))
b2 = tf.Variable( tf.random_uniform( [1] , minval=0.1 , maxval=0.9 , dtype=tf.float32 ))
y_out = tf.sigmoid( tf.matmul( h1,m2 ) + b2 )
### loss
# loss : sum of the squares of y0 - y_out
loss = tf.reduce_sum( tf.square( y0 - y_out ) )
# training step : gradient decent (1.0) to minimize loss
train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
### training
# run 500 times using all the X and Y
# print out the loss and any other interesting info
with tf.Session() as sess:
sess.run( tf.global_variables_initializer() )
for step in range(500) :
sess.run(train)
results = sess.run([m1,b1,m2,b2,y_out,loss])
labels = "m1,b1,m2,b2,y_out,loss".split(",")
for label,result in zip(*(labels,results)) :
print ""
print label
print result
print ""
让我们来看看它,但是以相反的顺序开始
sess.run(train)
这告诉 tensorflow 查找由 train 定义的图节点并计算它。 火车定义为
train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
要计算这个张量流必须计算loss的自动微分,这意味着走图。 损失定义为
loss = tf.reduce_sum( tf.square( y0 - y_out ) )
真正的 tensorflow 应用 自动微分 首先展开 tf.reduce_sum,然后是 tf.square,然后是 y0 - y_out ,这导致必须同时遍历 y0 和 y_out 的图形。
y0 = tf.constant( y_ , dtype=tf.float32 )
y0 是一个常数,不会被更新。
y_out = tf.sigmoid( tf.matmul( h1,m2 ) + b2 )
y_out会像loss一样被处理,首先tf.sigmoid会被处理,以此类推……
总而言之,每个操作(例如 tf.sigmoid、tf.square )不仅定义了前向操作(应用 sigmoid 或 square ),还定义了自动微分所需的信息。这与标准 python 数学不同,例如
x = 7 + 9
上面的等式除了如何更新 x 之外什么都不编码,其中为
z = y0 - y_out
对从 y0 减去 y_out 的图形进行编码,并将前向运算和足以在 z
中进行
自动微分的操作存储起来