Nausad's picture
Upload 9 files
d7ab363 verified
import numpy as np
import tensorflow as tf
from flask import Flask, render_template, request, jsonify
from PIL import Image
import io
import base64
import os
app = Flask(__name__)
# Load the pre-trained MNIST model
print("Loading MNIST model...")
model_path = 'digit_model.h5'
if not os.path.exists(model_path):
print("Training improved model... this may take a few minutes")
# Load MNIST dataset
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# Normalize data
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
# Reshape for CNN
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)
# Data augmentation
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.2,
zoom_range=0.1,
fill_mode='nearest'
)
model = tf.keras.Sequential([
# First convolutional block
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1), padding='same'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Dropout(0.25),
# Second convolutional block
tf.keras.layers.Conv2D(64, (3, 3), activation='relu', padding='same'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu', padding='same'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Dropout(0.25),
# Third convolutional block
tf.keras.layers.Conv2D(128, (3, 3), activation='relu', padding='same'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Dropout(0.25),
# Flatten and dense layers
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(256, activation='relu'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
print("Training with data augmentation...")
model.fit(
datagen.flow(x_train, y_train, batch_size=64),
epochs=20,
validation_data=(x_test, y_test),
verbose=1
)
model.save(model_path)
print("Model trained and saved!")
else:
print("Loading saved model...")
model = tf.keras.models.load_model(model_path)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/predict', methods=['POST'])
def predict():
try:
# Get image data from request
data = request.json
image_data = data.get('image')
if not image_data:
return jsonify({'error': 'No image provided'}), 400
# Remove data URI prefix
if 'base64,' in image_data:
image_data = image_data.split('base64,')[1]
# Decode image
image_bytes = base64.b64decode(image_data)
image = Image.open(io.BytesIO(image_bytes)).convert('L')
# Resize to 28x28
image = image.resize((28, 28), Image.Resampling.LANCZOS)
# Convert to numpy array and normalize
image_array = np.array(image) / 255.0
# Make prediction
prediction = model.predict(np.array([image_array]), verbose=0)
predicted_digit = int(np.argmax(prediction[0]))
confidence = float(np.max(prediction[0])) * 100
# Get all predictions for visualization
all_predictions = {str(i): float(prediction[0][i]) * 100 for i in range(10)}
return jsonify({
'digit': predicted_digit,
'confidence': round(confidence, 2),
'all_predictions': all_predictions
})
except Exception as e:
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(debug=True, port=5000)