rezaenayati's picture
Update app.py
a8538e2 verified
raw
history blame
4.91 kB
import gradio as gr
import numpy as np
from PIL import Image, ImageOps
import tensorflow as tf
# Load the model
model = tf.keras.models.load_model("cnn_model.h5")
def predict(image_array):
try:
# Handle dictionary input format from newer Gradio versions
if isinstance(image_array, dict) and 'composite' in image_array:
# Extract the image data from the 'composite' key
image_array = image_array['composite']
if image_array is None or np.sum(image_array) == 0:
return "Please draw a digit."
# Create PIL image from array
image = Image.fromarray(image_array.astype("uint8"), mode="L")
# EMNIST digits dataset might need specific preprocessing
# Resize to 28x28 first
image = image.resize((28, 28), Image.LANCZOS)
# EMNIST may have different orientation than your drawing
# Try rotating/flipping if needed
image = ImageOps.invert(image) # Invert colors
# Convert to model input format - EXACTLY as in your training code
image_array = np.array(image).astype("float32") / 255.0
image_array = image_array.reshape(1, 28, 28, 1)
# Make prediction
logits = model.predict(image_array, verbose=0)
prediction = int(np.argmax(logits))
# Since your model uses linear activation and SparseCategoricalCrossentropy(from_logits=True),
# we need to apply softmax to get probabilities
confidence = float(tf.nn.softmax(logits)[0][prediction])
return f"Digit: {prediction} (confidence: {confidence:.2%})"
except Exception as err:
return f"Runtime error: {str(err)}"
# Create the interface with settings optimized for EMNIST
gr.Interface(
fn=predict,
inputs=gr.Sketchpad(
image_mode="L",
canvas_size=(280, 280), # Larger canvas
type="numpy",
brush_radius=10, # Thicker brush
),
outputs="text",
title="EMNIST Digit Classifier",
description="Draw a digit (0-9) in the center of the canvas. For best results with EMNIST, make your digit large and clear."
).launch()
This updated version should better match how your model was trained with the EMNIST dataset. EMNIST digits might have different characteristics than standard MNIST, which could affect how preprocessing should be done.
If you're still having accuracy issues, let's try to add a debug output that shows the processed image before it goes to the model. This will help us understand if the preprocessing is correct:
pythonimport gradio as gr
import numpy as np
from PIL import Image, ImageOps
import tensorflow as tf
# Load the model
model = tf.keras.models.load_model("digit_model(CNN).h5")
def predict(image_array):
try:
# Handle dictionary input format from newer Gradio versions
if isinstance(image_array, dict) and 'composite' in image_array:
# Extract the image data from the 'composite' key
image_array = image_array['composite']
if image_array is None or np.sum(image_array) == 0:
return "Please draw a digit.", None
# Process the image
original = Image.fromarray(image_array.astype("uint8"), mode="L")
processed = original.resize((28, 28), Image.LANCZOS)
processed = ImageOps.invert(processed)
# Create a copy for display (enlarged for visibility)
display_img = processed.resize((140, 140), Image.NEAREST)
# Convert to model input format
input_array = np.array(processed).astype("float32") / 255.0
input_array = input_array.reshape(1, 28, 28, 1)
# Make prediction
logits = model.predict(input_array, verbose=0)
prediction = int(np.argmax(logits))
confidence = float(tf.nn.softmax(logits)[0][prediction])
return f"Digit: {prediction} (confidence: {confidence:.2%})", display_img
except Exception as err:
return f"Runtime error: {str(err)}", None
# Create interface with image output for debugging
gr.Interface(
fn=predict,
inputs=gr.Sketchpad(
image_mode="L",
canvas_size=(280, 280),
type="numpy",
brush_radius=5,
),
outputs=[
"text",
gr.Image(type="pil", label="Processed Image (28x28)")
],
title="EMNIST Digit Classifier with Debug View",
description="Draw a digit (0-9). The right panel shows the actual 28x28 image being fed to the model."
).launch()
This version adds a visual debug output so you can see exactly what the model is receiving. This should help us diagnose why the accuracy is low. If the processed image doesn't look like a clear digit, we'll need to adjust the preprocessing steps.RetryClaude can make mistakes. Please double-check responses. 3.7 Sonnet