我正在尝试创建一个最小的代码段来理解GradientDescentOptimizer
类,以帮助我更深入地理解tensorflow API文档。
我想为GradientDescentOptimizer
提供一些硬编码输入,运行minimize()
方法并检查输出。到目前为止,我创建了以下内容:
loss_data = tf.Variable([2.0], dtype=tf.float32)
train_data = tf.Variable([20.0], dtype=tf.float32, name='train')
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.02)
gradients = optimizer.compute_gradients(loss_data, var_list=[train_data])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(gradients))
我得到的错误是:
TypeError: Fetch argument None has invalid type <class 'NoneType'>
但是,我只是猜测输入的样子。任何指示赞赏,以帮助我理解我应该传递给这个功能。
更多背景......
我按照类似的过程来理解激活功能,通过隔离它们并将它们视为一个黑盒子,我发送一系列输入并检查相应的输出。
# I could have used a list of values but I wanted to experiment
# by passing in one parameter value at a time.
placeholder = tf.placeholder(dtype=tf.float32, shape=[1], name='placeholder')
activated = tf.nn.sigmoid(placeholder)
with tf.Session() as sess:
x_y = {}
for x in range(-10, 10):
x_y[x] = sess.run(activated, feed_dict={ placeholder: [x/1.0]})
import matplotlib.pyplot as plt
%matplotlib inline
x, y = zip(*x_y.items())
plt.plot(x, y)
上述过程对于我对激活函数的理解非常有用,我希望为优化器做类似的事情。
答案 0 :(得分:2)
您的损失不应该是变量(它不是您的模型的参数),而是操作的结果,例如
loss_data = train_data**2
目前您的损失不依赖于train_data
,这解释了为什么不能计算梯度。
答案 1 :(得分:1)
见this discussion on GitHub。基本上,tf.compute_gradients
为所有与其输入无关的变量返回None
的渐变,session.run
如果获得None
值则会引发此错误。简单的解决方法;只告诉它与你传递的损失函数相关的变量:
gradients = optimizer.compute_gradients(loss_data, var_list=[loss_data])
现在当你跑:
print(sess.run(gradients))
# [(gradient, input)]
# [(array([1.], dtype=float32), array([2.], dtype=float32))]
哪个有道理。您正在计算x
相对于x
的渐变,该渐变始终为1.
对于更具说明性的内容,让我们定义一个用输入变量更改的loss
op:
x = tf.Variable([1], dtype=tf.float32, name='input_x')
loss = tf.abs(x)
您的优化程序定义相同,但您的gradient
操作系统现在已根据此loss
操作计算:
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.02)
gradients = optimizer.compute_gradients(loss, [x])
最后,我们可以在具有不同输入的循环中运行它,并查看渐变如何变化:
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(-3, 3):
grad = sess.run(gradients, feed_dict={x: (i,)})
print(grad)
# [(gradient, input)]
# [(array([-1.], dtype=float32), array([-3.], dtype=float32))]
# [(array([-1.], dtype=float32), array([-2.], dtype=float32))]
# [(array([-1.], dtype=float32), array([-1.], dtype=float32))]
# [(array([0.], dtype=float32), array([0.], dtype=float32))]
# [(array([1.], dtype=float32), array([1.], dtype=float32))]
# [(array([1.], dtype=float32), array([2.], dtype=float32))]
如果loss = -x
为负数,则为x
;如果loss = +x
为正数,则为x
,因此对于负数,d_loss/d_x
为-1 ,+为正数,如果输入为零则为零。