首页 > 解决方案 > My model (CNN) predicts the same for everything

问题描述

hope you all have a great day. I´ve been working on a CNN type model that works as a FaceID, my data was only pictures of me, the model has no error, but when I predict it always give me the same output for everything(it says 100 percent for every face, even is not me), i think it is the Y value, but im not sure. What i want is the output to be wether is ME or OTHER. Here is my code

# Face ID project, using CNN tensorflow
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.optimizers import Adam 
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D, BatchNormalization, Activation
from tensorflow.keras import backend as K
import numpy as np
import cv2  
import glob

# Preparing the data and parameters
epochs = 100
lr = 1e-3
batch_size = 64 
img_dims = (96,96,3)

data = []
labels = []

image_files = glob.glob("C:/Users/berna/Desktop/Programming/AI_ML_DL/Projects/FaceID/Data/*")

for img in image_files:
    image = cv2.imread(img)

    image = cv2.resize(image, (img_dims[0], img_dims[1]))
    image = img_to_array(image)

    data.append(image)

    if img == img:
        label = 1
    else:
        label = 0
    
    labels.append([label])
    

# Preproccesing the data (convert arrays)
data = np.array(data, dtype="float32") / 255.0
labels = np.array(labels)

X = data 
y = labels

def build(width, height, depth, classes):
    model = Sequential()
    inputShape = height, width, depth 
    chanDim = -1

    if K.image_data_format() == "channels_first":
        inputShape = depth, height, width 
        chanDim = 1

    
    # Creating the model
    model.add(Conv2D(32, (3,3), padding="same", input_shape=inputShape))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))
    model.add(MaxPooling2D(pool_size=(3,3)))
    model.add(Dropout(0.25))

    model.add(Conv2D(64, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))

    model.add(Conv2D(64, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(128, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))

    model.add(Conv2D(128, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Flatten())
    model.add(Dense(1024))
    model.add(Activation("relu"))
    model.add(BatchNormalization())
    model.add(Dropout(0.5))

    model.add(Dense(1))
    model.add(Activation("sigmoid"))

    return model

# Build the model call 
model = build(width=img_dims[0], height=img_dims[1], depth=img_dims[2], classes=1)

# compile the model
opt = Adam(lr=lr, decay=lr/epochs)
model.compile(loss="binary_crossentropy",
            optimizer=opt,
            metrics=['accuracy'])

# fitting the model
H = model.fit(X, y, batch_size=batch_size,
                    epochs=epochs, verbose=1)

model.save('faceid.model')

Any Idea what is going on?

EDIT Si modified my code and dataset, and now other = 1 and me = 0 but the at the moment of prediction, it still predict only one here is my code

# Face ID project, using CNN tensorflow
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.optimizers import Adam 
from tensorflow.keras.models import Sequential
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D, BatchNormalization, Activation
from tensorflow.keras import backend as K
import numpy as np
import random
import cv2  
import glob
import os

# Preparing the data and parameters
epochs = 100
lr = 1e-3
batch_size = 64 
img_dims = (96,96,3)

data = []
labels = []

image_files = [f for f in glob.glob("C:/Users/berna/Desktop/Programming/AI_ML_DL/Projects/FaceID/Data"+"/**/*", recursive=True) if not os.path.isdir(f)]
random.shuffle(image_files)

for img in image_files:
    image = cv2.imread(img)

    image = cv2.resize(image, (img_dims[0], img_dims[1]))
    image = img_to_array(image)

    data.append(image)

    label = img.split(os.path.sep)[-2]
    if label == "Other":
        label = 1
    else:
        label = 0
    
    labels.append([label])
    

# Preproccesing the data (convert arrays)
data = np.array(data, dtype="float32") / 255.0
labels = np.array(labels)

X = data 
y = to_categorical(labels, num_classes=2)

def build(width, height, depth, classes):
    model = Sequential()
    inputShape = height, width, depth 
    chanDim = -1

    if K.image_data_format() == "channels_first":
        inputShape = depth, height, width 
        chanDim = 1

    
    # Creating the model
    model.add(Conv2D(32, (3,3), padding="same", input_shape=inputShape))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))
    model.add(MaxPooling2D(pool_size=(3,3)))
    model.add(Dropout(0.25))

    model.add(Conv2D(64, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))

    model.add(Conv2D(64, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(128, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))

    model.add(Conv2D(128, (3,3), padding="same"))
    model.add(Activation("relu"))
    model.add(BatchNormalization(axis=chanDim))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Flatten())
    model.add(Dense(1024))
    model.add(Activation("relu"))
    model.add(BatchNormalization())
    model.add(Dropout(0.5))

    model.add(Dense(classes))
    model.add(Activation("sigmoid"))

    return model

# Build the model call 
model = build(width=img_dims[0], height=img_dims[1], depth=img_dims[2], classes=2)

# compile the model
opt = Adam(lr=lr, decay=lr/epochs)
model.compile(loss="binary_crossentropy",
            optimizer=opt,
            metrics=['accuracy'])

# fitting the model
H = model.fit(X, y, batch_size=batch_size,
                    epochs=epochs, verbose=1)

model.save('faceid.model')

标签: pythonmachine-learningdeep-learningconv-neural-network

解决方案


The answer is inside your question. You say your data was only pictures of you. That means you trained the model using photos with the same label y = 1. So it's logical that the model will always predict y = 1. If you want the model to distinguish between photos of you and photos of other people, you must train the model using both photos of you as well as photos of other people, and set y = 1 for your photos, and y = 0 for other people's photos.

Note: In your code, this if condition always returns true:

if img == img:
    label = 1

Because img is equal to itself, the label will always = 1.


推荐阅读