8

여러 스레드 (그리고 tensorflow 백엔드)를 사용하여 매개 변수 값이 다른 복수 keras 모델을 교육하려고합니다. 여러 스레드 내에서 동일한 모델을 사용하는 몇 가지 예를 보았습니다. 그러나이 특별한 경우에는 충돌하는 그래프와 관련된 여러 가지 오류가 발생합니다. 여기에 내가 할 수있는 작업에 대한 간단한 예제가 있습니다.TensorFlow/Keras 멀티 스레드 모델 피팅

from concurrent.futures import ThreadPoolExecutor 
import numpy as np 
import tensorflow as tf 
from keras import backend as K 
from keras.layers import Dense 
from keras.models import Sequential 


sess = tf.Session() 


def example_model(size): 
    model = Sequential() 
    model.add(Dense(size, input_shape=(5,))) 
    model.add(Dense(1)) 
    model.compile(optimizer='sgd', loss='mse') 
    return model 


if __name__ == '__main__': 
    K.set_session(sess) 
    X = np.random.random((10, 5)) 
    y = np.random.random((10, 1)) 
    models = [example_model(i) for i in range(5, 10)] 

    e = ThreadPoolExecutor(4) 
    res_list = [e.submit(model.fit, X, y) for model in models] 

    for res in res_list: 
     print(res.result()) 

결과 오류는 ValueError: Tensor("Variable:0", shape=(5, 5), dtype=float32_ref) must be from the same graph as Tensor("Variable_2/read:0", shape=(), dtype=float32).입니다. 비슷한 실패를주는 스레드 내에서 모델을 초기화하려고 시도했습니다.

이 문제를 해결하는 가장 좋은 방법에 대한 의견이 있으십니까? 나는이 정확한 구조에 전혀 붙어 있지 않지만, 모든 모델이 동일한 GPU 메모리 할당 내에서 훈련되도록 프로세스보다는 다중 쓰레드를 사용할 수 있기를 원합니다.

답변

4

Tensorflow 그래프는 threadsafe가 아니며 (https://www.tensorflow.org/api_docs/python/tf/Graph 참조) 새 Tensorflow 세션을 만들 때 기본적으로 기본 그래프가 사용됩니다.

병렬 처리 된 함수에서 새 그래프로 새 세션을 만들고 여기에 케라 모델을 구성하면이 문제를 해결할 수 있습니다. 여기

생성하고 병렬로 사용 가능한 각 GPU의 모델에 맞는 몇 가지 코드입니다 : 이것은 내 문제를 해결

import concurrent.futures 
import numpy as np 

import keras.backend as K 
from keras.layers import Dense 
from keras.models import Sequential 

import tensorflow as tf 
from tensorflow.python.client import device_lib 

def get_available_gpus(): 
    local_device_protos = device_lib.list_local_devices() 
    return [x.name for x in local_device_protos if x.device_type == 'GPU'] 

xdata = np.random.randn(100, 8) 
ytrue = np.random.randint(0, 2, 100) 

def fit(gpu): 
    with tf.Session(graph=tf.Graph()) as sess: 
     K.set_session(sess) 
     with tf.device(gpu): 
      model = Sequential() 
      model.add(Dense(12, input_dim=8, activation='relu')) 
      model.add(Dense(8, activation='relu')) 
      model.add(Dense(1, activation='sigmoid')) 

      model.compile(loss='binary_crossentropy', optimizer='adam') 
      model.fit(xdata, ytrue, verbose=0) 

      return model.evaluate(xdata, ytrue, verbose=0) 

gpus = get_available_gpus() 
with concurrent.futures.ThreadPoolExecutor(len(gpus)) as executor: 
    results = [x for x in executor.map(fit, gpus)] 
print('results: ', results) 
+0

을, 나는이 하나 개의 프로세스에서 실행중인 모델, 그것은 항상 ValueError를 보여줘 가지고 인수를 가져 오기 Tensor로 해석 될 수 없다. (Tensor Tensor ("input : 0", shape = (2, 2), dtype = float32_ref)는이 그래프의 요소가 아닙니다. – forqzy