简体   繁体   English

在多处理中使用keras

[英]Use keras in multiprocessing

This is basically a duplicate of: Keras + Tensorflow and Multiprocessing in Python But my setup is a bit different, and their solution doesn't work for me. 这基本上是以下内容的副本: Keras + Tensorflow和Python中的多处理但是我的设置有点不同,它们的解决方案对我不起作用。

I need to train a keras model against predictions made from another model. 我需要针对另一个模型的预测来训练keras模型。 The predictions are connected to some CPU heavy code, so I would like to parallelize them and have the code run in worker processes. 预测与某些CPU繁重的代码有关,因此我想将它们并行化,并在工作进程中运行代码。 Here is the code I would like to execute: 这是我要执行的代码:

import numpy as np

from keras.layers import Input, Dense
from keras.models import Model
from keras.optimizers import Adam

def create_model():
    input_layer = Input((10,))
    dense = Dense(10)(input_layer)

    return Model(inputs=input_layer, outputs=dense)

model_outside = create_model()
model_outside.compile(Adam(1e-3), "mse")

def subprocess_routine(weights):
    model_inside = create_model()
    model_inside.set_weights(weights)

    while True:
        # lots of CPU
        batch = np.random.rand(10, 10)
        prediction = model_inside.predict(batch)

        yield batch, prediction

weights = model_outside.get_weights()

model_outside.fit_generator(subprocess_routine(weights),
                            epochs=10,
                            steps_per_epoch=100,
                            use_multiprocessing=True,
                            workers=1)

This produces an error 这会产生错误

E tensorflow/core/grappler/clusters/utils.cc:81] Failed to get device properties, error code: 3 E tensorflow / core / grappler / clusters / utils.cc:81]无法获取设备属性,错误代码:3

I found the above question, the answer is to move keras imports into the subprocess. 我发现了上面的问题,答案是将keras导入移动到子过程中。 I have added all imports into the subprocess_routine . 我已经将所有导入添加到subprocess_routine But that doesn't change the error. 但这并不会改变错误。 It would probably be necessary to eliminate keras imports altogether from the main process, but in my setup, that would mean huge refactorings. 可能有必要从主要过程中完全消除喀拉拉邦的进口,但是在我的设置中,这意味着大量的重构。

Keras + multithreading seems to work. Keras +多线程似乎有效。 In this issue, scroll down to the very last comment: https://github.com/keras-team/keras/issues/5640 In my code, it looks like this: 在此问题中,向下滚动到最后一条注释: https : //github.com/keras-team/keras/issues/5640在我的代码中,它看起来像这样:

model_inside = create_model()
model_inside._make_predict_function()

graph = tf.get_default_graph()

def subprocess_routine(model_inside, graph):

    while True:
        batch = np.random.rand(10, 10)

        with graph.as_default():
            prediction = model_inside.predict(batch)

        yield batch, prediction

model_outside.fit_generator(subprocess_routine(model_inside, graph),
                            epochs=10,
                            steps_per_epoch=100,
                            use_multiprocessing=True,
                            workers=1)

But the error message is identical. 但是错误消息是相同的。

Since the problem is apparently related to initialization of the subprocesses, I tried to create a new session in each subprocess: 由于问题显然与子流程的初始化有关,因此我尝试在每个子流程中创建一个新会话:

def subprocess_routine(weights):

    import keras.backend as K
    import tensorflow as tf
    sess = tf.Session()
    K.set_session(sess)

    model_inside = create_model()
    model_inside.set_weights(weights)

    while True:
        batch = np.random.rand(10, 10)
        prediction = model_inside.predict(batch)

        yield batch, prediction

It produces a variation on the same error message: 它在相同的错误消息上产生一个变体:

E tensorflow/stream_executor/cuda/cuda_driver.cc:1300] could not retrieve CUDA device count: CUDA_ERROR_NOT_INITIALIZED E tensorflow / stream_executor / cuda / cuda_driver.cc:1300]无法检索CUDA设备计数:CUDA_ERROR_NOT_INITIALIZED

