Точность последовательной модели Кераса плохая. Модель игнорирует / игнорирует класс

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

Проблема: программа отлично работает для двух классов, камень и бумага, но полностью терпит неудачу при получении тестового изображения "ножницы". Я пробовал увеличить свои тренировочные данные и еще кое-что, но безуспешно. Мне было интересно, есть ли у кого-нибудь идеи, как это компенсировать.

Примечание: я подозреваю, что это тоже как-то связано с переобучением. Я говорю это, потому что модель имеет точность 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

Заранее спасибо за любую помощь или идеи:)

1 ответ

Вы можете просто протестировать переоснащение, добавив 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, чтобы получить еще лучшую производительность.

Другие вопросы по тегам