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.        ]