【发布时间】:2018-07-12 02:12:04
【问题描述】:
免责声明:我认为问题与 keras 没有直接关系,更多的是关于 python 中生成器的一般行为
我正在尝试为 Keras 构建自定义数据生成器。我这样做是因为内置图像数据生成器仅支持分类任务,而我正在尝试以图像作为输入来解决回归任务。
首先,我将包含 img 路径和目标变量 Y 的文本文件上传到数据帧中,然后将它们打乱:
train, test = AnnoParser.get_data(input_path)
train = train.sample(frac=1).reset_index(drop=True)
AnnoParser 只是解析文本文件并返回 Pandas 数据帧。
然后我定义我的数据生成器:
def get_data_generator(array, resized_width, resized_height, mode):
while True:
if mode == 'train':
array = array.sample(frac=1).reset_index(drop=True)
augment = True
for img_path, img_hype in array:
try:
img = data_augment(img_path,resized_width, resized_height, augment)
yield np.copy(img), np.copy(img_hype)
由于我使用while True 循环,我希望它是无限的。如您所见,我每次都会重新洗牌输入数组以确保样本是随机的。 DataAugment 函数以 img 路径为输入,从该路径加载图像并将其调整为指定大小,返回图像本身(使用 cv2)。
最后我创建了一个生成器实例并在以后使用它:
data_gen_train = DataGenerator.get_data_generator(train, 224, 224, "train")
现在,据我了解,每次调用next(data_gen_train) 时,生成器都会对原始train 数组进行洗牌,并从执行结果中提取下一个值。因此,据我了解,我的生成器应该能够从我在原始数据集中拥有的所有图像路径的群体中无限地绘制图像。
但似乎生成器仍然经常抛出 StopIteration 异常。我不确定为什么。谁能解释一下?
更新
根据要求,您还可以在下面找到如何使用生成器来拟合模型。如您所见,我首先将一堆图像放入数组中,以便可以小批量训练网络。然后我只是将小批量输入网络并评估损失。
据我所知,生成器会在一段时间后中断,而不是在最初的几次迭代中。我怀疑在后台它只是对所有可用记录(可以由生成器产生的记录)执行一条路径,然后抛出迭代异常。
optimizer = Adam(lr=1e-5)
model = DenseNet(reduction=0.5, weights_path=weights_path)
model.compile(loss='mean_absolute_error', optimizer=optimizer)
iter_num = 0
accuracy_monitor = []
accuracy_for_epoch = []
start_time = time.time()
best_loss = np.Inf
print('Starting training')
for epoch_num in range(num_epochs):
progbar = generic_utils.Progbar(epoch_length)
print('Epoch {}/{}'.format(epoch_num + 1, num_epochs))
while True:
#keep training untill end of epoch, if end of epoch - check result
if len(accuracy_monitor) == epoch_length:
print("Average accuracy is {} for {} previous iterations", str(np.mean(accuracy_monitor)), epoch_length)
accuracy_for_epoch.append(np.mean(accuracy_monitor))
accuracy_monitor = []
X = np.ndarray((batch_size,224,224,3))
Y = np.ndarray((batch_size))
i = 0
#building a batch
for img,hype in data_gen_train:
X[i,] = img
Y[i] = hype
i+=1
if i == batch_size:
break
loss = model.train_on_batch(x= X, y = Y)
accuracy_monitor.append(loss)
iter_num +=1
progbar.update(iter_num,[('Loss', np.mean(accuracy_monitor[:iter_num]))])
if iter_num == epoch_length:
accuracy_for_epoch.append(np.mean(accuracy_monitor))
curr_loss = np.mean(accuracy_monitor)
print('Elapsed time: {}'.format(time.time() - start_time))
print("Regressor accuracy over epoch: {}", curr_loss)
if curr_loss < best_loss:
print('Total loss decreased from {} to {}, saving weights'.format(best_loss,curr_loss))
best_loss = curr_loss
model.save_weights(weights_path)
start_time = time.time()
iter_num = 0
【问题讨论】:
-
你能显示拟合的代码吗?生成器在第一批/纪元后会中断吗?
-
@MarcinMożejko 完成!
标签: python numpy keras generator