Python 我的模型具有较高的精度和val_精度,但在测试数据上给出了错误的结果

Python 我的模型具有较高的精度和val_精度,但在测试数据上给出了错误的结果,python,opencv,machine-learning,keras,Python,Opencv,Machine Learning,Keras,我已经用opencv创建了一些图像,并在上面运行了一个深度神经网络分类器。 它给出了大约97%的准确度和95%的val_准确度,但当我测试它时,它给出了错误的预测 这是我创建图像的代码 import cv2 import numpy as np import random import os size = 64 def circle(i,d): img = np.zeros(shape=(size,size,3)) point = (random.randint(1,size)

我已经用opencv创建了一些图像,并在上面运行了一个深度神经网络分类器。 它给出了大约97%的准确度和95%的val_准确度,但当我测试它时,它给出了错误的预测

这是我创建图像的代码

import cv2
import numpy as np
import random
import os
size = 64

def circle(i,d):
    img = np.zeros(shape=(size,size,3))
    point = (random.randint(1,size),random.randint(1,size))
    img = cv2.circle(img,point,random.randint(1,size),(255,255,0),thickness=2,lineType=8)

    if not os.path.exists(d+"/circle"):
        os.makedirs(d+"/circle")
    cv2.imwrite(d+"/circle/"+str(i)+"circle.png",img)
    #print("created circle"+str(i))


def rectangle(i,d):
    img = np.zeros(shape=(size,size,3))
    point = (random.randint(1,size),random.randint(1,size))
    w = random.randint(1,size);
    h = random.randint(1,size);
    point2 = (point[0] + w,point[1]+h)
    img = cv2.rectangle(img,point,point2,(255, 255, 0), 2)
    if not os.path.exists(d+"/react"):
        os.makedirs(d+"/react")
    cv2.imwrite(d+"/react/"+str(i)+"react.png",img)
    #print("created reactangle"+str(i))

def traingle(i,d):
    img = np.zeros(shape=(size,size,3))
    point1 = (random.randint(1,size),random.randint(1,size))
    point2 = (random.randint(1,size),random.randint(1,size))
    point3 = (random.randint(1,size),random.randint(1,size))

    img = cv2.line(img,point1,point2,(255, 255, 0), 2)
    img = cv2.line(img,point2,point3,(255, 255, 0), 2)
    img = cv2.line(img,point3,point1,(255, 255, 0), 2)
    if not os.path.exists(d+"/tra"):
        os.makedirs(d+"/tra")
    cv2.imwrite(d+"/tra/"+str(i)+"tra.png",img)
    #print("created trangle"+str(i))


if not os.path.exists("data_train"):
    os.makedirs('data_train')
for i in range(1,2000):
    circle(i,"data_train")
    rectangle(i,"data_train")
    traingle(i,"data_train")
print("Created test data")   
if not os.path.exists("data_test"):
    os.makedirs('data_test')
for i in range(1,500):
    circle(i,"data_test")
    rectangle(i,"data_test")
    traingle(i,"data_test")
这是我的分类代码

# importing libraries 
from keras.preprocessing.image import ImageDataGenerator 
from keras.models import Sequential 
from keras.layers import MaxPooling2D,Dropout, Convolution2D
from keras.layers import Flatten, Dense 
from keras import backend as K 


img_width, img_height = 64, 64

train_data_dir = 'data_train'
validation_data_dir = 'data_test'
nb_train_samples = 5997
nb_validation_samples = 1497
epochs = 3
batch_size = 15

if K.image_data_format() == 'channels_first': 
    input_shape = (3, img_width, img_height) 
else: 
    input_shape = (img_width, img_height, 3) 
model = Sequential() 

model.add(Convolution2D(32, 3, 3, input_shape = input_shape,activation="relu")) 
model.add(MaxPooling2D(pool_size =(2, 2))) 

model.add(Convolution2D(32, 3, 3,activation="relu")) 
model.add(MaxPooling2D(pool_size =(2, 2))) 

model.add(Flatten()) 
model.add(Dropout(0.2)) 
model.add(Dense(output_dim=180,activation="relu")) 
model.add(Dropout(0.2)) 
model.add(Dense(3,activation="softmax")) 

model.compile(loss ='categorical_crossentropy', 
                    optimizer ='adam', 
                metrics =['categorical_accuracy']) 

train_datagen = ImageDataGenerator( 
                rescale = 1. / 255, 
                shear_range = 0.2, 
                zoom_range = 0.2, 
            horizontal_flip = False) 

test_datagen = ImageDataGenerator(rescale = 1. / 255) 

train_generator = train_datagen.flow_from_directory(train_data_dir, 
                            target_size =(img_width, img_height), 
                    batch_size = batch_size, class_mode ='categorical') 

validation_generator = test_datagen.flow_from_directory( 
                                    validation_data_dir, 
                target_size =(img_width, img_height), 
        batch_size = batch_size, class_mode ='categorical') 

model.fit_generator(train_generator, 
    steps_per_epoch = nb_train_samples, 
    epochs = epochs, validation_data = validation_generator, 
    validation_steps = nb_validation_samples) 
我试过了 1.更改隐藏层的数目 2.在最后一层之前和第一层之后添加退出层。 2.添加conv层

有什么问题,请告诉我我做错了什么


提前感谢。

此问题最可能的原因是您的测试集和培训集不是来自同一个样本。这在分类问题中非常常见。在培训之前,您应该比较培训集和测试集的类分布和特征分布。如果它们彼此不接近,则从训练集学习的规则不会推广到测试集


例如,一个训练集的类分布是70%类1、20%类2和10%类3。由于交叉验证来自于训练集,因此该模型具有较高的训练和交叉验证精度。但是,如果测试集类分布类似于10%类1、20%类2和70%类3,则该模型可能表现不佳。

此问题最可能的原因是您的测试集和训练集不是来自同一样本。这在分类问题中非常常见。在培训之前,您应该比较培训集和测试集的类分布和特征分布。如果它们彼此不接近,则从训练集学习的规则不会推广到测试集


例如,一个训练集的类分布是70%类1、20%类2和10%类3。由于交叉验证来自于训练集,因此该模型具有较高的训练和交叉验证精度。但是,如果测试集类别分布类似于10%类别1、20%类别2和70%类别3,则该模型可能无法很好地执行。

此问题的另一个可能原因是过度拟合 因为你得到了很高的培训和验证准确性 常用的方法有:

交叉验证:找出样本预测误差的标准方法是使用5倍交叉验证。 提前停止:它的规则为我们提供了在学习者开始过度适应之前可以运行多少次迭代的指导。 修剪:修剪在构建相关模型时被广泛使用。它只是简单地删除了对手头的问题几乎没有预测能力的节点。
正则化:它引入了一个成本术语,用于在目标函数中引入更多功能。因此,它试图将许多变量的系数推到零,从而减少成本项。

此问题的另一个可能原因是过度拟合 因为你得到了很高的培训和验证准确性 常用的方法有:

交叉验证:找出样本预测误差的标准方法是使用5倍交叉验证。 提前停止:它的规则为我们提供了在学习者开始过度适应之前可以运行多少次迭代的指导。 修剪:修剪在构建相关模型时被广泛使用。它只是简单地删除了对手头的问题几乎没有预测能力的节点。
正则化:它引入了一个成本术语,用于在目标函数中引入更多功能。因此,它试图将许多变量的系数推到零,从而减少成本项。

您有培训和验证精度曲线图吗?我想知道你的数据是否有过度拟合。我是机器学习新手,让我检查一下如何创建这个问题的图,并会让你知道。你能给我推荐一些链接吗?糟糕的概括=>很高兴你已经发现缺乏培训数据覆盖率,并获得更多培训/验证数据。你有培训和验证准确性曲线图吗?我想知道你的数据是否有过度拟合。我是机器学习新手,让我检查一下如何创建这个问题的图,并会让你知道。你能给我推荐一些链接吗?糟糕的概括=>很高兴你已经发现缺乏培训数据覆盖率,并且获得了更多的培训/验证数据。对于我来说,培训和测试集是平均分布的。这是每堂课的25%。您是否尝试过在培训和测试集中使用相同的数据扩充?我看到您使用的是两种不同的数据元。不,我没有尝试,但当我将历元增加到25时,我的代码给出了相同的精度和准确的结果。对于我来说,训练集和测试集是均匀分布的。这是每堂课的25%。您是否尝试过在培训和测试集中使用相同的数据扩充?我知道你使用的是两种不同的数据元。不,我没有尝试过,但当我将历元增加到25时,我的代码给出了相同的精度和准确的结果。