#python #python-3.x #neural-network #multiprocessing
#python #python-3.x #нейронная сеть #многопроцессорная обработка
Вопрос:
Я хочу сделать процесс обучения моего NN короче, так что я использую многопроцессорную обработку. Однако полученные результаты неверны — сеть обучается неправильно (она обучается при использовании одних и тех же функций, но без многопроцессорной обработки). У меня две проблемы. Во-первых, если я введу некоторую переменную и использую ее внутри функции, реализованной с помощью многопроцессорной обработки, она работает нормально. Проблема в том, что когда я запускаю код и после этого изменяю переменную вручную (например. >>> a = 10), функция внутри многопроцессорной обработки не видит никаких изменений. Он работает так, как будто varible тот же, что и в начале. Вторая проблема — после принудительного ввода «свежих» данных внутри каждой запускаемой функции результаты по-прежнему неверны. У меня есть (другая) проблема, заключающаяся в том, что некоторые из начальных весов и отклонений слишком велики или малы, и небольшое изменение их значений не влияет на глобальный результат. Таким образом, некоторые из выходных градиентов должны быть равны 0, это верно в случае запуска обучения без многопроцессорной обработки. Когда я использую многопроцессорную обработку для обучения, каждый градиент отличается от формы 0, и они не являются копиями одного результата. У меня заканчиваются идеи, в чем может быть проблема, и мне нужна ваша помощь, пожалуйста.
Это мой код, в котором я запускаю multiTrain():
def calcGradM(data):
print(data[0])
VC=-epsilon/score0
for i in data:
if i[2]==1:
deltaMaskWB1[i[3]][0][i[4]]=i[0]*VC
deltaMaskWB1[i[3]][1][i[4]]=i[1]*VC
if i[2]==2:
deltaMaskWB2[i[3]][0][i[4]]=i[0]*VC
deltaMaskWB2[i[3]][1][i[4]]=i[1]*VC
def Grad(score0,lvl,layer,i):
maskW1=np.zeros_like(wb1)
maskW2=np.zeros_like(wb2)
maskB1=np.zeros_like(wb1)
maskB2=np.zeros_like(wb2)
if layer==1:
maskW1[lvl][0][i]=epsilon
maskB1[lvl][1][i]=epsilon
if layer==2:
maskW2[lvl][0][i]=epsilon
maskB2[lvl][1][i]=epsilon
return([result(wb1 maskW1,wb2 maskW2)-
score0,result(wb1 maskB1,wb2 maskB2)-score0,layer,lvl,i])
def result(L1,L2):
ans=[]
for i in range(pos1,pos2):
ans.append(netResponse(L1,L2,i))
return np.sum(ans)
def multiTrain():
T0=time.time()
global score0
score0=result(wb1,wb2)
if __name__ == '__main__':
pool = multiprocessing.Pool(4)
for l in range(2):
calcGradM(pool.map(partial(Grad,score0,l,2), range(hidLen)))
for l in range(hidLen):
calcGradM(pool.map(partial(Grad,score0,l,1), range(len(neuronsIn))))
pool.close()
print(time.time()-T0)
Ответ №1:
Переменные неявно совместно используются при чтении-записи между родителями многопроцессорных процессов и дочерними элементами.
Особенно, если их значения изменяются в родительском элементе, они не будут неявно переданы дочерним элементам, или если дочерние элементы изменяют значения, они не будут распространяться на другие процессы.
Дочерние элементы могут (в зависимости от режима создания) наследовать состояние глобальных объектов во время их разветвления от родительского процесса, но вы не должны полагаться на это.
В руководстве есть раздел о совместном использовании состояния между процессами multiprocessing
.
Эта статья также может вам помочь.