So again, the initialization seems broken. 再次,初始化似乎已损坏。

How can I run keras both in my main process and subprocesses spawned by multiprocessing ? 如何在多进程产生的主进程和子进程中运行keras?

The good news is that tensorflow sessions are thread-safe: Is it thread-safe when using tf.Session in inference service? 好消息是tensorflow会话是线程安全的: 在推理服务中使用tf.Session时是否是线程安全的?

To use a keras model in multiple processes, you have to do the following: 要在多个过程中使用keras模型,您必须执行以下操作:

  • set up the model 建立模型
  • call _make_predict_function() 调用_make_predict_function()
  • set up a session and use it to get the tensorflow graph 设置一个会话并使用它来获取张量流图
  • finalize this graph 最终确定该图
  • everytime you predict something, supply this graph as_default_graph() 每次您预测某事时,都将此图提供为as_default_graph()

Here is some sample code: 这是一些示例代码:

# the usual imports
import numpy as np
import tensorflow as tf

from keras.models import *
from keras.layers import *

# set up the model
i = Input(shape=(10,))
b = Dense(1)(i)
model = Model(inputs=i, outputs=b)

# now to use it in multiprocessing, the following is necessary
model._make_predict_function()
sess = tf.Session()
sess.run(tf.global_variables_initializer())
default_graph = tf.get_default_graph()
default_graph.finalize()

# now you share the model and graph between processes
# in each process you can call this:
with default_graph.as_default():
    return model.predict(something)

This technique is not working for me. 这项技术对我不起作用。

I am loading my saved model and passing it on as an argument. 我正在加载保存的模型并将其作为参数传递。 My error message is slightly different than the one posted. 我的错误消息与发布的错误消息略有不同。 It is 它是

E tensorflow/core/grappler/clusters/utils.cc:83] Failed to get device properties, error code: 3

I do not have any trouble running it outside of multiprocessing. 在多处理程序之外运行它没有任何麻烦。 Also, if it means anythings, I'm using a docker image tensorflow/tensorflow-gpu-py3 version 1.13.1 另外,如果这意味着一切,我正在使用docker image tensorflow / tensorflow-gpu-py3版本1.13.1

Here is my Object Detection code below that takes an image and produces multiple scales of that image (called an image pyramid). 这是我下面的“对象检测”代码,用于拍摄图像并生成该图像的多个比例(称为图像金字塔)。 It then processes one scale at a time. 然后,它一次处理一个刻度。 For each scale, it parses the image into smaller windows and then send each window to a processor. 对于每个比例,它会将图像解析为较小的窗口,然后将每个窗口发送给处理器。 The processor then uses model.evaluate([window],[1]) to test if the current window contains my object. 然后,处理器使用model.evaluate([window],[1])测试当前窗口是否包含我的对象。 If the probability is high, the window box info is stored in a queue and retrieved later (along with the values from other processes) 如果概率很高,则窗口框信息将存储在队列中,并在以后检索(以及其他进程的值)

Here is my code: 这是我的代码:

def start_detection_mp3(image,winDim, minSize,  winStep=4, pyramidScale=1.5, minProb=0.7):
    # Code to use multiple processors (mp)
    boxes=[]
    probs=[]
    print("Loading CNN Keras Model .... ")
    checkpoint_path="trainedmodels/cp.ckpt"
    mymodel=create_CNN_model(2,winDim[0],winDim[1])
    mymodel.load_weights(checkpoint_path)
    mymodel._make_predict_function()
    (keepscale,keeplayer)=CalculateNumberOfScales(image,pyramidScale,minSize)
    printinfo("There are {} scales in this image.".format(len(keepscale)))
    for i in range(0,len(keepscale)):
        printinfo("Working on layer {0:4d}. Scale {1:.2f}".format(i,keepscale[i]))
        (b,p)=detect_single_layer_mp3(keeplayer[i],keepscale[i],winStep,winDim,minProb,mysess,mymodel)

        boxes =boxes + b
        probs =probs + p
    mysess.close()
    return(boxes,probs)

