На этом шаге мы рассмотрим особенности использования GradientTape.
Пока что TensorFlow кажется очень похожим на NumPy. Но вот кое-что, чего NumPy не умеет делать: вычисление градиента любого дифференцируемого выражения по отношению к любому из его входов. Просто откройте контекст GradientTape, примените некоторые вычисления к одному или нескольким входным тензорам - и получите градиент результата относительно входов.
input_var = tf.Variable(initial_value=3.) with tf.GradientTape() as tape: result = tf.square(input_var) gradient = tape.gradient(result, input_var)
Этот прием чаще всего используется для получения градиентов потерь модели относительно ее весов:
gradient = tape.gradient(loss, weights) .
До сих пор мы рассматривали только случай, когда входными тензорами в tape.gradient() были переменные TensorFlow. Входные данные могут быть представлены любым тензором, но по умолчанию отслеживаются только обучаемые переменные. Чтобы задействовать тензор-константу, придется вручную отметить его как отслеживаемый вызовом tape.watch().
input_const = tf.constant(3.) with tf.GradientTape() as tape: tape.watch(input_const) result = tf.square(input_const) gradient = tape.gradient(result, input_const)
Почему так? Потому что было бы слишком дорого хранить информацию, необходимую для вычисления градиента чего-либо по отношению к чему-либо. Чтобы не тратить ресурсы впустую, объект GradientTape должен знать, за чем наблюдать. Обычно GradientTape используется для вычисления градиента потерь относительно списка обучаемых переменных, так что по умолчанию наблюдение ведется именно за обучаемыми переменными.
GradientTape - мощный объект, способный даже вычислять градиенты второго порядка, то есть градиенты градиентов. Например, градиент положения объекта относительно времени - это скорость объекта, а градиент второго порядка - его ускорение.
Если измерить положение падающего яблока вдоль вертикальной оси с течением времени и обнаружить, что результаты соответствуют формуле
position(time) = 4.9 * time ** 2 ,
time = tf.Variable(0.) with tf.GradientTape() as outer_tape: with tf.GradientTape() as inner_tape: position = 4.9 * time ** 2 speed = inner_tape.gradient(position, time) acceleration = outer_tape.gradient(speed, time) # Мы использовали внешний объект GradientTape # для вычисления градиента из градиента внутреннего объекта GradientTape. # Естественно, результат получился равным 4.9 * 2 = 9.8
На следующем шаге мы начнем создавать линейный классификатор на TensorFlow.