使用带有validate_split的ImageDataGenerator的每个班级的训练样本数

时间:2018-12-18 23:23:12

标签: python machine-learning keras

使用Keras,我在X中有图像,在Y中有标签。然后我这样做:

 train_datagen = ImageDataGenerator(validation_split = 0.25)

 train_generator = train_datagen.flow(X, Y, subset = 'training')

我的问题是:当在模型的train_generator中使用fit_generator时,实际上每个类别中有多少样本作为训练样本?

例如,如果我有3个类别的1000(x,y)对:A类500个,B类300个和C类200个,那么A,B和C类中有多少个样本{{1} }真的是训练样本吗?还是我们所能做的就是:500 *(1.0-0.25)等等?

1 个答案:

答案 0 :(得分:1)

如果我们检查the relevant part of the source code,我们将意识到validation_split * num_samples(和X)中的最后y个样本将用于验证,其他样本将被用作验证。用于训练:

split_idx = int(len(x) * image_data_generator._validation_split)

# ...
if subset == 'validation':
    x = x[:split_idx]
    x_misc = [np.asarray(xx[:split_idx]) for xx in x_misc]
    if y is not None:
        y = y[:split_idx]
else:
    x = x[split_idx:]
    x_misc = [np.asarray(xx[split_idx:]) for xx in x_misc]
    if y is not None:
        y = y[split_idx:]

因此,如果您要确保训练和验证子集中的类比例相同,则这是您的责任(即Keras在使用此功能时不保证这样做)。 Keras verifies的唯一一件事是,每个类别中至少有一个样本包含在训练和验证子集中:

if not np.array_equal(
        np.unique(y[:split_idx]),
        np.unique(y[split_idx:])):
    raise ValueError('Training and validation subsets '
                     'have different number of classes after '
                     'the split. If your numpy arrays are '
                     'sorted by the label, you might want '
                     'to shuffle them.')

因此,要进行分层拆分(即在训练和验证拆分中保留每个类的样本比例)的解决方案是将sklearn.model_selection.train_test_splitstratify参数一起使用:

from sklearn.model_selection import train_test_split

val_split = 0.25
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=val_split, stratify=y)

X = np.concatenate((X_train, X_val))
y = np.concatenate((y_train, y_val))

现在您可以将validation_split=val_split传递给ImageDataGenerator,并且可以保证在训练和验证子集中,类的比例是相同的。