Kashinath Patekar
Kashinath Patekar

Reputation: 1133

Tensorflow - Batch predict on multiple images

I have a faces list, where each element of list is a numpy array with shape ( 1, 224, 224, 3) , i.e., a face image. I have a model whose input shape is (None, 224, 224, 3) and output shape is (None, 2).

Now I want to get predictions on all images inside faces list. Sure, I can iterate over the list and get predictions one by one, but I want to process all the images as a batch, using only one call to model.predict() to get results faster.

If I pass the faces list directly as I am doing now (complete code at the end), I get predictions for only the first image.

print(f"{len(faces)} faces found")
print(faces[0].shape)
maskPreds = model.predict(faces)
print(maskPreds)

Output:

3 faces found
(1, 224, 224, 3)
[[0.9421933  0.05780665]]

But maskPreds for 3 images should be something like:

[[0.9421933  0.05780665], 
 [0.01584494 0.98415506], 
 [0.09914105 0.9008589 ]] 

The full code:

from tensorflow.keras.models import load_model
from cvlib import detect_face
import cv2
import numpy as np

def detectAllFaces(frame):
    dets = detect_face(frame)
    boxes = dets[0]
    confidences = dets[1]
    faces = []

    for box, confidence in zip(boxes, confidences):
        startX, startY, endX, endY = box
        cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 1)
        face = frame[startY:endY, startX:endX]
        face = cv2.resize(face, (224, 224))
        face = np.expand_dims(face, axis=0) # convert (224,224,3) to (1,224,224,3)
        faces.append(face)

    return faces, frame

model = load_model("mask_detector.model")
vs = cv2.VideoCapture(0)
model.summary()

while True:
    ret, frame = vs.read()
    if not ret:
        break            
    faces, frame = detectAllFaces(frame)

    if len(faces):
        print(f"{len(faces)} faces found")
        maskPreds = model.predict(faces) # <==========
        print(maskPreds) 

    cv2.imshow("Window", frame)
    if cv2.waitKey(1) == ord('q'):
        break

cv2.destroyWindow("Window")
vs.release()

Note: If I don't convert each image from (224, 224, 3) to ( 1, 224, 224, 3), tensorflow throws error saying that the input dimensions mismatch.

ValueError: Error when checking input: expected input_1 to have 4 dimensions, but got array with shape (224, 224, 3)

How do I achieve batch prediction?

Upvotes: 3

Views: 7379

Answers (1)

Kashinath Patekar
Kashinath Patekar

Reputation: 1133

The input to model.predict() function in this case needs to be given as a numpy array of shape (N, 224, 224, 3) where N is number of input images.

To achieve this, we can stack the N individual numpy arrays of size ( 1, 224, 224, 3) into one array of size ( N, 224, 224, 3) and then pass it to model.predict() function.

maskPreds = model.predict(np.vstack(faces))

Upvotes: 11

Related Questions