TensorFlow минимизирует только некоторые элементы переменной
можно ли минимизировать функцию потерь, меняя только некоторые элементы переменной? Другими словами, если у меня есть переменная X
длины 2, как я могу минимизировать функцию потери, изменив X[0]
и держа X[1]
постоянный?
надеюсь, этот код, который я попытался, опишет мою проблему:
import tensorflow as tf
import tensorflow.contrib.opt as opt
X = tf.Variable([1.0, 2.0])
X0 = tf.Variable([3.0])
Y = tf.constant([2.0, -3.0])
scatter = tf.scatter_update(X, [0], X0)
with tf.control_dependencies([scatter]):
loss = tf.reduce_sum(tf.squared_difference(X, Y))
opt = opt.ScipyOptimizerInterface(loss, [X0])
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
opt.minimize(sess)
print("X: {}".format(X.eval()))
print("X0: {}".format(X0.eval()))
выходы:
INFO:tensorflow:Optimization terminated with:
Message: b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
Objective function value: 26.000000
Number of iterations: 0
Number of functions evaluations: 1
X: [3. 2.]
X0: [3.]
где я хотел бы найти оптимальное значение X0 = 2
и таким образом X = [2, 2]
редактировать
мотивация для этого: я хотел бы импортировать обученный график / модель, а затем настроить различные элементы некоторых переменных в зависимости от некоторых новых данных, которые у меня есть.
3 ответов
вы можете использовать этот трюк, чтобы ограничить расчет градиента одним индексом:
import tensorflow as tf
import tensorflow.contrib.opt as opt
X = tf.Variable([1.0, 2.0])
part_X = tf.scatter_nd([[0]], [X[0]], [2])
X_2 = part_X + tf.stop_gradient(-part_X + X)
Y = tf.constant([2.0, -3.0])
loss = tf.reduce_sum(tf.squared_difference(X_2, Y))
opt = opt.ScipyOptimizerInterface(loss, [X])
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
opt.minimize(sess)
print("X: {}".format(X.eval()))
part_X
становится значением, которое вы хотите изменить в одном горячем векторе той же формы, что и X. part_X + tf.stop_gradient(-part_X + X)
совпадает с X в прямом проходе, так как part_X - part_X
- Это 0. Однако в обратном проходе tf.stop_gradient
предотвращает все ненужные вычисления градиента.
это должно быть довольно легко сделать с помощью .
trainable_var = X[0]
train_op = tf.train.GradientDescentOptimizer(learning_rate=1e-3).minimize(loss, var_list=[trainable_var])
вы должны отметить, что по соглашению все обучаемые переменные добавляются в коллекцию tensorflow по умолчанию GraphKeys.TRAINABLE_VARIABLES
, поэтому вы можете получить список всех обучаемых переменных, используя:
all_trainable_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)
это всего лишь список переменных, которыми вы можете манипулировать по своему усмотрению и использовать в качестве
Я не уверен, что это возможно с интерфейсом оптимизатора SciPy, но с помощью одного из обычных tf.train.Optimizer
подклассов вы можете сделать что-то подобное, называя compute_gradients
сначала, затем маскировка градиентов, а затем вызов apply_gradients
,
вместо вызова minimize
(который, как говорят документы, в основном называет предыдущие).
import tensorflow as tf
X = tf.Variable([3.0, 2.0])
# Select updatable parameters
X_mask = tf.constant([True, False], dtype=tf.bool)
Y = tf.constant([2.0, -3.0])
loss = tf.reduce_sum(tf.squared_difference(X, Y))
opt = tf.train.GradientDescentOptimizer(learning_rate=0.1)
# Get gradients and mask them
((X_grad, _),) = opt.compute_gradients(loss, var_list=[X])
X_grad_masked = X_grad * tf.cast(X_mask, dtype=X_grad.dtype)
# Apply masked gradients
train_step = opt.apply_gradients([(X_grad_masked, X)])
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for i in range(10):
_, X_val = sess.run([train_step, X])
print("Step {}: X = {}".format(i, X_val))
print("Final X = {}".format(X.eval()))
выход:
Step 0: X = [ 2.79999995 2. ]
Step 1: X = [ 2.63999987 2. ]
Step 2: X = [ 2.51199985 2. ]
Step 3: X = [ 2.40959978 2. ]
Step 4: X = [ 2.32767987 2. ]
Step 5: X = [ 2.26214385 2. ]
Step 6: X = [ 2.20971513 2. ]
Step 7: X = [ 2.16777205 2. ]
Step 8: X = [ 2.13421774 2. ]
Step 9: X = [ 2.10737419 2. ]
Final X = [ 2.10737419 2. ]