Как сделать избирательное обратное распространение в мини-партии в Tensorflow?

Недавно я работаю над проектом "Предсказание будущих траекторий объектов по их прошлым траекториям с использованием LSTM в Tensorflow". (Здесь траектория означает последовательность двухмерных позиций.)

Вход в LSTM - это, конечно, "прошлые траектории", а выход - "будущие траектории".

Размер мини-партии фиксируется при обучении. Однако количество прошедших траекторий в мини-партии может быть разным. Например, пусть размер мини-партии равен 10. Если у меня есть только 4 прошлых траектории для текущей итерации обучения, 6 из 10 в мини-партии дополняются нулевым значением.

При расчете потерь для обратного распространения я допускаю, что потери от 6 равны нулю, так что только 4 способствуют обратному распространению.

Проблема, с которой я сталкиваюсь, заключается в том, что Tensorflow все еще вычисляет градиенты для 6, даже если их потеря равна нулю. В результате скорость обучения становится меньше, когда я увеличиваю размер мини-партии, даже если я использую те же данные тренировки.

Я также использовал функцию tf.where при расчете потерь. Однако время тренировки не уменьшается.

Как я могу сократить время обучения?

Здесь я приложил свой псевдокод для обучения.

# For each frame in a sequence
for f in range(pred_length):

    # For each element in a batch
    for b in range(batch_size):


        with tf.variable_scope("rnnlm") as scope:
            if (f > 0 or b > 0):
                scope.reuse_variables()

            # for each pedestrian in an element
            for p in range(MNP):

                # ground-truth position
                cur_gt_pose = ...

                # loss mask
                loss_mask_ped = ... # '1' or '0'

                # go through RNN decoder
                output_states_dec_list[b][p], zero_states_dec_list[b][p] = cell_dec(cur_embed_frm_dec,
                                                                                    zero_states_dec_list[b][p])

                # fully connected layer for output
                cur_pred_pose_dec = tf.nn.xw_plus_b(output_states_dec_list[b][p], output_wd, output_bd)

                # go through embedding function for the next input
                prev_embed_frms_dec_list[b][p] = tf.reshape(tf.nn.relu(tf.nn.xw_plus_b(cur_pred_pose_dec, embedding_wd, embedding_bd)), shape=(1, rnn_size))

                # calculate MSE loss
                mse_loss = tf.reduce_sum(tf.pow(tf.subtract(cur_pred_pose_dec, cur_gt_pose_dec), 2.0))

                # only valid ped's traj contributes to the loss
                self.loss += tf.multiply(mse_loss, loss_mask_ped)

1 ответ

Я думаю, что вы ищете функцию tf.stop_gradient. Используя это, вы можете сделать что-то вроде tf.where(loss_mask, tensor, tf.stop_gradient(tensor)) для достижения желаемого результата, при условии, что размеры правильные.

Тем не менее, похоже, что это не ваша проблема. Кажется, что для каждого элемента в вашем наборе данных вы определяете новые узлы графа. Это не то, как TensorFlow должен функционировать, у вас должен быть только один график, построенный заранее, который выполняет некоторую фиксированную функцию, независимо от размера пакета. Определенно не следует определять новые узлы для каждого элемента в пакете, поскольку это не может эффективно использовать преимущества параллелизма.

Другие вопросы по тегам