Tensorflow - Уменьшить издержки session.run () - PullRequest
1 голос
/ 17 апреля 2019

В настоящее время я программирую небольшой учебный проект по подкреплению с tenorflow. Когда я профилировал тренировочный прогон, я заметил, что более 65% времени выполнения требуется только для выборки действий.

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

Я запускаю этот график на графическом процессоре, поэтому я подозреваю, что издержки, связанные с вызовом метода session.run () и, следовательно, копированием данных из ОЗУ в графический процессор каждый раз, вызывают такие издержки.

Мой вопрос таков: есть ли способ уменьшить накладные расходы, связанные с вызовом метода session.run () столько раз? Можно ли запустить sample_op (прямой проход) на CPU и запустить обучение на GPU?

Заранее большое спасибо!

Это код моей политики RL:

class Policy:
def __init__(self, sess, state_size, action_size, lr, alpha_entropy,  epsilon):
    self.sess = sess
    self.action_size = action_size
    with tf.device("/cpu:0"):
        with tf.variable_scope("Policy"):
            self.state_ph = tf.placeholder(tf.float32, [None, state_size], name="state_ph")
            self.action_ph = tf.placeholder(tf.float32, [None, action_size], name="action_ph")
            self.advantage_ph = tf.placeholder(tf.float32, [None, 1], name="action_ph")

            with tf.variable_scope("pi"):
                self.pi, self.mean_action = self._create_model(trainable=True)
                self.pi_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope="Policy/pi")

                self.sample_op = self.pi.sample()

            with tf.variable_scope("old_pi"):
                self.old_pi, _ = self._create_model(trainable=False)
                self.old_pi_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope="Policy/old_pi")

            with tf.variable_scope("loss"):
                prob_ratio = self.pi.prob(self.action_ph) / self.old_pi.prob(self.action_ph)
                surrogate = prob_ratio * self.advantage_ph

                clipped_surrogate = tf.minimum(surrogate,  tf.clip_by_value(prob_ratio, 1.-epsilon, 1.+epsilon)*self.advantage_ph)

                self.pi_entropy = self.pi.entropy()

                tf.summary.scalar("entropy", tf.reduce_mean(self.pi_entropy))

                self.loss = -tf.reduce_mean(clipped_surrogate + alpha_entropy * self.pi_entropy)

                tf.summary.scalar("objective", self.loss)

            with tf.variable_scope("training"):
                self.gradients = tf.gradients(self.loss, self.pi_vars)
                #self.gradients = [tf.clip_by_value(g, -1000, 1000) for g in self.gradients]
                #self.gradients, _ = tf.clip_by_global_norm(self.gradients, GRADIENT_NORM)
                grads = zip(self.gradients, self.pi_vars)
                self.optimize = tf.train.AdamOptimizer(lr).apply_gradients(grads)

                [tf.summary.histogram(v.name, g) for g, v in grads]

            with tf.variable_scope("update_old_policy"):
                self.update_oldpi_op = [oldp.assign(p) for p, oldp in zip(self.pi_vars, self.old_pi_vars)]

            self.summary_op = tf.summary.merge_all(scope="Policy")

def _create_model(self, trainable):
    layer_names = ["l1", "l2", "l3", "l4"]

    l1 = tf.layers.Dense(32, activation="relu", name=layer_names[0], trainable=trainable, kernel_initializer = tf.initializers.he_normal(),)(self.state_ph)
    l2 = tf.layers.Dense(64, activation="relu", name=layer_names[1], trainable=trainable, kernel_initializer = tf.initializers.he_normal(),)(l1)
    l3 = tf.layers.Dense(32, activation="relu", name=layer_names[2], trainable=trainable, activity_regularizer= tf.contrib.layers.l2_regularizer(scale=0.001),kernel_initializer = tf.initializers.he_normal(),)(l2)
    mu = tf.layers.Dense(self.action_size, activation="tanh", name=layer_names[3], trainable=trainable, kernel_initializer = tf.initializers.he_normal(),)(l3)

    log_sigma = tf.Variable(initial_value=tf.fill((self.action_size,), 0.), trainable=trainable)

    distribution = tfp.distributions.MultivariateNormalDiag(loc=mu, scale_diag=tf.exp(log_sigma))

    tf.summary.histogram("log_sigma", log_sigma)
    tf.summary.histogram("mu", mu)

    for name in layer_names:
        with tf.variable_scope(name, reuse=True):
            tf.summary.histogram("kernel", tf.get_variable("kernel"))
            tf.summary.histogram("bias", tf.get_variable("bias"))

    return distribution, mu

def sample_action(self, state):
    return self.sess.run([self.mean_action, self.sample_op], feed_dict={
        self.state_ph: state
    })

def train(self, states, actions, advantages):
    _, summaries =self.sess.run([self.optimize, self.summary_op], feed_dict={
        self.state_ph:states,
        self.action_ph: actions,
        self.advantage_ph: advantages
    })
    return summaries

def update_old_pi(self):
    self.sess.run([self.update_oldpi_op])

Результат профилирования:

enter image description here

...