Как использовать несколько экземпляров графа тензорного потока из класса, который создает граф тензорного потока? - PullRequest
0 голосов
/ 07 ноября 2019

Я использую глубокое подкрепление обучения с двумя классами, а именно:
1. DeepQNetwork
2. Agent

Характеристика класса DeepQNetwork:
1. Он имеетсвой собственный tf.Session
2. У него есть метод, который строит граф TensorFlow со своим собственным заполнителем и функцией оптимизации.

Характеристика класса Agent:
1. Внутри класса Agent два DeepQNetwork создаются с использованием вышеуказанного класса, один q_eval (Основная сеть) и другие q_next (Цельсеть).
2. Agent также имеет метод загрузки, который загружает предварительно обученную сеть q_eval.

Я хочу создать несколько агентов, каждый из которых имеет сеть q_eval и q_next, и выполнить операцию.

class DeepQNetwork(object):

    def __init__(self, lr, n_actions, name, fc1_dims=512, LSTM_DIM=256,
                 input_dims=(210, 160, 4), chkpt_dir="tmp/dqn"):
        config = tf.ConfigProto()
        ....
        self.sess = tf.Session(config=config)
        self.build_network()

    def build_network(self):

        with tf.variable_scope(self.name):
            self.states = tf.placeholder(tf.float32, shape=[None, *self.input_dims],
                                        name='states') 
            self.actions = tf.placeholder(tf.float32, shape=[None, self.n_actions],
                                          name='action_taken')
            self.q_target = tf.placeholder(tf.float32, shape=[None],
                                           name='q_value')
            self.seq_len = tf.placeholder(tf.int32, name='sequence_length')
            self.batch_size = tf.placeholder(tf.int32, name='batch_size')

            # Create placeholders to input the hidden state values
            c_in = tf.placeholder(tf.float32, [None, self.LSTM_DIM], name='cell_state')
            h_in = tf.placeholder(tf.float32, [None, self.LSTM_DIM], name='h_state')
            self.state_in = tf.nn.rnn_cell.LSTMStateTuple(c_in, h_in)

            #self._reward = tf.placeholder(tf.float32, shape=[], name='Reward/Time_step')
            #self.reward_sum = tf.summary.scalar('Reward/Time_step', self._reward)

            #self._waitingtime = tf.placeholder(tf.float32, shape=[], name='TotalWaitingTime/Time_step')
            #self.waitingtime_sum = tf.summary.scalar('TotalWaitingTime/Time_step', self._waitingtime)

            #self._delay = tf.placeholder(tf.float32, shape=[], name='TotalDelay/Time_step')
            #self.delay_sum = tf.summary.scalar('TotalDelay/Time_step', self._delay)

            conv1 = tf.layers.conv2d(inputs=self.states, filters=16,
                                     kernel_size=(8, 8), strides=(4,4), name='conv1', padding='VALID',
                                     kernel_initializer=tf.contrib.layers.variance_scaling_initializer(factor=2),use_bias=True, bias_initializer=tf.constant_initializer(0.1))

            conv1_activated = tf.nn.relu(conv1)

            conv2 = tf.layers.conv2d(inputs=conv1_activated, filters=32,
                                     kernel_size=(4, 4), strides=(2,2), name='conv2', padding='VALID',
                                     kernel_initializer=tf.contrib.layers.variance_scaling_initializer(factor=2), use_bias=True, bias_initializer=tf.constant_initializer(0.1))


            conv2_activated = tf.nn.relu(conv2)

            #conv3 = tf.layers.conv2d(inputs=conv2_activated, filters=64,
            #                         kernel_size=(3, 3), strides=1, name='conv3',
                                     #kernel_initializer=tf.contrib.layers.variance_scaling_initializer(factor=2))
            #conv3_activated = tf.nn.relu(conv3)

            n_input = conv2_activated.get_shape().as_list()[1]*conv2_activated.get_shape().as_list()[2]*conv2_activated.get_shape().as_list()[3]

            conv2_activated = tf.reshape(conv2_activated, [-1, n_input])

            conv2_activated = tf.reshape(conv2_activated, [self.batch_size, self.seq_len, n_input])

            lstm_cell = tf.nn.rnn_cell.LSTMCell(self.LSTM_DIM, initializer=tf.contrib.layers.xavier_initializer())
            outputs, self.cell_state = tf.nn.dynamic_rnn(lstm_cell, conv2_activated, initial_state=self.state_in, dtype=tf.float32, sequence_length=self.seq_len)

            var1 = tf.get_variable('weights', (self.LSTM_DIM, self.n_actions), initializer=tf.contrib.layers.xavier_initializer(), trainable=True, 
                                                    regularizer=tf.contrib.layers.l2_regularizer(0.01))
            var2 = tf.get_variable('biases', (self.n_actions,), trainable=True, initializer=tf.constant_initializer(0.1))

            h = outputs[:,-1,:] 

            self.Q_values = tf.matmul(h, var1) + var2
            tf.summary.histogram('Q_value', self.Q_values)

            self.q = tf.reduce_sum(tf.multiply(self.Q_values, self.actions), axis=1)

            self.loss = tf.reduce_mean(tf.square(self.q_target - self.q))

            self.loss_sum = tf.summary.scalar("Loss", self.loss)

            self.train_op = tf.train.AdamOptimizer(self.lr).minimize(self.loss)

            if self.name == 'q_eval':
                for var in tf.trainable_variables():
                    c = var.name[:-2]
                    with tf.name_scope(c):
                        self.variable_summaries(var)


class Agent(object):

    def __init__(self, alpha, gamma, mem_size, epsilon, batch_size, num_agents, act_per_agent, replace_target=3000, input_dims=(210, 160,4), q_next_dir="tmp/q_next", q_eval_dir="tmp/q_eval", test= False):
    ...
    ...
        self.q_eval = DeepQNetwork(alpha, self.n_actions, input_dims=input_dims,
                                   name='q_eval', chkpt_dir=q_eval_dir)

        self.q_next = DeepQNetwork(alpha, self.n_actions, input_dims=input_dims,
                                   #name='q_next', chkpt_dir=q_next_dir)

Для каждого из этих агентов я хочу загрузить предварительно обученную модель для сети q_eval, но эти веса и смещения q_evals будут различаться в зависимости от модели, которую я использую для их загрузки.

Я не уверен, что в рамках DeepQNetwork я должен использовать reuse=True или нет. Боюсь, что если я воспользуюсь этим, все они будут иметь одинаковый вес, который я, конечно, не хочу.

...