Reputation: 130
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
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
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