Свернуть функцию в 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
Другие вопросы по тегам