Получить вес графика из другого процесса - PullRequest
0 голосов
/ 21 октября 2019

Я создаю несколько копий мастер-модели, каждая в отдельном процессе, чтобы получить градиенты каждого отдельно и применить их все к мастер-модели в целом. (Сейчас я тестирую его только с одним дочерним процессом (рабочий):

num_workers = 1
    master = ACNetwork()  # Creates the network
    envs = [gym.make('CartPole-v0') for i in range(num_workers)] 
    # the environment that gives me data to train on
    workers = [Worker(number=i, environment=envs[i], master_network=master,
                      counter=counter) for i in range(num_workers)]
    for worker in workers:
        worker.start()

Моя проблема заключается в том, что я создаю основную модель в родительском процессе, передаю ее в качестве аргумента каждому дочернему процессу иполучение весов вызывает ошибку значения:

# The worker executes
def run(self):
        with tf.Session(graph=tf.Graph()) as sess:
            self.private_net = ACNetwork()
.......
            a_grads, c_grads = self.private_net.get_gradients()
            self.master.update_from_gradients(a_grads, c_grads)
# now inside the master network
def update_from_gradients(self, actor_gradients, critic_gradients):
        grads_and_vars = list(zip(actor_gradients, self.actor_t.get_weights()))  
        # get_weights raises the error
        train_op = self.actor_opt.apply_gradients(grads_and_vars)

повышает:

ValueError: Tensor Tensor("dense_4/kernel:0", shape=(4, 512), dtype=float32_ref) is not an element of this graph

Насколько я понимаю, код обновления весов выполняется внутри графа, который не влечет за собойосновная сеть, таким образом, поднимает ошибку. Как я могу сохранить график основной сети, чтобы я мог обновить его в контексте дочернего процесса?

1 Ответ

0 голосов
/ 21 октября 2019

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

Вам не нужны процессы для передачи параллельных пакетов, вы можете создать параллельную модель:

mainModel = ....

inputs = []
outputs = []
for i in range(num_workers):
    inp = Input(input_shape)
    out = mainModel(inp)
    inputs.append(inp)
    outputs.append(out)

parallelModel = Model(inputs, outputs)

Train с num_workersразличные группы данных:

parallelModel.fit(
               [xTrain1, xTrain2,...],
               [yTrain1, yTrain2,...]
               )

Если вы используете активное выполнение, даже без параллельной модели или других процессов, вы можете передавать num_workers пакетов, вычислять их градиенты, суммировать их градиенты и, наконец, применять градиенты.

Если вы действительно хотите использовать параллельную обработку без создания предложенной параллельной модели, вам, вероятно, следует использовать multiprocessing.dummy и оставить одну единственную модель в главном потоке, используя рабочих только для передачи данных и получения градиентов.

Теперь, еще проще, использование размера пакета, который в num_workers раз превышает размер каждой из ваших параллельных партий, приведет к тому же самому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...