CoolFace
Apppublic

Ali-Hyder2019/ali_hyder_Assignment

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
app.py213 linesDownload Raw Back to root
1import gradio as gr2import numpy as np3from PIL import Image4import matplotlib.pyplot as plt5import io6from sklearn.datasets import fetch_openml7from sklearn.naive_bayes import BernoulliNB8from sklearn.preprocessing import Binarizer9from sklearn.metrics import accuracy_score10 11print("๐Ÿš€ Starting MNIST Digit Classifier...")12 13# Train model directly14try:15    print("๐Ÿ”„ Loading MNIST dataset...")16    mnist = fetch_openml('mnist_784', version=1, as_frame=False, parser='auto')17    X, y = mnist["data"][:2000], mnist["target"][:2000].astype(int)18    19    print("๐Ÿ”„ Training Bernoulli Naive Bayes...")20    binarizer = Binarizer(threshold=127.0)21    X_bin = binarizer.fit_transform(X)22    23    model = BernoulliNB()24    model.fit(X_bin, y)25    26    # Calculate accuracy27    y_pred = model.predict(X_bin)28    accuracy = accuracy_score(y, y_pred)29    print(f"โœ… Model trained! Accuracy: {accuracy*100:.2f}%")30    31except Exception as e:32    print(f"โŒ Training failed: {e}")33    model = None34    binarizer = Binarizer(threshold=127.0)35    accuracy = 0.8336 37def preprocess_image(image):38    """Convert drawing to MNIST format"""39    try:40        # Convert to numpy array if needed41        if isinstance(image, np.ndarray):42            image_array = image43        else:44            image_array = np.array(image)45        46        # Convert to grayscale if needed47        if len(image_array.shape) == 3:48            image_array = np.mean(image_array, axis=2)49        50        # Resize to 28x2851        pil_image = Image.fromarray(image_array.astype('uint8'))52        pil_image = pil_image.resize((28, 28))53        image_array = np.array(pil_image)54        55        # Invert colors (MNIST has white digits on black background)56        image_array = 255 - image_array57        58        # Flatten and binarize59        image_flat = image_array.flatten()60        image_bin = binarizer.transform([image_flat])61        62        return image_bin, image_array63    64    except Exception as e:65        print(f"Preprocessing error: {e}")66        return None, None67 68def predict_digit(image):69    """Predict digit from drawing"""70    if image is None:71        return "Please draw a digit (0-9) first! โœ๏ธ", None72    73    try:74        processed_image, processed_array = preprocess_image(image)75        76        if processed_image is None:77            return "Error processing image. Please try again. ๐Ÿ”„", None78        79        if model is None:80            return "Model not loaded. Please wait... โณ", None81        82        # Make prediction83        prediction = model.predict(processed_image)[0]84        probabilities = model.predict_proba(processed_image)[0]85        86        # Get top 3 predictions87        top_3_indices = np.argsort(probabilities)[-3:][::-1]88        top_3_probs = probabilities[top_3_indices]89        90        # Create visualization91        fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))92        93        # Show processed image94        ax1.imshow(processed_array, cmap='gray')95        ax1.set_title(f'Processed Image\nPrediction: {prediction}')96        ax1.axis('off')97        98        # Show probabilities99        colors = ['green' if i == prediction else 'blue' for i in range(10)]100        bars = ax2.bar(range(10), probabilities, color=colors, alpha=0.7)101        ax2.set_xlabel('Digits')102        ax2.set_ylabel('Probability')103        ax2.set_title('Prediction Probabilities')104        ax2.set_xticks(range(10))105        ax2.set_ylim(0, 1)106        107        # Add value labels108        for bar, prob in zip(bars, probabilities):109            height = bar.get_height()110            if height > 0.1:111                ax2.text(bar.get_x() + bar.get_width()/2., height,112                        f'{prob:.2f}', ha='center', va='bottom', fontsize=9)113        114        plt.tight_layout()115        116        # Convert plot to image117        buf = io.BytesIO()118        plt.savefig(buf, format='png', dpi=100, bbox_inches='tight')119        buf.seek(0)120        plot_image = Image.open(buf)121        plt.close()122        123        # Format results124        result_text = f"๐ŸŽฏ **Predicted Digit: {prediction}**\n\n"125        result_text += f"๐Ÿ“Š **Confidence: {probabilities[prediction]*100:.2f}%**\n\n"126        result_text += "๐Ÿ† **Top 3 Predictions:**\n"127        for i, (digit, prob) in enumerate(zip(top_3_indices, top_3_probs)):128            result_text += f"   {i+1}. Digit {digit}: {prob*100:.2f}%\n"129        130        return result_text, plot_image131    132    except Exception as e:133        return f"โŒ Error: {str(e)}", None134 135# Create Gradio interface - COMPLETELY FIXED VERSION136with gr.Blocks(137    theme=gr.themes.Soft(),138    title="MNIST Digit Classifier - Bernoulli Naive Bayes"139) as demo:140    141    gr.Markdown(f"""142    # โœ๏ธ MNIST Handwritten Digit Classifier143    ## ๐Ÿค– Bernoulli Naive Bayes | Accuracy: {accuracy*100:.2f}%144    145    **Upload an image of a digit (0-9) and see the AI prediction!**146    """)147    148    with gr.Row():149        with gr.Column(scale=1):150            gr.Markdown("### ๐Ÿ“ Upload Image")151            152            # โœ… FIXED: Simple Image upload without sources parameter153            image_input = gr.Image(154                label="Upload digit image (0-9)",155                type="numpy",156                height=300,157                width=300158            )159            160            with gr.Row():161                clear_btn = gr.Button("๐Ÿงน Clear")162                predict_btn = gr.Button("๐Ÿ” Predict Digit", variant="primary")163        164        with gr.Column(scale=1):165            gr.Markdown("### ๐Ÿ“Š Prediction Results")166            output_text = gr.Markdown(167                value="**Upload an image of a digit and click Predict!**"168            )169            170            gr.Markdown("### ๐Ÿ“ˆ Visualization")171            output_plot = gr.Image(172                label="Probability Distribution",173                height=300174            )175    176    # Instructions for drawing177    gr.Markdown("### ๐Ÿ’ก How to use:")178    gr.Markdown("""179    1. **Draw a digit** on paper or using any drawing app180    2. **Save as image** (PNG/JPG format)181    3. **Upload here** using the upload button above182    4. **Click Predict** to see results183    184    **Tips:**185    - Draw clear, centered digits186    - Use black ink on white background187    - Make digits large and clear188    """)189    190    gr.Markdown("---")191    gr.Markdown(f"""192    **Model Information:**193    - Algorithm: Bernoulli Naive Bayes194    - Dataset: MNIST Handwritten Digits195    - Accuracy: {accuracy*100:.2f}%196    - Input: 28ร—28 grayscale images197    """)198    199    # Button actions200    predict_btn.click(201        fn=predict_digit,202        inputs=image_input,203        outputs=[output_text, output_plot]204    )205    206    clear_btn.click(207        fn=lambda: [None, "**Cleared! Upload a new image.**", None],208        outputs=[image_input, output_text, output_plot]209    )210 211# Launch app212if __name__ == "__main__":213    demo.launch(server_name="0.0.0.0", server_port=7860)