Spaces:
Sleeping
Sleeping
| import tensorflow as tf | |
| import numpy as np | |
| import cv2 | |
| from PIL import Image | |
| import json | |
| # Constants | |
| IMG_SIZE = 240 | |
| MODEL_PATH = "model/efficientnetb1_plant_final.weights.h5" | |
| CLASS_NAMES_PATH = "model/class_names.json" | |
| # Load CLASS_NAMES | |
| with open(CLASS_NAMES_PATH, "r") as f: | |
| CLASS_NAMES = json.load(f) | |
| # Build model EXACTLY like in training | |
| base_model = tf.keras.applications.EfficientNetB1( | |
| include_top=False, | |
| weights="imagenet", | |
| input_shape=(IMG_SIZE, IMG_SIZE, 3) | |
| ) | |
| base_model.trainable = True | |
| model = tf.keras.Sequential([ | |
| base_model, | |
| tf.keras.layers.GlobalAveragePooling2D(), | |
| tf.keras.layers.Dropout(0.2), | |
| tf.keras.layers.Dense(len(CLASS_NAMES), activation='softmax') | |
| ]) | |
| # Load weights | |
| model.load_weights(MODEL_PATH) | |
| # Preprocess image | |
| def preprocess_image(image_path): | |
| img = tf.keras.preprocessing.image.load_img(image_path, target_size=(IMG_SIZE, IMG_SIZE)) | |
| img_array = tf.keras.preprocessing.image.img_to_array(img) / 255.0 | |
| return np.expand_dims(img_array, axis=0) | |
| # Grad-CAM | |
| def generate_gradcam(img_path, model, class_index, layer_name="efficientnetb1"): | |
| img_array = preprocess_image(img_path) | |
| grad_model = tf.keras.models.Model( | |
| [model.inputs], | |
| [model.get_layer(layer_name).output, model.output] | |
| ) | |
| with tf.GradientTape() as tape: | |
| conv_outputs, predictions = grad_model(img_array) | |
| loss = predictions[:, class_index] | |
| grads = tape.gradient(loss, conv_outputs)[0] | |
| pooled_grads = tf.reduce_mean(grads, axis=(0, 1)) | |
| conv_outputs = conv_outputs[0] | |
| heatmap = tf.reduce_sum(conv_outputs * pooled_grads, axis=-1) | |
| heatmap = np.maximum(heatmap, 0) | |
| heatmap /= tf.math.reduce_max(heatmap) + 1e-6 | |
| heatmap = heatmap.numpy() | |
| # Overlay heatmap | |
| img = cv2.imread(img_path) | |
| img = cv2.resize(img, (IMG_SIZE, IMG_SIZE)) | |
| heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) | |
| heatmap = np.uint8(255 * heatmap) | |
| heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) | |
| superimposed_img = heatmap * 0.4 + img | |
| result_img = Image.fromarray(np.uint8(superimposed_img)) | |
| return result_img | |
| # Inference | |
| def predict_plant_disease(image_path): | |
| img_array = preprocess_image(image_path) | |
| preds = model.predict(img_array)[0] | |
| class_index = int(np.argmax(preds)) | |
| confidence = float(preds[class_index]) | |
| label = CLASS_NAMES[class_index] | |
| return {label: confidence} | |
| ''' gradcam_img = generate_gradcam(image_path, model, class_index) | |
| we will disable gradcam for now, we need to rebuild the model in kaggle using functional API to for this to work''' | |
| ''' def build_model(num_classes=15): | |
| inputs = tf.keras.Input(shape=(240, 240, 3)) | |
| base_model = tf.keras.applications.EfficientNetB1(include_top=False, weights='imagenet', input_tensor=inputs) | |
| x = tf.keras.layers.GlobalAveragePooling2D()(base_model.output) | |
| x = tf.keras.layers.Dropout(0.2)(x) | |
| outputs = tf.keras.layers.Dense(num_classes, activation='softmax')(x) | |
| return tf.keras.Model(inputs=inputs, outputs=outputs) | |
| model = build_model() | |
| model.load_weights("model/efficientnetb1_plant_final.weights.h5")''' | |