Ответ 1
Вы можете фильтровать переменные по имени и только инициализировать их. IE
momentum_initializers = [var.initializer for var in tf.global_variables() if 'Momentum' in var.name]
sess.run(momentum_initializers)
Я хочу использовать MomentumOptimizer
в Tensorflow. Однако, поскольку этот оптимизатор использует некоторую внутреннюю переменную, попытка использовать ее без инициализации этой переменной дает ошибку:
FailedPreconditionError (see above for traceback): Attempting to use
uninitialized value Variable_2/Momentum
Это легко решить путем инициализации всех переменных, например:
tf.global_variables_initializer().run()
Тем не менее, я не хочу инициализировать переменные all только для оптимизатора. Есть ли способ сделать это?
Вы можете фильтровать переменные по имени и только инициализировать их. IE
momentum_initializers = [var.initializer for var in tf.global_variables() if 'Momentum' in var.name]
sess.run(momentum_initializers)
Оба текущих ответа выполняют свою работу путем фильтрации имени переменной с использованием строки "Momentum". Но это очень хрупкое с двух сторон:
К счастью, у абстрактного Optimizer
класса tensorflow есть механизм для этого, эти дополнительные переменные оптимизатора называются "слоты" , и вы можете получить все имена слотов оптимизатора, используя метод get_slot_names()
:
opt = tf.train.MomentumOptimizer(...)
print(opt.get_slot_names())
# prints ['momentum']
И вы можете получить переменную, соответствующую слоту для конкретной (обучаемой) переменной v
, используя метод get_slot(var, slot_name)
:
opt.get_slot(some_var, 'momentum')
Объединяя все это вместе, вы можете создать оп, который инициализирует состояние оптимизатора следующим образом:
var_list = # list of vars to optimize, e.g.
# tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)
opt = tf.train.MomentumOptimizer(0.1, 0.95)
step_op = opt.minimize(loss, var_list=var_list)
reset_opt_op = tf.variables_initializer([opt.get_slot(var, name) for name in opt.get_slot_names() for var in var_list])
Это действительно будет только reset правильными переменными и будет надежным для оптимизаторов.
За исключением одного несчастливое предостережение: AdamOptimizer
. Это также поддерживает счетчик того, как часто он был вызван. Это означает, что вы должны действительно серьезно думать о том, что вы здесь делаете, но для полноты вы можете получить дополнительные состояния как opt._get_beta_accumulators()
. Возвращенный список должен быть добавлен в список в приведенной выше строке reset_opt_op
.
tf.variables_initializer
кажется предпочтительным способом инициализации определенного набора переменных:
var_list = [var for var in tf.global_variables() if 'Momentum' in var.name]
var_list_init = tf.variables_initializer(var_list)
...
sess = tf.Session()
sess.run(var_list_init)
Построение ответа LucasB на AdamOptimizer
, эта функция принимает экземпляр AdamOptimizer
adam_opt
, который имеет свой Variables
, созданный (один из этих двух вызываемых: adam_opt.minimize(loss, var_list=var_list)
или adam_opt.apply_gradients(zip(grads, var_list))
. Op
, который при вызове повторно инициализирует переменные оптимизатора для переданной переменной, а также глобальное состояние подсчета.
def adam_variables_initializer(adam_opt, var_list):
adam_vars = [adam_opt.get_slot(var, name)
for name in adam_opt.get_slot_names()
for var in var_list if var is not None]
adam_vars.extend(list(adam_opt._get_beta_accumulators()))
return tf.variables_initializer(adam_vars)
например:.
opt = tf.train.AdamOptimizer(learning_rate=1e-4)
fit_op = opt.minimize(loss, var_list=var_list)
reset_opt_vars = adam_variables_initializer(opt, var_list)
Чтобы устранить проблему "Нет", просто выполните:
self.opt_vars = [opt.get_slot(var, name) for name in opt.get_slot_names()
for var in self.vars_to_train
if opt.get_slot(var, name) is not None]