由于将numpy数组列表转换为单个数组,自定义图像数据生成器(keras)非常慢

问题描述 投票:0回答:1

我的神经模型训练遇到瓶颈。我编写了一个自定义生成器,该生成器可以动态加载图像和蒙版,以传递给我的模型进行训练。我发现,即使在使用GPU时,它也非常慢,并将范围缩小到将我的一批面具从数组列表转换为具有尺寸(批处理,高度,宽度,类)的数组时。这似乎要花很长时间,但是我不知道为什么?每个遮罩为224x224x4(4个类为一个热编码),并且我仅使用一批16。如果我生成一个随机集合(224x224x4)数组的列表并应用np.array(arrays)对他们的操作非常快。任何想法将不胜感激?

import cv2
import os
import numpy as np
from tensorflow import keras
from skimage import img_as_bool
from skimage.transform import resize


class DataGenerator(keras.utils.Sequence):
    def __init__(self, imgIds, maskIds, imagePath, maskPath, weights=[1,1,1,1],
                        batchSize=16, shuffle=False):
        self.imgIds = imgIds
        self.maskIds = maskIds
        self.imagePath = imagePath
        self.maskPath = maskPath
        self.weights = np.array(weights)
        self.batchSize = batchSize
        self.shuffle = shuffle


    '''
    for each image id load the patch and corresponding mask
    '''
    def __load__(self, imgName, maskName):

        img = cv2.imread(os.path.join(self.imagePath,imgName))
        img = img/255.0

        mask = np.load(os.path.join(self.maskPath,maskName))
        mask = np.multiply(mask, self.weights)
        mask = tf.cast(mask, tf.float32)

        return (img, mask)


    '''
    get the files for each batch (override __getitem__ method)
    '''
    def __getitem__(self, index):

        if(index+1)*self.batchSize > len(self.imgIds):
            self.batchSize = len(self.imgIds) - index*self.batchSize

        batchImgs = self.imgIds[self.batchSize*index:self.batchSize*(index+1)]
        batchMasks = self.maskIds[self.batchSize*index:self.batchSize*(index+1)]
        batchfiles = [self.__load__(imgFile, maskFile) for imgFile, maskFile in zip(batchImgs, batchMasks)]
        images, masks = zip(*batchfiles)

        return np.array(list(images)), np.array(list(masks))


    '''
    Return number of steps per batch that are needed (override __len__ method)
    '''
    def __len__(self):
        return int(np.ceil(len(self.imgIds)/self.batchSize))
arrays performance numpy keras image-segmentation
1个回答
0
投票

尝试在tensorflow中尽您所能(我正在使用tensorflow 2.1.0):

def __load__(self, imgName, maskName):
  path = os.path.join(self.imagePath,imgName)
  img = tf.image.decode_jpeg(tf.io.read_file(path)))
  img = img/255.0
  mask = np.load(os.path.join(self.maskPath,maskName))
  mask = tf.cast(mask, tf.float32)
  mask = tf.multiply(mask, self.weights)

np.multiply绝对不是一个好主意,可以肯定的是用户tf.multiply。我担心np.load,它也可能很慢,因为您的数据根本没有被压缩(意味着更多的I / O)。

您可以通过使用np.load保存数据并将tf.data.TFRecord用作数据生成器来解决tf.data.Dataset问题。这是在tensorflow中加载数据的性能的最佳选择。

© www.soinside.com 2019 - 2024. All rights reserved.