我在使用Python 2.7的Keras。我正在创建自己的数据生成器来计算训练批次。基于这里看到的模型,我对data_generator有一些疑问:
class DataGenerator(keras.utils.Sequence):def __init__(self, list_IDs, ...): #initdef __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, ydef 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__- 每个epoch的循环 : - 每个批次的循环 : - __len__ - __get_item__ (+数据生成) - on_epoch_end
如果你知道如何调试生成器,我很想知道,打断点和打印在这种情况下不起作用..
还有,我遇到了一个糟糕的情况,但我认为每个人都会遇到这个问题:
例如,我有200条数据(和200个标签)并且我想使用64作为批量大小。如果我没想错,__len__会给出200/64 = 3(而不是3.125)。所以1个epoch会用3个批次完成?剩余的数据怎么办?我因为数据量不是批量大小的倍数而遇到错误…
第二个例子,我有200条数据,我想使用256作为批量大小?在这种情况下,我应该如何调整我的生成器?我考虑过检查批量大小是否大于我的数据量,以便用1个批次来喂给CNN,但批次不会达到预期的大小,所以我认为这会导致错误?
谢谢你的阅读。我更喜欢使用伪代码,因为我的问题更多是关于理论而不是编码错误!
回答:
- __len__ : 返回批次数量
- __getitem__ : 返回第i个批次
通常你永远不会在模型架构中提到批量大小,因为它是训练参数而不是模型参数。所以在训练时使用不同的批量大小是可以的。
示例
from keras.models import Sequentialfrom keras.layers import Dense, Conv2D, Flattenfrom keras.utils import to_categoricalimport keras#create modelmodel = Sequential()#add model layersmodel.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, yX = 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/1016/16 [==============================] - 0s 2ms/step - loss: 0.6774 - acc: 0.6097
如你所见,它在一个epoch中运行了16个批次,即13*15+5=200