Joshua Potts
Joshua Potts

Reputation: 13

Keras image classification network always predicting one class, and stays at 50% accuracy

I've been working on a Keras network to classify images as to whether they contain traffic lights or not, but so far I've had 0 success. I have a dataset of 11000+ images, and for my first test I used 240 images (or rather, text files for each image with the grayscale pixel values). There is only one output - a 0 or 1 saying whether the image contains traffic lights.

However, when I ran the test, it only predicted one class. Given that 53/240 images had traffic lights, it was achieving about a 79% accuracy rate because it was just predicting 0 all the time. I read that this might be down to inbalanced data, so I downscaled to just 4 images - 2 with traffic lights, 2 without.

Even with this test, it still stuck at 50% accuracy after 5 epochs; it's just predicting one class! Similar questions have been answered but I haven't found anything that is working for me :(

Here is the code I am using:

from keras.datasets import mnist
from keras import models
from keras import layers
from keras.utils import to_categorical
import numpy as np
import os

train_images = []
train_labels = []

#The following is just admin tasks - extracting the grayscale pixel values
#from the text files, adding them to the input array. Same with the labels, which
#are extracted from text files and added to output array. Not important to performance. 

for fileName in os.listdir('pixels1/'):
    newRead = open(os.path.join('pixels1/', fileName))

    currentList = []
    for pixel in newRead:
        rePixel = int(pixel.replace('\n', ''))/255
        currentList.append(rePixel)
    train_images.append(currentList)

        
for fileName in os.listdir('labels1/'):
    newRead = open(os.path.join('labels1/', fileName))
    line = newRead.readline()
    train_labels.append(int(line))

train_images = np.array(train_images)
train_labels = np.array(train_labels)

train_images = train_images.reshape((4,13689))

#model

model = models.Sequential()

model.add(layers.Dense(13689, input_dim=13689, activation='relu'))
model.add(layers.Dense(13689, activation='relu'))
model.add(layers.Dense(1, activation='softmax'))

model.compile(optimizer='adam',
                loss='categorical_crossentropy',
                metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=5, batch_size=1)

I was hoping at the very least it would be able to recognise the images at the end. I really want to move onto running a training session on my full 11,000 examples, but at this point I can't get it to work with 4.

Upvotes: 0

Views: 368

Answers (1)

desertnaut
desertnaut

Reputation: 60378

Rough points:

  1. You seem to believe that the number of units in your dense layers should be equal to your data dimension (13869); this is not the case. Change both of them to something smaller (in the range of 100-200) - they do not even have to be equal. A model that big is not recommended with your relatively small number of data samples (images).

  2. Since you are in a binary classification setting with a single node in your last layer, you should use activation=sigmoid for this (last) layer, and compile your model with loss='binary_crossentropy'.

  3. In imaging applications, normally the first couple of layers are convolutional ones.

Upvotes: 1

Related Questions