背景
我想使用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
期待回复!谢谢!