Свернуть функцию в Tensorflow
Как я могу получить градиенты функции, используя tf.gradients? ниже работает, когда я использую GradientDescentOptimizer.minimize(), tf.gradients, кажется, оценивает 1 в производной от x^2+2, что 2x
Что мне не хватает?
x = tf.Variable(1.0, trainable=True)
y = x**2 + 2
grad = tf.gradients(y, x)
#grad = tf.train.GradientDescentOptimizer(0.1).minimize(y)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
grad_value = sess.run(grad)
print(grad_value)
1 ответ
Если я правильно понимаю ваш вопрос, вы хотите найти значение x
который сводит к минимуму x^2 + 2
,
Для этого нужно повторно позвонить GradientDescentOptimizer
до тех пор x
сходится к значению, которое минимизирует функцию. Это потому, что градиентный спуск является итеративной техникой.
Также в тензорном потоке метод minimize
из GradientDescentOptimizer
выполняет оба вычисления градиентов и затем применяет их к соответствующим переменным (x
в твоем случае). Таким образом, код должен выглядеть следующим образом (обратите внимание, я прокомментировал grad
переменная, которая не требуется, если вы не хотите смотреть на значения градиента):
x = tf.Variable(1.0, trainable=True)
y = x**2 + 2
# grad = tf.gradients(y, x)
grad_op = tf.train.GradientDescentOptimizer(0.2).minimize(y)
init = tf.global_variables_initializer()
n_iterations = 10
with tf.Session() as sess:
sess.run(init)
for i in range(n_iterations):
_, new_x = sess.run([grad_op, x])
print('Iteration:', i,', x:', new_x)
и вы получите:
Iteration: 0 , x: 1.0
Iteration: 1 , x: 0.6
Iteration: 2 , x: 0.36
Iteration: 3 , x: 0.216
Iteration: 4 , x: 0.07776
Iteration: 5 , x: 0.07776
Iteration: 6 , x: 0.046656
Iteration: 7 , x: 0.01679616
Iteration: 8 , x: 0.010077696
Iteration: 9 , x: 0.010077696
который вы видите в сходящемся к истинному ответу, который равен 0.
Если вы увеличите скорость обучения GradientDescentOptimizer
от 0,2 до 0,4 он будет сходиться к 0 гораздо быстрее.
РЕДАКТИРОВАТЬ
Хорошо, исходя из моего нового понимания вопроса, чтобы вручную реализовать градиентный спуск, вы не можете сделать x = x - alpha * gradient
потому что это операция Python, которая просто заменяет объект x
, Вы должны указать tenorflow добавить оп к графику, и это можно сделать, используя x.assign
, Это будет выглядеть так:
x = tf.Variable(1.0, trainable=True)
y = x**2 + 2
grad = tf.gradients(y, x)
# grad_op = tf.train.GradientDescentOptimizer(0.5).minimize(y)
update_op = x.assign(x - 0.2*grad[0])
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for i in range(10):
new_x = sess.run([update_op, x])
print('Iteration:', i,', x:', new_x)
и мы получаем тот же ответ, что и родной GradientDescentOptimizer
:
Iteration: 0 , x: 1.0
Iteration: 1 , x: 0.6
Iteration: 2 , x: 0.36
Iteration: 3 , x: 0.1296
Iteration: 4 , x: 0.1296
Iteration: 5 , x: 0.077759996
Iteration: 6 , x: 0.046655998
Iteration: 7 , x: 0.027993599
Iteration: 8 , x: 0.01679616
Iteration: 9 , x: 0.010077696