这是my implementation 几乎满足您的要求。在train.py中使用很简单。
dataset_train = Dataset("path/to/list.train.txt", subtract_mean=True, is_train=True, name='train')
dataset_val = Dataset("path/to/list.val.txt", subtract_mean=True, is_train=False, name='val')
dataset_train.shuffle()
for batch_x, batch_y in dataset_train.batches(batch_size):
# batch_x: (batch_size, H, W, 3), batch_y: (batch_size)
...
# for samling for validation
for val_step, (val_batch_x, val_batch_y) in \
enumerate(dataset_val.sample_batches(batch_size, 256)):
- 使用“threading”和“concurrent.futures”进行后台加载,使用“Queue”进行固定大小的预取(但这不使用多 CPU,如下所述,不会损失速度)。
- 加载训练时,每张图像都是随机裁剪和翻转的。 (仅中心裁剪用于测试和验证)
- 一批图像被出列以馈送到 CNN。
为什么不使用多 CPU
由于GIL of CPython 带有threading 的python 线程无法在多个CPU 内核上同时运行。使用多核的另一种方法是multiprocessing (mp)。
I used to implement the function 与 mp.Process 和 mp.Queue,但 mp.Queue VERY SLOW 用于在进程之间传输像图像这样的大数据,因为它与 pipe() 的实现存在限制(在Linux)。在快速工作站上,一批 100 张 256x256 图像的开销约为 0.5 秒,而 AlexNet 的一批 64 张图像训练只需要 0.6 秒。
我尝试了threading和Queue,发现瓶颈是I/O而不是CPU计算,而Queue.Queue一次可以传输100张图片,即使没有多CPU,加载也变得更快。