Моя модель имеет высокую точность и val_accuracy, но дает неверные результаты на тестовых данных - PullRequest
0 голосов
/ 21 июня 2019

Я создал несколько изображений, используя opencv, и я использую классификатор глубокой нейронной сети.Он дает точность около 97% и val_accuracy 95%, но когда я проверяю его, он дает неверные прогнозы.

Вот мой код для создания изображений.

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. Добавьте слой конв.

Любой, пожалуйста, подскажите, что я делаю не так.

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 21 июня 2019

Другая вероятная причина этой проблемы - переоснащение , поскольку вы получаете высокую точность обучения и проверки. Обычно используются следующие методологии:

Перекрестная проверка: СтандартЧтобы найти ошибку прогнозирования вне выборки, используйте 5-кратную перекрестную проверку. Ранняя остановка: Его правила дают нам руководство относительно того, сколько итераций может быть выполнено до того, как учащийся начнет чрезмерно соответствовать. Обрезка: Обрезка широко используется при построении связанных моделей.Он просто удаляет узлы, которые добавляют небольшую предсказательную силу для рассматриваемой проблемы. Регуляризация: Она вводит стоимостной термин для добавления большего количества функций с целевой функцией.Следовательно, он пытается подтолкнуть коэффициенты для многих переменных к нулю и, следовательно, уменьшить стоимость затрат.

1 голос
/ 21 июня 2019

Наиболее вероятная причина этой проблемы - ваш тестовый набор и тренировочный набор не из одного и того же образца. Это так часто встречается в задачах классификации. Перед началом обучения вы должны сравнить распределения классов и наборы функций учебных и тестовых наборов. Если они не близки друг к другу, правила, усвоенные на тренировочном наборе, не распространяются на тестовый набор.

Например, классы учебных наборов имеют следующие классы: 70% класса 1, 20% класса 2 и 10% класса 3. После перекрестной проверки Происходит из учебного набора, модель имеет высокую точность обучения и перекрестной проверки. Однако модель может не работать должным образом, если распределения классов тестового набора имеют вид 10% класс 1, 20% класс 2 и 70% класс 3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...