Keras顺序模型的准确性很差模型正在忽略/忽略课程

问题描述

小背景:我正在制作一个简单的石头,纸张,剪刀图像分类程序。基本上,我希望图像分类器能够区分岩石,纸张或剪刀图像。

问题:该程序对石头和纸两个类的效果都很好,但是只要给出剪刀测试图像,它就会完全失败。我尝试增加训练数据和其他一些东西,但是没有运气。我想知道是否有人对如何弥补这一点有任何想法。

旁注::我怀疑它也与过度拟合有关。我之所以这样说,是因为该模型的训练数据的准确性约为92%,而测试数据的准确性为55%。

import numpy as np
import os
import cv2
import random
import tensorflow as tf
from tensorflow import keras

CATEGORIES     = ['rock','paper','scissors']
IMG_SIZE       = 400  # The size of the images that your neural network will use
CLASS_SIZE     = len(CATEGORIES)
TRAIN_DIR  = "../Train/"

def loadData( directoryPath ):
    data = []
    for category in CATEGORIES:
        path = os.path.join(directoryPath,category)
        class_num = CATEGORIES.index(category)
        for img in os.listdir(path):
            try:
                img_array = cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)
                new_array = cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
                data.append([new_array,class_num])
            except Exception as e:
                pass
    return data


training_data = loadData(TRAIN_DIR)
random.shuffle(training_data)
X = [] #features
y = [] #labels

for i in range(len(training_data)):
    features = training_data[i][0]
    label    = training_data[i][1]
    X.append(features)
    y.append(label)

X = np.array(X)
y = np.array(y)
X = X/255.0

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(IMG_SIZE,IMG_SIZE)),keras.layers.Dense(128,activation='relu'),keras.layers.Dense(CLASS_SIZE)
])

model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])


model.fit(X,y,epochs=25)


TEST_DIR  = "../Test/"
test_data = loadData( TEST_DIR )
random.shuffle(test_data)
test_images = []
test_labels = []

for i in range(len(test_data)):
    features = test_data[i][0]
    label    = test_data[i][1]
    test_images.append(features)
    test_labels.append(label)

test_images = np.array(test_images)
test_images = test_images/255.0
test_labels = np.array(test_labels)

test_loss,test_acc = model.evaluate(test_images,test_labels,verbose=2)
print('\nTest accuracy:',test_acc)

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

model.save_weights("model.h5")
print("Saved model to disk")

model.save('CNN.model')

如果您想快速创建大量的训练数据:https://github.com/ThomasStuart/RockPaperScissorsMachineLearning/blob/master/source/0.0-collectMassiveData.py

首先感谢您的帮助或想法:)

解决方法

您可以简单地通过添加2个附加层,一个辍学层和一个密集层来测试过度拟合。另外,请确保在每个时期之后都对您的train_data进行改组,以便该模型保持学习的一般性。另外,如果我正确地看到了这一点,则说明您正在执行多类分类,但是在最后一层中没有softmax激活。我会建议您使用它。

使用drouput和softmax,您的模型将如下所示:

model = keras.Sequential([
keras.layers.Flatten(input_shape=(IMG_SIZE,IMG_SIZE)),keras.layers.Dense(128,activation='relu'),keras.layers.Dropout(0.4),#0.4 means 40% of the neurons will be randomly unused
keras.layers.Dense(CLASS_SIZE,activation="softmax")

])

最后的建议:CNN在这样的任务上总体上表现更好。您可能想切换到CNN网络,以获得更好的性能。