Ali-Hyder2019/ali_hyder_Assignment
0
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)