Chen Du
Chen Du

Reputation: 130

ValueError: Error when checking input: expected flatten_input to have 3 dimensions, but got array with shape (22, 12)

I am new to Tensorflow, I am trying to do text recognize for image(size 12x22) using tensorflow. Training model seems to be ok, but when do prediction, there is error:

  File "C:\Python\Python36\lib\site-packages\tensorflow\python\keras\engine\training_utils.py", line 316, in standardize_input_data
    'with shape ' + str(data_shape))
ValueError: Error when checking input: expected flatten_input to have 3 dimensions, but got array with shape (22, 12)

I don't know why it needs 3 dimension while I just input a image in 2D.

train_model.py, this is the trainer, export a training model

import cv2
import pickle
import os.path
import numpy as np
from imutils import paths
import tensorflow as tf
# from sklearn.preprocessing import LabelBinarizer
# from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
# from keras.layers.convolutional import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Flatten, Dense

import image_fit

LETTER_IMAGES_FOLDER = "training_generate/divided_sample"
MODEL_FILENAME = "captcha_model.hdf5"
MODEL_LABELS_FILENAME = "model_labels.dat"


# initialize the data and labels
data = []
labels = []

# loop over the input images
print('Read images')
for image_file in paths.list_images(LETTER_IMAGES_FOLDER):
    # Load the image and convert it to grayscale
    image = cv2.imread(image_file)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # resize the image as 12, 22
    image = image_fit.resize_to_fit(image, 12, 22)

    # Grab the name of the letter based on the folder it was in
    label = image_file.split(os.sep)[-2]
    label = chr(int(label))
    # Add the letter image and it's label to our training data
    data.append(image)
    labels.append(label)

print('Done reading')
data = tf.keras.utils.normalize(np.array(data), axis=1)
# print(data[0])
labels = np.array(labels)

model = Sequential()
model.add(Flatten(input_shape=(22, 12)))
model.add(Dense(128, activation=tf.nn.relu))
model.add(Dense(128, activation=tf.nn.relu))
model.add(Dense(62, activation=tf.nn.softmax))

model.compile(optimizer='Adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(data, labels, epochs=3)
print('Finish training')

# val_loss, val_acc = model.evaluate()
model.save(MODEL_FILENAME)

solve.py, this is the python script that solve the letter.

import cv2
import pickle
import os.path
import numpy as np
from imutils import paths
import tensorflow as tf

import image_fit


LETTER_IMAGES_FOLDER = "training_generate/divided_sample"
MODEL_FILENAME = "captcha_model.hdf5"
MODEL_LABELS_FILENAME = "model_labels.dat"

image_file = 'test_0.bmp'
image = cv2.imread(image_file)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = image_fit.resize_to_fit(image, 12, 22)

new_model = tf.keras.models.load_model(MODEL_FILENAME)
predicitions = new_model.predict(image)
print(np.argmax(predicitions[0]))

Upvotes: 0

Views: 3833

Answers (2)

Chen Du
Chen Du

Reputation: 130

According to Kruger's answer, the code should be look like this:

    image_file = 'test_0.bmp'
    image = cv2.imread(image_file)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    image = image_fit.resize_to_fit(image, 12, 22)

    data = [image]

    new_model = tf.keras.models.load_model(MODEL_FILENAME)
    predicitions = new_model.predict(np.array(data))
    print(np.argmax(predicitions[0]))

Upvotes: 0

A Kruger
A Kruger

Reputation: 2419

When you make the prediction with the line

predicitions = new_model.predict(image)

it is expecting the first dimension to be the number of images in the batch. Since you only have one image, the first dimension would be of size one. You could resize the image to be (1,22,12), and this would pass:

predicitions = new_model.predict(image.reshape(1,22,12))

Upvotes: 1

Related Questions