使用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)等等?
答案 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_split
与stratify
参数一起使用:
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
,并且可以保证在训练和验证子集中,类的比例是相同的。