如何编写带预加载的caffe python数据层?

时间:2018-01-02 08:35:52

标签: python machine-learning neural-network deep-learning caffe

如何在执行其他处理时编写异步数据层以预加载批次?有一些示例代码吗?感谢

1 个答案:

答案 0 :(得分:4)

有几种方法可以达到你想要的效果。我将尝试在这里草拟一个选项。

系统的整体视图是:您n Loader异步加载数据并提供队列。然后,该层从队列中读取batch_size个项目,并在forward()函数中提供网络。

import caffe, multiprocessing

class Loader(multiprocessing.Process):
  def __init__(self, outq, *args, **kwargs):
    super(Loader, self).__init__()
    self.daemon = True
    self.outq = outq
    self.start()  # start working

  def run(self):
    while True:  # read and never stop at all!
      try:
        # do your magic here
        # assuming you load x,y pairs
        self.outq.put((x[None, ...], y[None, ...]))  # add singleton "batch" dimension
      except Exception as e:
        # handle errors?
        pass

 class MultiProcessInputLayer(caffe.Layer):
   def setup(self, bottom, top):
     # verify no bottoms, right number of tops etc.
     self.dataQ = multiprocessing.Queue()
     for _ in xrange(n):
       Loader(self.dataQ)  # start n Loaders
     # some other stuff here...

   def reshape(self, bottom, top):
     # reshape the inputs to the right sizes

   def forward(self, bottom, top):
     for i in xrange(batch_size):
       item = self.dataQ.get()
       top[0].data[i, ...] = item[0]
       top[1].data[i, ...] = item[1]

   def backward(self, top, propagate_down, bottom):
     pass  # no backward for data layer

我学到了很多困难的一些提示和技巧:
1.由于GIL,请使用multiprocessing而非threading包 2.有时(例如,如果batch_size非常大),forward()需要很长时间才能从队列中逐项读取以形成每个批次。在这种情况下,您可以添加另一个multiprocessing.Process,它将batch_size中的异步读取self.dataQ项并将整批编写到self.batchQ。然后forward()只会在每次通话时等待来自self.batchQ项。
3.注意不要过多地复制数据。使用大图像/标签可以使所有这些复制成为瓶颈。