Keras val_acc и model.evaluate acc не совпадают - PullRequest
1 голос
/ 03 ноября 2019

Я использую Python 3.6.9 (Anaconda), keras 2.2.4 и тензор потока 1.10.0, чтобы создать двоичный классификатор, используя частичные данные из набора данных celebA. Мои файлы разделены следующим образом:

                  dataset
           __________|_________
          |                    |
    training_set        validation_set
     _____|_____          _____|_____
    |           |        |           |
   men        women     men         women
    |           |        |           |
   40k         40k       4k          4k

Выполнение моего кода, который я получаю (например, для 2 эпох):

Using TensorFlow backend. 
Found 80000 images belonging to 2 classes.
Found 8000 images belonging to 2 classes.
Class weights:  {0: 1.0, 1: 1.0}

Epoch 1/2
1250/1250 [==============================] - 341s 273ms/step - loss: 0.3103 - acc: 0.8662 - val_loss: 0.2502 - val_acc: 0.9005

Epoch 2/2
1250/1250 [==============================] - 346s 276ms/step - loss: 0.2094 - acc: 0.9152 - val_loss: 0.2133 - val_acc: 0.9129

8000/8000 [==============================] - 9s 1ms/step
[8.048886075259292, 0.500625]

Проблема в том, что val_acc достигает 0,9, и в соответствии сЯ получаю только 0,5 (понятно). Набор, модель и веса, используемые для проверки, являются теми же, что используются для оценки, но они дают совершенно разные значения, почему?

Другое дело, с такой простой сетью, как поезд, достигающий 0,86 с однимэпоха? Является ли это значение достоверным?

Вот мой код:

import os
import numpy as np
import keras
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers import Dense, Flatten
from keras.preprocessing.image import ImageDataGenerator
from keras.preprocessing import image
from keras.applications.mobilenet import preprocess_input
from keras.optimizers import Adam
from keras.layers.normalization import BatchNormalization
from keras.models import Sequential
import cv2
from keras.models import model_from_json
import psutil

p = psutil.Process(os.getpid())

try:

    p.nice(19) #Ubuntu

except:

    p.nice(psutil.HIGH_PRIORITY_CLASS) #Windows

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

HEIGHT = 128
WIDTH = 128

def prepare_image(file):
    img_path = ''
    img = image.load_img(img_path + file, target_size=(HEIGHT, WIDTH))
    img_array = image.img_to_array(img)
    img_array_expanded_dims = np.expand_dims(img_array, axis=0)
    return keras.applications.mobilenet.preprocess_input(img_array_expanded_dims)


model = Sequential()
model.add(Conv2D(32, (3, 3) , padding='same', activation='relu', input_shape=(HEIGHT,WIDTH,3)))
model.add(Conv2D(64, (3, 3) , padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(BatchNormalization())

model.add(Dense(128, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

opt = Adam(lr = 0.0001)

train_datagen=ImageDataGenerator(preprocessing_function=preprocess_input,
    rotation_range=20,
    zoom_range=0.2,
    shear_range=0.2,
    horizontal_flip=True,
    rescale=1./255
    )

valid_datagen=ImageDataGenerator(preprocessing_function=preprocess_input,
    rescale=1./255)

train_generator=train_datagen.flow_from_directory('dataset/training_set',
    target_size=(HEIGHT,WIDTH),
    color_mode='rgb',
    batch_size=64,
    class_mode='binary',
    )

valid_generator=valid_datagen.flow_from_directory('dataset/validation_set',
    target_size=(HEIGHT,WIDTH),
    color_mode='rgb',
    batch_size=64,
    class_mode='binary'
    )

step_size_train=train_generator.n//train_generator.batch_size
step_size_valid=valid_generator.n//valid_generator.batch_size

model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])

from collections import Counter
itemCt = Counter(train_generator.classes)
maxCt = float(max(itemCt.values()))
cw = {clsID : maxCt/numImg for clsID, numImg in itemCt.items()}

print("Class weights: ", cw)

model.fit_generator(
    train_generator,
    steps_per_epoch = step_size_train,
    validation_data = valid_generator,
    validation_steps = step_size_valid,
    epochs=2,
    verbose = 1,
    class_weight=cw
    )


model_json = model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)

model.save_weights("model.h5")

def load_data():

    path = os.getcwd() + "\\dataset\\validation_set\\"
    lista = os.listdir(path)
    lista.sort()

    data = []
    pred = []

    for i in range(len(lista)):

        listb = os.listdir(path+lista[i])
        listb.sort()

        for j in listb:

            pic = cv2.imread(path+lista[i]+"/"+j)
            pic = cv2.resize(pic, (HEIGHT,WIDTH)) / 255.
            data.append(pic)

            pred.append(i)


    data = np.asarray(data)
    pred = np.asarray(pred)

    return data, pred

data, pred = load_data()

def load_model():

    json_file = open('model.json', 'r')
    loaded_model_json = json_file.read()
    json_file.close()

    loaded_model = model_from_json(loaded_model_json)
    loaded_model.load_weights("model.h5")
    loaded_model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])

    return loaded_model

loaded_model = load_model()

result = loaded_model.evaluate(data, pred)
print(result)

Я отредактировал с предложенными исправлениями, но все еще с той же проблемой. Правильно ли я загружаю модель?

1 Ответ

0 голосов
/ 04 ноября 2019

В вашем коде

valid_generator=train_datagen.flow_from_directory('dataset/validation_set',
    target_size=(HEIGHT,WIDTH),
    color_mode='rgb',
    batch_size=64,
    class_mode='binary'
    )

valid_datagen должен идти здесь, вместо train_datagen .

Также я думаю, что при вызове load_data () вы не масштабируете свои данные на 1./255, что вы делаете во время обучения и проверки.
Это должно решить вашу проблему,

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