【发布时间】:2017-01-24 03:55:42
【问题描述】:
我正在尝试使用 caffe 和 python 进行实时图像分类。我在一个进程中使用 OpenCV 从我的网络摄像头流式传输,在一个单独的进程中,使用 caffe 对从网络摄像头拉取的帧执行图像分类。然后我将分类结果传回主线程,为网络摄像头流添加字幕。
问题是,即使我有一个 NVIDIA GPU 并且正在 GPU 上执行 caffe 预测,主线程也会变慢。通常不做任何预测,我的网络摄像头流以 30 fps 运行;但是,根据预测,我的网络摄像头流最多可以达到 15 fps。
我已验证 caffe 在执行预测时确实使用了 GPU,并且我的 GPU 或 GPU 内存没有达到最大值。我还验证了我的 CPU 内核在程序期间的任何时候都没有达到最大值。我想知道我是否做错了什么,或者是否没有办法让这两个过程真正分开。任何建议表示赞赏。这是我的参考代码
class Consumer(multiprocessing.Process):
def __init__(self, task_queue, result_queue):
multiprocessing.Process.__init__(self)
self.task_queue = task_queue
self.result_queue = result_queue
#other initialization stuff
def run(self):
caffe.set_mode_gpu()
caffe.set_device(0)
#Load caffe net -- code omitted
while True:
image = self.task_queue.get()
#crop image -- code omitted
text = net.predict(image)
self.result_queue.put(text)
return
import cv2
import caffe
import multiprocessing
import Queue
tasks = multiprocessing.Queue()
results = multiprocessing.Queue()
consumer = Consumer(tasks,results)
consumer.start()
#Creating window and starting video capturer from camera
cv2.namedWindow("preview")
vc = cv2.VideoCapture(0)
#Try to get the first frame
if vc.isOpened():
rval, frame = vc.read()
else:
rval = False
frame_copy[:] = frame
task_empty = True
while rval:
if task_empty:
tasks.put(frame_copy)
task_empty = False
if not results.empty():
text = results.get()
#Add text to frame
cv2.putText(frame,text)
task_empty = True
#Showing the frame with all the applied modifications
cv2.imshow("preview", frame)
#Getting next frame from camera
rval, frame = vc.read()
frame_copy[:] = frame
#Getting keyboard input
key = cv2.waitKey(1)
#exit on ESC
if key == 27:
break
我很确定这是 caffe 预测减慢了一切,因为当我注释掉预测并在进程之间来回传递虚拟文本时,我再次获得 30 fps。
class Consumer(multiprocessing.Process):
def __init__(self, task_queue, result_queue):
multiprocessing.Process.__init__(self)
self.task_queue = task_queue
self.result_queue = result_queue
#other initialization stuff
def run(self):
caffe.set_mode_gpu()
caffe.set_device(0)
#Load caffe net -- code omitted
while True:
image = self.task_queue.get()
#crop image -- code omitted
#text = net.predict(image)
text = "dummy text"
self.result_queue.put(text)
return
import cv2
import caffe
import multiprocessing
import Queue
tasks = multiprocessing.Queue()
results = multiprocessing.Queue()
consumer = Consumer(tasks,results)
consumer.start()
#Creating window and starting video capturer from camera
cv2.namedWindow("preview")
vc = cv2.VideoCapture(0)
#Try to get the first frame
if vc.isOpened():
rval, frame = vc.read()
else:
rval = False
frame_copy[:] = frame
task_empty = True
while rval:
if task_empty:
tasks.put(frame_copy)
task_empty = False
if not results.empty():
text = results.get()
#Add text to frame
cv2.putText(frame,text)
task_empty = True
#Showing the frame with all the applied modifications
cv2.imshow("preview", frame)
#Getting next frame from camera
rval, frame = vc.read()
frame_copy[:] = frame
#Getting keyboard input
key = cv2.waitKey(1)
#exit on ESC
if key == 27:
break
【问题讨论】:
-
您是否为代码的各个块计时? CPU 和 GPU 之间的数据传输可能会导致大量开销。
-
我怎么知道传输是否是导致它变慢的原因?这里没有从 GPU 传输到 CPU 的显式代码
-
您是否尝试将
net.predict(image)替换为使用大量CPU 的代码与预测时间大致相同?例如,for i in range(10000000): pass在我的机器上大约需要 0.22 秒。对于我的机器和网络摄像头,您的代码以这种方式以 30 fps 的速度运行。 -
但是预测应该发生在 GPU 上吧?那么为什么在这种情况下增加 CPU 使用率会有所帮助呢?有点迷茫
-
我使用 cuda-convnet 进行 非实时 视频分析,并且 CPU 和 GPU 负载不错。不过,我还没有分析 CPU 使用情况是什么部分是我,什么是 cuda-convnet。不过,我使用了批处理,直观地讲,单帧可能会导致更多的 CPU 开销。但我的直觉可能是错误的。 :)
标签: python multiprocessing deep-learning caffe gpgpu