【问题标题】:How to write a caffe python data layer with preload?如何编写带有预加载的 caffe python 数据层?
【发布时间】:2018-06-11 23:23:17
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    有几种方法可以实现您想要的。我将在这里尝试绘制一个选项。

    系统的整体看法是:你有nLoaders 异步加载数据和喂一个队列。然后该层从队列中读取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. 使用multiprocessing 而不是threading 包,因为GIL
    2. 有时(例如,如果batch_size 非常大)forward() 需要很长时间才能从队列中逐项读取以形成每个批次。在这种情况下,您可能会添加另一个 multiprocessing.Process,它将从 self.dataQ 异步读取 batch_size 项目并将整个批次写入 self.batchQ。然后forward() 将在每次调用时只等待来自self.batchQ单个 项。
    3. 注意不要过多地复制数据。使用大图像/标签会使所有这些复制成为瓶颈。

    【讨论】:

    • 嗨,@Shai 非常感谢你,你真的帮了我很多。你能提供一个更具体的例子吗?例如,如何使用您的代码来实现 ImageData 层,即从文本文件(img_path、img_label)中读取图像和标签。我不知道如何维护索引以及如何在这个多重处理设置中的每个时期之后对列表进行洗牌。非常感谢。
    • @kli_nlpr 您可以添加另一个multiprocessing.Process,将图像/标签列表发送到Loaders。这个过程将在每个 epoch 后洗牌并做所有的记账
    猜你喜欢
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多