{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import efficientnet.keras as efn\n\n# Standard ImageNet weights\nmodel = efn.EfficientNetB3(weights=\"imagenet\", include_top=False, input_shape=(300,300,3))\n\n# Or Noisy Student weights\nbase = efn.EfficientNetB3(weights=\"noisy-student\", include_top=False, input_shape=(300,300,3))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-09-04T22:50:28.815094Z","iopub.execute_input":"2025-09-04T22:50:28.816036Z","iopub.status.idle":"2025-09-04T22:50:52.489406Z","shell.execute_reply.started":"2025-09-04T22:50:28.815999Z","shell.execute_reply":"2025-09-04T22:50:52.488643Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import efficientnet.keras as efn\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport numpy as np\nimport tensorflow as tf\nimport keras.backend as K\nimport os\n\n# -------------------------------\n# 1. Fix Keras backend issue\n# -------------------------------\nif not hasattr(K, \"sigmoid\"):\n    K.sigmoid = tf.nn.sigmoid\n\n# -------------------------------\n# 2. Load EfficientNetB3 backbone\n# -------------------------------\nbase = efn.EfficientNetB3(weights=\"noisy-student\", include_top=False, input_shape=(300,300,3))\nbase.trainable = False   # freeze base for stage 1\n\n# -------------------------------\n# 3. Add custom classification head (5 classes for DR)\n# -------------------------------\nx = GlobalAveragePooling2D()(base.output)\nx = Dropout(0.5)(x)\nout = Dense(5, activation=\"softmax\")(x)\n\nmodel = Model(inputs=base.input, outputs=out)\n\n# -------------------------------\n# 4. Compile model\n# -------------------------------\nmodel.compile(optimizer=Adam(learning_rate=1e-3),\n              loss=\"categorical_crossentropy\",\n              metrics=[\"accuracy\"])\n\nmodel.summary()\n\n# -------------------------------\n# 5. Option A: REAL TRAINING (if you have dataset)\n# -------------------------------\nDATASET_PATH = \"/kaggle/input/aptos2019-blindness-detection/train_images\"\nCSV_PATH = \"/kaggle/input/aptos2019-blindness-detection/train.csv\"\n\nif os.path.exists(DATASET_PATH):\n    import pandas as pd\n    from sklearn.model_selection import train_test_split\n\n    # Load CSV\n    # Load CSV\n    df = pd.read_csv(CSV_PATH)\n    df['id_code'] = df['id_code'].apply(lambda x: f\"{x}.png\")\n\n    # Convert diagnosis to string for flow_from_dataframe\n    df['diagnosis'] = df['diagnosis'].astype(str)\n\n    # Split train/val\n    train_df, val_df = train_test_split(df, test_size=0.2, stratify=df['diagnosis'], random_state=42)\n\n\n    # Generators\n    train_datagen = ImageDataGenerator(rescale=1./255)\n    val_datagen = ImageDataGenerator(rescale=1./255)\n\n    train_generator = train_datagen.flow_from_dataframe(\n        dataframe=train_df,\n        directory=DATASET_PATH,\n        x_col=\"id_code\",\n        y_col=\"diagnosis\",\n        target_size=(300, 300),\n        batch_size=16,\n        class_mode=\"categorical\"\n    )\n\n    val_generator = val_datagen.flow_from_dataframe(\n        dataframe=val_df,\n        directory=DATASET_PATH,\n        x_col=\"id_code\",\n        y_col=\"diagnosis\",\n        target_size=(300, 300),\n        batch_size=16,\n        class_mode=\"categorical\"\n    )\n\n\n    history = model.fit(train_generator,\n                        validation_data=val_generator,\n                        epochs=5)\n\n# -------------------------------\n# 5. Option B: MOCK TRAINING (using single image duplicated)\n# -------------------------------\nelse:\n    print(\"⚠️ No dataset found, running mock training with a single image...\")\n\n    # Load your retina image\n    img_path = r\"C:\\Users\\ghane\\Downloads\\1bb0ddfe753a.png\"\n    img = image.load_img(img_path, target_size=(300, 300))\n    img_array = image.img_to_array(img) / 255.0\n    img_array = np.expand_dims(img_array, axis=0)\n\n    # Create fake dataset (duplicate same image with random labels)\n    X_fake = np.vstack([img_array for _ in range(20)])\n    y_fake = tf.keras.utils.to_categorical(np.random.randint(0, 5, 20), num_classes=5)\n\n    # Train only on fake data (to test pipeline)\n    history = model.fit(X_fake, y_fake, epochs=3, batch_size=4)\n\n# -------------------------------\n# 6. Fine-tuning (Stage 2)\n# -------------------------------\nprint(\"\\n🔓 Unfreezing EfficientNet base for fine-tuning...\")\nbase.trainable = True\nmodel.compile(optimizer=Adam(learning_rate=1e-5),\n              loss=\"categorical_crossentropy\",\n              metrics=[\"accuracy\"])\n\n# Run one fine-tuning epoch (mock or real)\nif os.path.exists(DATASET_PATH):\n    history_fine = model.fit(train_generator,\n                             validation_data=val_generator,\n                             epochs=3)\nelse:\n    history_fine = model.fit(X_fake, y_fake, epochs=2, batch_size=4)\n\n# -------------------------------\n# 7. Test prediction on a single image\n# -------------------------------\npreds = model.predict(img_array)\nprint(\"Raw probabilities:\", preds)\nprint(\"Predicted class index:\", np.argmax(preds))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T23:03:46.944637Z","iopub.execute_input":"2025-09-04T23:03:46.945321Z","iopub.status.idle":"2025-09-05T01:47:20.922644Z","shell.execute_reply.started":"2025-09-04T23:03:46.945291Z","shell.execute_reply":"2025-09-05T01:47:20.917150Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-05T11:08:36.385935Z","iopub.execute_input":"2025-09-05T11:08:36.386290Z","iopub.status.idle":"2025-09-05T11:08:50.083546Z","shell.execute_reply.started":"2025-09-05T11:08:36.386263Z","shell.execute_reply":"2025-09-05T11:08:50.082318Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}