我已经使用opencv创建了一些图像,并且正在其上运行深度神经网络分类器。 它提供了大约97%的准确度和95%的val_accuracy,但是当我对其进行测试时,它给出了错误的预测。
这是我创建图像的代码。
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.添加转换层。
任何人都可以建议我我在做什么错。
谢谢。
答案 0 :(得分:1)
此问题的最可能原因是您的测试集和训练集不是来自同一样本。这在分类问题中很常见。训练之前,您应该比较训练和测试集的类分布和特征分布。如果它们彼此之间距离不太近,则从训练集中学习到的规则不会推广到测试集中。
例如,训练集的班级分布是第一班的 70%,第二班的 20%和第三班的 10%。交叉验证来自训练集,该模型具有较高的训练和交叉验证精度。但是,如果测试集类别的分布类似于 10%类别1, 20%类别2和 70%类别,则该模型可能效果不佳3。
答案 1 :(得分:1)
此问题的另一个可能原因是过度拟合 因为您获得了很高的培训和验证准确性 常用的方法是:
交叉验证:查找样本外预测误差的标准方法是使用5倍交叉验证。 提前停止:它的规则为我们提供了指导,指导他们在学习者开始过度适应之前可以运行多少次迭代。 修剪:修剪在构建相关模型时被广泛使用。它只是删除了节点,这些节点对于手头的问题几乎没有增加预测能力。 正则化::它引入了一个成本项,目的是引入具有目标功能的更多功能。因此,它试图将许多变量的系数推为零,从而减少成本项。