Debugging Keras fit和fit_生成器返回完全不同的结果

Debugging Keras fit和fit_生成器返回完全不同的结果,debugging,keras,Debugging,Keras,Keras fit和fit_生成器返回完全不同的结果,fit_生成器的精度下降近20%。我确实在数据生成器中使用了shuffle。我在下面附上了我的数据发生器。谢谢大家! def data_generator(input_x, input_y, batch_size = BATCH_SIZE): loopcount = len(input_x) // batch_size while True: i = random.randint(0, loopcount -

Keras fit和fit_生成器返回完全不同的结果,fit_生成器的精度下降近20%。我确实在数据生成器中使用了shuffle。我在下面附上了我的数据发生器。谢谢大家!

def data_generator(input_x, input_y, batch_size = BATCH_SIZE):
    loopcount = len(input_x) // batch_size
    while True:
        i = random.randint(0, loopcount - 1)
        x_batch = input_x[i*batch_size:(i+1)*batch_size]
        y_batch = input_y[i*batch_size:(i+1)*batch_size]
        yield x_batch, y_batch
我的model.fit_生成器如下所示:

    model.fit_generator(generator = data_generator(x_train, y_train, batch_size = BATCH_SIZE),steps_per_epoch = len(x_train) // BATCH_SIZE, epochs = 20, validation_data = data_generator(x_val, y_val, batch_size = BATCH_SIZE), validation_steps = len(x_val) // BATCH_SIZE)

注意:这不是解决方案,而是一个类似的问题。我认为这两个问题都是相关的,解决一个问题可以解决另一个问题


看起来您的生成器随机选取批次,很可能在同一时间段内重复或未使用批次

为了避免这种情况,您可以这样做(未经测试):

但是,如果数据量不是批量大小的倍数,则会丢失一些修补程序。不过,您可以对其进行编码,并返回小于批大小的最终批

或者,您可以使用迭代器:

class MyIterator(Iterator):
    def __init__(self, x, y, batch_size, shuffle=True, seed=None):
        self.x = x
        self.y = y
        super(MyIterator, self).__init__(x.shape[0], batch_size, shuffle, seed)

    def _get_batches_of_transformed_samples(self, index_array):
        return self.x[index_array], self.y[index_array]
然后像这样开始培训:

    train_iterator = MyIterator(x_train, y_train, batch_size)
    val_iterator = MyIterator(x_val, y_val, batch_size)
    model.fit_generator(generator=iterator, 
                        steps_per_epoch=len(train_iterator),  
                        validation_data=val_iterator, 
                        validation_steps=len(val_iterator),
                        epochs=20)
迭代器将为您处理剩余的补丁,有效地创建最后一批可能小于batch_大小的补丁


编辑:在上的讨论之后,在编写自己的自定义生成器时,对数据进行洗牌非常重要。

TLDR;使用
fit
代替
fit\u生成器


从TensorFlow 2.x开始,
fit
方法可以将生成器作为输入,因此我强烈建议不要使用
fit\u生成器
,而只使用
fit

这里的信息很少,但您的每个历元步骤和验证步骤是错误的,因为您没有除以批量大小,因此模型将在不同的数据集上进行评估。嗨,Matias,我确实在每个历元步骤和验证步骤上分析了批量大小。(steps\u per\u epoch=len(x\u train)//BATCH\u SIZE,validation\u steps=len(x\u val)//BATCH\u SIZE))是的,然后提供fit调用和更多信息。model.fit(x\u train,y\u train,validation\u data=(x\u val,y\u val),epoch=20,BATCH\u SIZE=10)fit如上所示,唯一的区别是fit_generator使用之前提供的数据生成器。
    train_iterator = MyIterator(x_train, y_train, batch_size)
    val_iterator = MyIterator(x_val, y_val, batch_size)
    model.fit_generator(generator=iterator, 
                        steps_per_epoch=len(train_iterator),  
                        validation_data=val_iterator, 
                        validation_steps=len(val_iterator),
                        epochs=20)