[英]Machine Learning model performs worse on test data than validation data
I am quite new to machine learning.我对机器学习很陌生。
To start things, I wanted to train a model to classify pictures of cats and dogs.首先,我想训练一个 model 来对猫和狗的图片进行分类。
The problem I have is that when I train my model, it gives me a (approximately) 80-85% accuracy on the training data and the validation data.我遇到的问题是,当我训练我的 model 时,它在训练数据和验证数据上给了我(大约)80-85% 的准确度。 The loss is quite low with about 0.4 - 0.5 on both the validation data and the training data.
损失非常低,验证数据和训练数据的损失都在 0.4 - 0.5 左右。 Because those numbers are quite similar, I suspect that I don't have a problem with overfitting, right?
因为这些数字非常相似,我怀疑我没有过度拟合的问题,对吧?
But when I test my model with pictures from the dataset (which it has not seen before), the accuracy turns out to be around 70%-73%.但是,当我用数据集中的图片(以前从未见过)测试我的 model 时,准确率大约是 70%-73%。 So it's significantly lower.
所以显着降低。 I was not able to find any information on why this is the case.
我找不到任何关于为什么会这样的信息。 And, as I said, I suspect that overfitting is not the problem but since I'm a beginner, I'm not quite sure.
而且,正如我所说,我怀疑过度拟合不是问题,但由于我是初学者,我不太确定。
My model looks like this (I use tensorflow in python):我的 model 看起来像这样(我在 python 中使用 tensorflow):
model = Sequential([
Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding = 'same', input_shape=(224,224,3), kernel_initializer="he_uniform"),
MaxPool2D(pool_size=(2, 2)),
Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding = 'same', kernel_initializer="he_uniform"),
MaxPool2D(pool_size=(2, 2)),
Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding = 'same', kernel_initializer="he_uniform", kernel_regularizer=l2(.001)),
MaxPool2D(pool_size=(2, 2)),
Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding = 'same', kernel_initializer="he_uniform", kernel_regularizer=l2(.001)),
MaxPool2D(pool_size=(2, 2)),
Flatten(),
Dense(units = 128, activation='relu'),
Dropout(.5),
Dense(units=2, activation='softmax')
])
Trainable params: 3,471,810
Non-trainable params: 0
Optimizer, loss:优化器,损失:
model.compile(optimizer=Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
This is the dataset, which I use: https://www.kaggle.com/tongpython/cat-and-dog I use 3000 images for training (1500 of dogs and 1500 of cats), 1000 for validation and 1000 for testing.这是我使用的数据集: https://www.kaggle.com/tongpython/cat-and-dog我使用 3000 张图像进行训练(1500 只狗和 1500 只猫),1000 张用于验证,1000 张用于测试。 There are no duplicates (so no images in the validation set, which are also in the training set and so on).
没有重复(因此验证集中没有图像,它们也在训练集中等等)。
I preprocess the images like that (and I also use data augmentation):我像这样预处理图像(并且我还使用数据增强):
train_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input, rescale=1/255, horizontal_flip=True, vertical_flip=True, width_shift_range=.2, height_shift_range=.2) \
.flow_from_directory(directory=training_path, target_size=(224,224), classes=['cat', 'dog'], batch_size=64)
valid_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input, rescale=1/255, horizontal_flip=True, vertical_flip=True, width_shift_range=.2, height_shift_range=.2) \
.flow_from_directory(directory=validation_path, target_size=(224,224), classes=['cat', 'dog'], batch_size=64)
test_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input).flow_from_directory(directory=test_path, target_size=(224,224), classes=['cat', 'dog'], batch_size=64, shuffle=False)
EDIT: Solved the problem.编辑:解决了这个问题。 My mistake was that I did not preprocess the train, validation and test data in the exact same way because I misunderstood one parameter.
我的错误是我没有以完全相同的方式预处理训练、验证和测试数据,因为我误解了一个参数。 Thank you to all, who helped me.
感谢所有帮助过我的人。
I believe your problem results from the fact that for the validation data and the training data you have我相信您的问题是由于您拥有的验证数据和训练数据
train_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input, rescale=1/255, .....
The vgg16.preprocess_input function rescales the pixel value between +1 and -1 so there is no need to include rescale=1/255. vgg16.preprocess_input function 在 +1 和 -1 之间重新缩放像素值,因此无需包含 rescale=1/255。 In your test generator you do not rescale the pixel values.
在您的测试生成器中,您不会重新调整像素值。 So remove the rescale=1/255 in the train and validation generators
所以删除训练和验证生成器中的 rescale=1/255
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.