Я хочу внедрить циклический курс обучения, в отличие от AdamOptimizer или любой другой формы SGD, например.Итак, часть, которую я хочу представить здесь, это «Скорость циклического обучения» с функцией get_triangular_lr
.Функция показана ниже:
def get_triangular_lr(iteration, stepsize, base_lr, max_lr):
"""Given the inputs, calculates the lr that should be applicable for
this iteration"""
scale_fn = lambda x: 1/(2.**(x-1))
cycle = math.floor(1 + iteration/(2 * stepsize))
x = abs(iteration/stepsize - 2 * cycle + 1)
lr = base_lr + (max_lr - base_lr) * max(0, (1-x)) *scale_fn(cycle)
lr = tf.convert_to_tensor(lr)
return lr
Ниже показан код для использования этого в реальной модели Inception ResNet V2, моя цель - заменить tf_train_exponential_decay
на циклический LR, который сам увеличивается и уменьшаетсяскорость обучения за шаг.
iteration_step = 0 #(is increased every global_step)
lr1 = get_triangular_lr(iteration_step, stepsize, base_lr, max_lr)
#Define your exponentially decaying learning rate
# lr = tf.train.exponential_decay(
# learning_rate = initial_learning_rate,
# global_step = global_step,
# decay_steps = decay_steps,
# decay_rate = learning_rate_decay_factor,
# staircase = True)
#Now we can define the optimizer that takes on the learning rate
optimizer = tf.train.AdamOptimizer(learning_rate = lr1)
#Create the train_op.
train_op = slim.learning.create_train_op(total_loss, optimizer)
Однако, когда я запускаю приведенный выше код (запустив полную модель обучения), скорость обучения никогда не увеличивается при использовании этой функции.Он начинается только в 0.0001
, и каждый взятый global_step использует это значение, в то время как он должен увеличиваться на каждом глобальном шаге (с новым значением, рассчитанным на get_triangular_lr
. Я думаю, что требуется какой-то цикл for, но я могуне могу понять, как именно это реализовать.
#Now we need to create a training step function that runs both the
#train_op, metrics_op and updates the global_step concurrently.
def train_step(sess, train_op, global_step):
'''
Simply runs a session for the three arguments provided and gives a
logging on the time elapsed for each global step
'''
#Check the time for each sess run
start_time = time.time()
total_loss, global_step_count, _ = sess.run([train_op, global_step,
metrics_op])
time_elapsed = time.time() - start_time
#Run the logging to print some results
logging.info('global step %s: loss: %.4f (%.2f sec/step)',
global_step_count, total_loss, time_elapsed)
return total_loss, global_step_count
Когда я изменяю ввод с train_op
на total_loss, lr1
, это дает мне AttributeError: у объекта 'Tensor' нет атрибута 'compute_gradients', итаким образом, модель не работает вообще.
РЕДАКТИРОВАТЬ: еще не нашли решение, но удалось использовать py.func, но теперь возникает следующая ошибка:
Итак, я создал triangular_tf
, который использует tf.py_func
для загрузки функции, следующим образом:
triangular_tf = tf.py_func(get_triangular_lr, [iteration, stepsize, base_lr, max_lr], [tf.float64])
Единственная проблема заключается в том, когда я сейчас передаю triangular_tf
в `optimizer = tf.train.AdamOptimizer (learning_rate = triangular_tf) возникает следующая ошибка:
ValueError: cannot add op with name <my weights variable name>/Adam as that name is already used
Не уверен, нужен ли мне AdamOptimizer в этом процессе, но мне просто нужен способ настройки скорости обучения каждый разшаг.