Точность проверки CNN высока, но плоха в предсказаниях? - PullRequest
0 голосов
/ 23 февраля 2020

Я пытаюсь создать CNN, чтобы различать guish между 3 классами, которые являются подлинными лицами, печатными лицами и переигранными лицами. Я подготовил данные следующим образом:

classes = ['Genuine', 'Printed', 'Replay']

base_dir = '/Dataset'

import os
import numpy as np
import glob
import shutil

for cl in classes:
  img_path = os.path.join(base_dir, cl)
  images = glob.glob(img_path + '/*.jpg')
  print("{}: {} Images".format(cl, len(images)))
  num_train = int(round(len(images)*0.8))
  train, val = images[:num_train], images[num_train:]

  for t in train:
    if not os.path.exists(os.path.join(base_dir, 'train', cl)):
      os.makedirs(os.path.join(base_dir, 'train', cl))
    shutil.move(t, os.path.join(base_dir, 'train', cl))

  for v in val:
    if not os.path.exists(os.path.join(base_dir, 'val', cl)):
      os.makedirs(os.path.join(base_dir, 'val', cl))
    shutil.move(v, os.path.join(base_dir, 'val', cl))

from tensorflow.keras.preprocessing.image import ImageDataGenerator

image_gen_train = ImageDataGenerator(
                    rescale=1./255,
                    rotation_range=45,
                    width_shift_range=.15,
                    height_shift_range=.15,
                    horizontal_flip=True,
                    zoom_range=0.5
                    )

batch_size = 32
IMG_SHAPE = 96 
train_data_gen = image_gen_train.flow_from_directory(
                                                batch_size=batch_size,
                                                directory=train_dir,
                                                shuffle=True,
                                                target_size=(IMG_SHAPE,IMG_SHAPE),
                                                class_mode='sparse'
                                                )

Я построил простую модель, подобную следующей:

    ## Model
import tensorflow as tf
from keras import regularizers
from keras.layers.normalization import BatchNormalization

IMG_SHAPE = (96, 96, 3)
batch_size = 32

## Trainable classification head


aConv_layer = tf.keras.layers.Conv2D(576, (3, 3), padding="same", 
                                     activation="relu", input_shape= IMG_SHAPE)
aConv_layer = tf.keras.layers.Conv2D(144, (3, 3), padding="same", 
                                     activation="relu", input_shape= IMG_SHAPE)

gmaxPool_layer = tf.keras.layers.GlobalMaxPooling2D() #reduces input from 4D to 2D
maxPool_layer = tf.keras.layers.MaxPool2D(pool_size=(1, 1), strides=None, 
                                          padding='valid', data_format=None,
                                          )

batNor_layer = tf.keras.layers.BatchNormalization(axis=-1, momentum=0.99, 
                                                  epsilon=0.001, 
                                center=True, scale=True, 
                                beta_initializer='zeros', 
                                gamma_initializer='ones', 
                                moving_mean_initializer='zeros', 
                                moving_variance_initializer='ones', 
                                beta_regularizer=None, gamma_regularizer=None, 
                                beta_constraint=None, gamma_constraint=None)

flat_layer = tf.keras.layers.Flatten()

dense_layer = tf.keras.layers.Dense(9, activation='softmax', 
                                    kernel_regularizer=regularizers.l2(0.01))

prediction_layer = tf.keras.layers.Dense(3, activation='softmax')

model = tf.keras.Sequential([
     #base_model,
     tf.keras.layers.Conv2D(576, (3, 3), padding="same", activation="relu", input_shape= IMG_SHAPE),
     tf.keras.layers.Dense(288, activation='softmax', kernel_regularizer=regularizers.l2(0.01)),
     tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None),
     tf.keras.layers.Conv2D(144, (3, 3), padding="same", activation="relu"),
     tf.keras.layers.Dense(72, activation='softmax', kernel_regularizer=regularizers.l2(0.01)),
     tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None),
     #
     batNor_layer,
     gmaxPool_layer,
     tf.keras.layers.Flatten(),
     #tf.keras.layers.Dropout(0.5),
     prediction_layer                        
])

learning_rate = 0.001

## Compiles the model
model.compile(optimizer=tf.keras.optimizers.Adam(lr=learning_rate),
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy']
)

Я обучил модель и получил следующее, что я считаю отличным результаты:

CNN result

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

import numpy as np
from google.colab import files
from keras.preprocessing import image

uploaded = files.upload()
for fn in uploaded.keys():

# predicting images
  path = fn
  img = image.load_img(path, target_size=(96, 96))
  x = image.img_to_array(img)
  x = np.expand_dims(x, axis=0)
  images = np.vstack([x])
  classes = model.predict(images, batch_size=10)
print(fn)
print('Genuine | Printout | Replay')
print(np.argmax(classes))

Как прогнозы могут быть неверными, когда точность проверки так высока? Вот Codelab , если это поможет.

1 Ответ

2 голосов
/ 23 февраля 2020

Обрабатывайте изображения для прогнозирования так же, как вы обрабатывали изображения для обучения. В частности, измените масштаб ваших изображений, как вы сделали с ImageDataGenerator.

import numpy as np
from google.colab import files
from keras.preprocessing import image

uploaded = files.upload()
for fn in uploaded.keys():

# predicting images
  path = fn
  img = image.load_img(path, target_size=(96, 96))
  x = image.img_to_array(img)
  # Rescale image.
  x = x / 255.
  x = np.expand_dims(x, axis=0)
  images = np.vstack([x])
  classes = model.predict(images, batch_size=10)
print(fn)
print('Genuine | Printout | Replay')
print(np.argmax(classes))
...