Background
我想使用带有Inception-Resnet_v2的keras来预测病理图像 . 我已经训练了模型并得到了.hdf5文件 . 由于病理图像非常大(例如:20,000 x 20,000像素),因此我必须扫描图像以获得用于预测的小补丁 .
我想使用python2.7的多处理库来加速预测过程 . 主要思想是使用不同的子进程扫描不同的行,然后将补丁发送到模型 .
我看到有人建议在子进程中导入keras和加载模型 . 但我不认为它适合我的任务 . 使用 keras.models.load_model()
一次加载模型大约需要47秒,这非常耗时 . 因此,每次启动新的子进程时,我都无法重新加载模型 .
Question
我的问题是我可以在主进程中加载模型并将其作为参数传递给子进程吗?
我尝试过两种方法,但两种方法都不起作用 .
Method 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 .
Method 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
期待回复!谢谢!
1 回答
也许你可以使用apply_async()而不是Pool()
你可以在这里找到更多细节:
Python multiprocessing pickling error