当batch_size与数据量不匹配时的Keras自定义生成器

时间:2019-03-13 16:51:42

标签: python tensorflow machine-learning keras data-generation

我在Python 2.7中使用Keras。我正在制作自己的数据生成器来计算火车的批次。我对基于此模型seen here的data_generator有一些疑问:

class DataGenerator(keras.utils.Sequence):

def __init__(self, list_IDs, ...):
    #init

def __len__(self):
    return int(np.floor(len(self.list_IDs) / self.batch_size))

def __getitem__(self, index):
    indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]
    # Find list of IDs
    list_IDs_temp = [self.list_IDs[k] for k in indexes]
    # Generate data
    X, y = self.__data_generation(list_IDs_temp)
    return X, y

def on_epoch_end(self):
    'Updates indexes after each epoch'
    self.indexes = np.arange(len(self.list_IDs))
    if self.shuffle == True:
        np.random.shuffle(self.indexes)

def __data_generation(self, list_IDs_temp):
    #generate data
    return X, y

好的,这是我的几个问题:

您能证实我对功能顺序的看法吗?这是:

- __init__
- loop for each epoc :
    - loop for each batches :
        - __len_
        - __get_item__ (+data generation)
    - on_epoch_end

如果我想知道一种调试生成器的方法,则断点和打印都无法使用。.

更多,我的处境很糟,但我认为每个人都有问题:

例如,我有200个数据(还可以有200个标签),并且我希望批量大小为64。如果我想的很好,__ len_将给出200/64 = 3(而不是3125)。那么1个时代将完成3个批次?其余的数据呢?我有一个错误,因为我的数据量不是批处理大小的倍数...

第二个例子,我有200个数据,我想一批256个?在这种情况下,我该怎么做才能适应发电机?我考虑过要检查batch_size是否优于我的数据量,以便用1个批处理填充CNN,但是该批处理没有预期的大小,因此我认为这会出错?

感谢您的阅读。我更喜欢使用伪代码,因为我的问题更多是关于理论,而不是编码错误!

3 个答案:

答案 0 :(得分:1)

  • __ len__:返回批次数
  • __ getitem__:返回第i批

通常您不会在模型体系结构中提及批处理大小,因为它是训练参数而不是模型参数。因此,确定可以在训练时具有不同的批次大小。

示例

from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten
from keras.utils import to_categorical
import keras

#create model
model = Sequential()
#add model layers
model.add(Conv2D(64, kernel_size=3, activation='relu', input_shape=(10,10,1)))
model.add(Flatten())
model.add(Dense(2, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
class DataGenerator(keras.utils.Sequence):
    def __init__(self, X, y, batch_size):
        self.X = X
        self.y = y
        self.batch_size = batch_size

    def __len__(self):
        l = int(len(self.X) / self.batch_size)
        if l*self.batch_size < len(self.X):
            l += 1
        return l

    def __getitem__(self, index):
        X = self.X[index*self.batch_size:(index+1)*self.batch_size]
        y = self.y[index*self.batch_size:(index+1)*self.batch_size]
        return X, y

X = np.random.rand(200,10,10,1)
y = to_categorical(np.random.randint(0,2,200))
model.fit_generator(DataGenerator(X,y,13), epochs=10)

输出:

Epoch 1/10 16/16 [==============================] - 0s 2ms/step - loss: 0.6774 - acc: 0.6097

如您所见,它已经在一个时期内运行了16批,即13*15+5=200

答案 1 :(得分:0)

Keras在您的python环境中使用了您的生成器,如果您无法调试它,则原因在其他地方。

cf:https://keras.io/utils/#sequence

__len__:为您提供迷你批处理的数量

__getitem__:给出第i个小批量

您不必知道何时何地调用它们,而更像是这样:

- __init__
- __len_
- loop for each epoc :
    - loop for each batches :
        - __get_item__
    - on_epoch_end

对于小批量大小,您有两个(经典)选择,即截断或通过从集合中再次选择条目来进行填充。 如果您应该按每个时期随机分配训练集,那么随着时间的流逝,就不会出现某些物品曝光过度或曝光不足的情况

答案 2 :(得分:0)

这个问题的调试方面听起来与我最近尝试发布但没有得到答案的问题相同。我最终想通了,我认为这是一个简单的原则,初学者很容易错过。如果下面是 tensorflow-gpu,则无法在 keras 源代码级别进行中断/调试。该 keras 代码被“翻译”以在 gpu 上运行。我想如果在 cpu 上运行 tensorflow 可能会中断,但这也不可能。有一些方法可以在 tensorflow 级别对 gpu 进行调试/中断,但这超出了高级 keras 的简单性。