|
import gradio as gr |
|
import numpy as np |
|
from PIL import Image, ImageOps |
|
import tensorflow as tf |
|
|
|
|
|
model = tf.keras.models.load_model("cnn_model.h5") |
|
|
|
def predict(image_array): |
|
try: |
|
|
|
if isinstance(image_array, dict) and 'composite' in image_array: |
|
|
|
image_array = image_array['composite'] |
|
|
|
if image_array is None or np.sum(image_array) == 0: |
|
return "Please draw a digit." |
|
|
|
|
|
image = Image.fromarray(image_array.astype("uint8"), mode="L") |
|
|
|
|
|
|
|
image = image.resize((28, 28), Image.LANCZOS) |
|
|
|
|
|
|
|
image = ImageOps.invert(image) |
|
|
|
|
|
image_array = np.array(image).astype("float32") / 255.0 |
|
image_array = image_array.reshape(1, 28, 28, 1) |
|
|
|
|
|
logits = model.predict(image_array, verbose=0) |
|
prediction = int(np.argmax(logits)) |
|
|
|
|
|
|
|
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)}" |
|
|
|
|
|
gr.Interface( |
|
fn=predict, |
|
inputs=gr.Sketchpad( |
|
image_mode="L", |
|
canvas_size=(280, 280), |
|
type="numpy", |
|
brush_radius=10, |
|
), |
|
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 |
|
|
|
|
|
model = tf.keras.models.load_model("digit_model(CNN).h5") |
|
|
|
def predict(image_array): |
|
try: |
|
|
|
if isinstance(image_array, dict) and 'composite' in image_array: |
|
|
|
image_array = image_array['composite'] |
|
|
|
if image_array is None or np.sum(image_array) == 0: |
|
return "Please draw a digit.", None |
|
|
|
|
|
original = Image.fromarray(image_array.astype("uint8"), mode="L") |
|
processed = original.resize((28, 28), Image.LANCZOS) |
|
processed = ImageOps.invert(processed) |
|
|
|
|
|
display_img = processed.resize((140, 140), Image.NEAREST) |
|
|
|
|
|
input_array = np.array(processed).astype("float32") / 255.0 |
|
input_array = input_array.reshape(1, 28, 28, 1) |
|
|
|
|
|
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 |
|
|
|
|
|
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 |