基于单个GPU进行Keras模型预测的多进程处理

6

背景

我想使用Inception-Resnet_v2和Keras来预测病理图像。我已经训练好了模型并获得了.hdf5文件。因为病理图像非常大(例如:20,000 x 20,000像素),所以我必须扫描图像以获取用于预测的小块。

我想使用Python2.7中的multiprocessing库加速预测过程。主要思路是使用不同的子进程扫描不同的行,然后将小块发送给模型。

我看到有人建议在子进程中导入keras并加载模型。但我认为这对我的任务不适合。使用keras.models.load_model()一次加载模型需要约47秒,这非常耗时。所以我不能在每次启动新的子进程时重新加载模型。

问题

我的问题是,我能否在主进程中加载模型,并将其作为参数传递给子进程?

我尝试了两种方法,但都没有成功。

方法1。使用multiprocessing.Pool

代码如下:

import keras
from keras.models import load_model
import multiprocessing

def predict(num,model):
    print dir(model)
    print num
    model.predict("image data, type:list")

if __name__ == '__main__':
    model = load_model("path of hdf5 file")
    list = [(1,model),(2,model),(3,model),(4,model),(5,model),(6,model)]
    pool = multiprocessing.Pool(4)
    pool.map(predict,list)
    pool.close()
    pool.join()

输出结果如下:
cPickle.PicklingError: Can't pickle <type 'module'>: attribute lookup __builtin__.module failed

我搜寻了这个错误并发现 Pool 无法映射不可反序列化的参数,所以我尝试了第二种方法。

方法2. 使用 multiprocessing.Process

代码如下:

import keras
from keras.models import load_model
import multiprocessing

def predict(num,model):
    print num
    print dir(model)
    model.predict("image data, type:list")

if __name__ == '__main__':
    model = load_model("path of hdf5 file")
    list = [(1,model),(2,model),(3,model),(4,model),(5,model),(6,model)]
    proc = []
    for i in range(4):
        proc.append(multiprocessing.Process(predict, list[i]))
        proc[i].start()
    for i in range(4):
        proc[i].join()

在方法2中,我可以打印dir(model)。我认为这表示模型已经成功地传递给了子进程。但是我遇到了这个错误。
E tensorflow/stream_executor/cuda/cuda_driver.cc:1296] failed to enqueue async memcpy from host to device: CUDA_ERROR_NOT_INITIALIZED; GPU dst: 0x13350b2200; host src: 0x2049e2400; size: 4=0x4

我使用的环境:

  • Ubuntu 16.04,Python 2.7
  • Keras 2.0.8(TensorFlow后端)
  • 一张Titan X,驱动版本为384.98,CUDA 8.0

期待回复!谢谢!


你解决过这个问题吗?我在面临相同的Pickling问题。使用纯进程而非进程池会导致进程挂起而不是无法进行Pickling。但我不确定这是否有所进展。 - Eduardo
3个回答

0

多进程在CPU上运行,而模型预测发生在GPU上,只有一个GPU。我看不出多进程如何对预测有帮助。

相反,我认为你可以使用多进程扫描不同的补丁,你似乎已经成功实现了这一点。然后将这些补丁堆叠成一个或多个批次,在GPU上并行进行预测。


0

正如Statham所指出的,多进程需要所有args与pickle兼容。本博客介绍了如何将keras模型保存为pickle文件:[http://zachmoshe.com/2017/04/03/pickling-keras-models.html][1]。这可能是一个足够的解决方法,可以将您的keras模型作为参数传递给multiprocess,但我没有测试这个想法。

我还要补充一点,我在使用Windows而不是Linux上运行两个Keras进程并在单个GPU上获得更好的运行效果。在Linux上,第二个进程会出现内存不足的错误,但相同的内存分配(每个45%总GPU RAM)在Windows上也能正常工作。在我的情况下,它们都是fits - 仅用于运行预测,也许内存需求较少。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接