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