def detect_single_layer_mp3(layer,scale,winStep,winDim,minProb,mysess,mymodel): 
    # Use multiple processors
    q=[]
    p=[]
    d=[]
    i=0
    boxes=[]
    probs=[]
    xx, yy, windows= sliding_window_return(layer, winStep, winDim)
    # process in chunks of 4 (for four processors)
    NumOfProcessors=4;
    for aa in range(0,len(xx)-1,4):
        for ii in range(0,NumOfProcessors):
            ##print("aa: {}  ii: {}".format(aa,ii))
            printinfo("Processes {} of Loop {}".format(ii,aa))
            x=xx[aa]
            y=yy[aa]
            window=windows[aa]
            q=Queue() # Only need to create one Queue (FIFO buffer) to hold output from each process
            # when all processes are completed, the buffer will be emptied.
            p.append(Process(target=f2,args=(x,y,window,scale, minProb,winDim,q,mysess,mymodel)))
            pp=p[-1] # get last
            printinfo("Starting process {}".format(pp))
            pp.start()
            pp.join()

        while not q.empty():
            d=q.get()
            boxes = boxes + d[0]
            probs = probs + d[1]

        p=[]  # Clear Processes    
        p=[]
        q=[]   

    return(boxes,probs)


def f2(x,y,window,scale,minProb,winDim,q,mysess,mymodel):
    processID = os.getpid()
    boxes=[]
    probs=[]
    isHOG = 0
    isCNN = 0
    isCNN_Keras=1
    (winH, winW) = window.shape[:2]
    if winW == winDim[0] and winH ==winDim[1]: # Check that window dimension is 
        if isCNN_Keras ==1:
            ### TODO  It appears that it is freezing at the prediction step                     
            printinfo("Process id: {} Starting test against CNN model".format(processID))
            window=window.reshape(-1,winH,winW,1)
            loss,prob = mymodel.evaluate([window],[1])
            print("Loss: {}  Accuracy: {}".format(loss,prob))

            if prob > minProb:
                printinfo("*** [INFO] ProcessID: {0:7d} Probability: {1:.3f}  Scale {2:.3f} ***".format(processID,prob,scale))
                # compute the (x, y)-coordinates of the bounding box using the current
                # scale of the image pyramid
                (startX, startY) = (int(scale * x), int(scale * y))
                endX = int(startX + (scale * winW))
                endY = int(startY + (scale * winH))

                # update the list of bounding boxes and probabilities
                boxes.append((startX, startY, endX, endY))
                probs.append(prob)      
    # return a tuple of the bounding boxes and probabilities            
    if q!=1:        
        q.put([boxes,probs])
        q.close()
        q=[]
    else:
        return(boxes,probs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python中的Keras + Tensorflow和Multiprocessing - Keras + Tensorflow and Multiprocessing in Python 导入Keras会破坏多处理 - Importing Keras breaks multiprocessing Keras 多处理 model 预测 - Keras multiprocessing model prediction Keras 多处理中断验证准确性 - Keras Multiprocessing breaks validation accuracy Keras:在predict_generator中使用use_multiprocessing = True可以提供比所需更多的预测吗? - Keras: Using use_multiprocessing=True in predict_generator gives more predictions than required? 将 keras fit_generator 与 max_queue_size、workers 和 use_multiprocessing 一起使用 - Using keras fit_generator with max_queue_size, workers and use_multiprocessing 使用 tf.keras.utils.Sequence 和 model.fit_generator 和 use_multiprocessing=True 生成警告 - Using tf.keras.utils.Sequence with model.fit_generator with use_multiprocessing=True generated warning 如何在keras fit_generator()中定义max_queue_size,workers和use_multiprocessing? - How to define max_queue_size, workers and use_multiprocessing in keras fit_generator()? tensorflow 2 使用 keras.sequence 作为训练机器学习的数据生成器 model 具有多处理错误 - tensorflow 2 use keras.sequence as data generator for training machine learning model with multiprocessing error 如何正确启用 keras fit() 多处理? - how to enable keras fit() multiprocessing properly?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM