Модель в родительской области не позволяет модели в области подпроцесса
Итак, вот проблема, с которой я сталкиваюсь. Я пытаюсь обучить модель многопроцессорности Process
, но когда модель уже существует в родительской области, процесс будет остановлен при инициализации Embedding
слой.
from multiprocessing import Process, Pipe
import numpy as np
from keras.models import Model
from keras.layers import Input, Dense, Embedding
from keras.optimizers import Adam
import tensorflow as tf
def make_model(vecs, weights=None):
inp = Input((5,))
embd = Embedding(len(vecs), 50, weights=[vecs], trainable=False)(inp)
out = Dense(5, activation='softmax')(embd)
model = Model(inp, out)
model.compile(Adam(0.001), 'categorical_crossentropy', metrics=['accuracy'])
return model
def f(vecs, conn):
model = make_model(vecs)
conn.send('done')
conn.close()
if __name__ == '__main__':
vecs = np.random.random((100000, 50))
model1 = make_model(vecs)
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(vecs, child_conn), daemon=True)
p.start()
print('starting model two')
print(parent_conn.recv())
print('completed')
Когда этот скрипт выполняется так, как он написан в данный момент, он никогда не напечатает "завершенное" сообщение. Если, однако, я закомментирую строку model1 = make_model(vecs)
тогда все будет работать нормально.
1 ответ
Карас действительно хороший и удобный для пользователя и довольно удивительный. Но... он делает много "волшебства", с которым трудно работать, если вы хотите сделать что-то "нестандартное".
Когда вы извлекаете дочерний процесс из родительского процесса, он копирует состояние keras, в котором содержатся некоторые предположения, которые верны для исходного процесса, но не для дочернего процесса. Вы можете копаться в коде, чтобы выяснить, каковы эти предположения.
Обратите внимание, что если вы двигаетесь model1 = make_model(vecs)
после p.start()
тогда все работает. Причина в том, что дочерний процесс копирует керас в своем "чистом" состоянии (до того, как что-либо было выполнено). Это состояние изменяется в дочернем процессе, но это не влияет на родительский процесс.
Еще лучше исправить то, что все импорты keras переносятся в целевую функцию и никогда не импортируются в родительский процесс, таким образом вы можете безопасно запускать столько детей, сколько захотите.