由于在model.fit_generator
中使用多重处理的优点,我从简单的生成器方法(在True True循环中使用yield)切换到keras.utils.Sequence
。在下面的代码中,我加载了一些图像和遮罩文件(该应用程序是语义分割),而我的__len__
方法正在返回数据集长度除以批处理大小,如许多教程中所述(例如this one )
class ImageSequence(Sequence):
def __init__(self, data_location, batch_size=32, is_training=False, class_to_detect='face'):
if is_training:
self.dataset = open(os.path.join(data_location, 'train.txt')).readlines()
else:
self.dataset = open(os.path.join(data_location, 'test.txt')).readlines()
self.class_to_detect = class_to_detect
self.data_location = data_location
self.batch_size = batch_size
def __len__(self):
return len(self.dataset) // self.batch_size
def __getitem__(self, i):
files = self.dataset[(i * self.batch_size):((i + 1) * self.batch_size)]
data = np.zeros((self.batch_size, 64, 64, 3))
labels = np.zeros((self.batch_size, 64, 64, 1))
for i, sample in enumerate(files):
image_file = sample.split(',')[0]
truth_file = sample.split(',')[1][:-1]
image = np.float32(cv2.imread(os.path.join(self.data_location, image_file)) / 255.0)
truth_mask = cv2.imread(os.path.join(self.data_location, truth_file), cv2.IMREAD_GRAYSCALE)
label = np.zeros_like(truth_mask)
label[truth_mask == object_label[self.class_to_detect]] = 1.0
data[i], labels[i] = crop_random(image, label)
return data, labels
但是正如您所看到的,我使用一种方法来从加载的图像中crop_random
使我的模型更加健壮。我想使用的另一种方法是随机翻转,但在实现过程中我会问自己
“当我分解数据集并使用所有这些预处理材料时,序列长度也在增加吗?”
但是当我增加序列长度时,__getitem__
的索引显然应该超出范围了吗?但是当我不增加len时,fit_generator方法将始终只看到一个时期的“少量”样本。
我以错误的方式使用keras.utils.Sequence
还是对它的工作方式有错误的思维模式?