longhodac
fixed age dtection model and added some scripting files
bf32e4b
# --- imports ---
import os, time, hashlib
import numpy as np
import cv2
import tensorflow as tf
import matplotlib.pyplot as plt
from PIL import Image
from IPython.display import clear_output, display
from deepface import DeepFace
# --- config ---
IMG_PATH = "data/test_images/5_images_baby_cute_face/5.jpg"
TFLITE_PATH = "models/age_model_single_batch.tflite"
DETECTOR_BACKEND = "opencv" # try "retinaface" for better alignment, slower [page:0]
ALIGN = True
ENFORCE_DETECTION = True
def md5_file(path):
with open(path, "rb") as f:
return hashlib.md5(f.read()).hexdigest()
def softmax(x):
x = x - np.max(x)
e = np.exp(x)
return e / np.sum(e)
def show_inline(title, img_rgb):
# img_rgb: HxWx3 RGB uint8/float
clear_output(wait=True)
plt.figure(figsize=(4, 4))
plt.title(title)
plt.imshow(np.clip(img_rgb, 0, 255).astype(np.uint8))
plt.axis("off")
plt.show()
plt.close()
# --- sanity: confirm image really changes between runs ---
print("IMG_PATH:", IMG_PATH)
print("mtime:", os.path.getmtime(IMG_PATH))
print("md5:", md5_file(IMG_PATH))
# --- 1) detect/extract face crop with DeepFace ---
faces = DeepFace.extract_faces(
img_path=IMG_PATH,
detector_backend=DETECTOR_BACKEND,
align=ALIGN,
enforce_detection=ENFORCE_DETECTION,
)
print("faces found:", len(faces))
face_rgb = faces[0]["face"] # RGB numpy array from DeepFace.extract_faces [page:0]
# display the face crop so you can verify it's correct
show_inline("Extracted face (RGB)", face_rgb)
# --- 2) load TFLite interpreter ---
interpreter = tf.lite.Interpreter(model_path=TFLITE_PATH) # TFLite interpreter API [web:74]
interpreter.allocate_tensors()
inp = interpreter.get_input_details()[0]
out = interpreter.get_output_details()[0]
print("\nINPUT details:", {k: inp.get(k) for k in ["shape", "dtype", "quantization", "quantization_parameters"]})
print("OUTPUT details:", {k: out.get(k) for k in ["shape", "dtype", "quantization", "quantization_parameters"]})
# --- 3) preprocess to the model’s expected input ---
h, w = int(inp["shape"][1]), int(inp["shape"][2])
x = cv2.resize(face_rgb, (w, h), interpolation=cv2.INTER_AREA)
# common float model input: [0,1]
x = x.astype(np.float32) / 255.0
x = np.expand_dims(x, axis=0) # [1,H,W,3]
# if model is quantized, quantize using scale/zero_point
if inp["dtype"] in (np.uint8, np.int8):
scale, zero_point = inp["quantization"]
if scale == 0:
raise ValueError("Input scale is 0; quantization info looks invalid.")
x = (x / scale + zero_point).round().astype(inp["dtype"])
interpreter.set_tensor(inp["index"], x)
# --- 4) run inference ---
interpreter.invoke()
y = interpreter.get_tensor(out["index"])
print("\nraw output shape:", y.shape, "dtype:", y.dtype)
y1 = y.reshape(-1)
print("raw output (first 10):", y1[:10])
print("raw output sum:", float(np.sum(y1)))
# --- 5) decode output into an age ---
# Case A: 101-bin classifier (ages 0..100). If output isn't normalized, softmax it.
if y1.size == 101:
probs = y1
if not (0.99 <= probs.sum() <= 1.01):
probs = softmax(probs)
age = float(np.sum(probs * np.arange(101)))
print("\npredicted age (expected value over 0..100 bins):", age)
# Case B: regression scalar output
elif y1.size == 1:
print("\npredicted age (scalar regression):", float(y1[0]))
else:
print("\nUnhandled output size:", y1.size, "— tell me the model’s output meaning and I’ll adapt decoding.")