¿Cómo escribir una capa de datos python caffe con precarga?

¿Cómo escribir una capa de datos asíncrona para precargar lotes mientras se realiza otro procesamiento? ¿Hay algunos códigos de ejemplo? Gracias

Hay varias formas en que puede lograr lo que quiere. Intentaré dibujar una opción aquí.

La vista general del sistema es: usted tiene n Loader s cargando datos de forma asíncrona y alimentando una cola. La capa luego lee los elementos batch_size de la cola y alimenta la red en la función 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 

Algunos consejos y trucos que aprendí de la manera difícil:
1. Utilice el paquete de multiprocessing y no de threading debido a la GIL .
2. A veces (por ejemplo, si batch_size es muy grande) tomará mucho tiempo para que forward() lea artículo por artículo de la cola para formar cada lote. En ese caso, puede agregar otro proceso de multiprocessing.Process que async leerá los elementos self.dataQ de self.dataQ y escribirá lotes enteros en self.batchQ . Luego, forward() solo esperará un elemento de self.batchQ en cada llamada.
3. Tenga cuidado de no copiar demasiado los datos. Trabajar con imágenes / tags grandes puede hacer que todas estas copias se conviertan en un cuello de botella.