Минимизация базовых функций и отслеживание переменных в TensorFlow 2.0

Я пытаюсь выполнить самую простую минимизацию функций, возможную в TensorFlow 2.0, точно так же, как в вопросе Tensorflow 2.0: минимизировать простую функцию, однако я не могу заставить описанное там решение работать. Вот моя попытка, в основном скопированная, но с некоторыми добавленными битами, которые, похоже, отсутствуют.

import tensorflow as tf

x = tf.Variable(2, name='x', trainable=True, dtype=tf.float32)
with tf.GradientTape() as t:
    y = tf.math.square(x)

# Is the tape that computes the gradients!
trainable_variables = [x]

#### Option 2
# To use minimize you have to define your loss computation as a funcction
def compute_loss():
    y = tf.math.square(x)
    return y

opt = tf.optimizers.Adam(learning_rate=0.001)
train = opt.minimize(compute_loss, var_list=trainable_variables)

print("x:", x)
print("y:", y)

Выход:

x: <tf.Variable 'x:0' shape=() dtype=float32, numpy=1.999>
y: tf.Tensor(4.0, shape=(), dtype=float32)

Итак, он говорит, что минимум равен x=1.999, но, очевидно, это неверно. Так что случилось? Я полагаю, он выполнил только один цикл минимизатора или что-то в этом роде? Если это так, то «минимизировать» кажется ужасным названием для функции. Как это должно работать?

Кстати, мне также нужно знать значения промежуточных переменных, которые вычисляются в функции потерь (в примере есть только y, но представьте, что для вычисления y потребовалось несколько шагов, и мне нужны все эти числа). Я тоже не думаю, что правильно использую градиентную ленту, для меня не очевидно, что она имеет какое-либо отношение к вычислениям в функции потерь (я просто скопировал это из другого вопроса).


person Ben Farmer    schedule 30.04.2019    source источник


Ответы (1)


Вам нужно вызывать minimize несколько раз, потому что minimize выполняет только один шаг вашей оптимизации.

Следующее должно работать

import tensorflow as tf

x = tf.Variable(2, name='x', trainable=True, dtype=tf.float32)

# Is the tape that computes the gradients!
trainable_variables = [x]

# To use minimize you have to define your loss computation as a funcction
class Model():
    def __init__(self):
        self.y = 0

    def compute_loss(self):
        self.y = tf.math.square(x)
        return self.y

opt = tf.optimizers.Adam(learning_rate=0.01)
model = Model()
for i in range(1000):
    train = opt.minimize(model.compute_loss, var_list=trainable_variables)

print("x:", x)
print("y:", model.y)

person Sparky05    schedule 30.04.2019
comment
Хорошо, я могу заставить это работать, если я увеличу скорость обучения, но тогда я получаю NameError: имя 'y' не определено. - person Ben Farmer; 30.04.2019
comment
Изменил свой код, чтобы отразить, что я явно не храню y. Теперь должно работать. - person Sparky05; 30.04.2019
comment
Хорошо, это работает именно для этого случая, но в целом мне действительно нужны значения, вычисленные в функции потерь, а не только конечный результат. Как мне сохранить эти значения? - person Ben Farmer; 30.04.2019
comment
Вы можете использовать глобальные переменные для хранения ваших значений, или я бы предпочел инкапсулировать функцию потерь в классе, а затем вы можете получить доступ к атрибутам с помощью ссылки на себя. - person Sparky05; 30.04.2019