简体   繁体   中英

Tensorflow classification not running correctly with multiprocessing, but is with multithreading

I have an app that should be classifying images in parallel every 5 seconds. I want to get around the Global Interpreter Lock, so I am trying to use the multiprocessing library rather than multithreading. More or less, my code looks like this:

# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line 
                   in tf.gfile.GFile("/home/aneksteind/tensorflowSource/output_labels.txt")]

# Unpersists graph from file
f = tf.gfile.FastGFile("/home/aneksteind/tensorflowSource/output_graph.pb", 'rb')
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
_ = tf.import_graph_def(graph_def, name='')

sess = tf.Session()
mainGraph = sess.graph

# a function that starts a thread for each region of interest to classify
def checkFrames():
    timer = threading.Timer(5.0, checkFrames)
    timer.daemon = True
    timer.start()
    if(started):
        index = 0
        threads = []
        for roi in rois:
            p = Process(target=containsPlane, args=(frame, roi, index))
            p.daemon = True
            p.start()
            index += 1

def containsPlane(frame, roi, index):
    tempGraph = mainGraph
    tempSession = tf.Session(graph=tempGraph)
    tempTensor = tempSession.graph.get_tensor_by_name('final_result:0')
    predictions = tempSession.run(tempTensor, \
             {'DecodeJpeg:0': subframe})

    ...

When I am running this code using a Thread, it runs just fine. It prints out each preliminary message/warnings before classifying for the first time only once and classifies each image, but not in parallel.

When I change to a Process, the preliminary messages/warnings repeatedly show up and the images are never classified. Could this be due to the sessions sharing a state of some sort? What can I do differently so that multiple images are classified in parallel?

From TensorFlow doc : Creates a new TensorFlow session.
If no graph argument is specified when constructing the session, the default graph will be launched in the session. If you are using more than one graph (created with tf.Graph() in the same process, you will have to use different sessions for each graph, but each graph can be used in multiple sessions. In this case, it is often clearer to pass the graph to be launched explicitly to the session constructor.

I think you should give graph=tf.Graph() as a parameter to def containsPlane(...) . Try to become independent from global vars and try to create the session inside def containsPlane(...) .


You have three arguments args=(frame, roi, index) , but I did not see any using of them in def containsPlane(..) ?


Question : ... running this code using a Thread, it runs just fine. ..., but not in parallel.
for roi in rois: threads.append(threading.Thread(...

You start roi Threads , so I can't imagin why executing is not in parallel ?

Your attemp to use multiprocessing this way will fail as you should not start more processes as your machine has cores. Starting more will result in swaping and therefore reduce the overall performance.

Question : how could I tell which variable is the one that needs to be a multiprocess.Value?

All not readonly


Didn't understand why you doing the following:

sess = tf.Session()
mainGraph = sess.graph
# ...
def containsPlane(frame, roi, index):
    tempGraph = mainGraph
    tempSession = tf.Session(graph=tempGraph)  

Why not simple:

def containsPlane(frame, roi, index):
    tempSession = tf.Session()  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM