{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Importing Dependencies","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models, callbacks\nfrom tensorflow.keras.applications import EfficientNetB0\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.model_selection import train_test_split, KFold\nfrom sklearn.utils.class_weight import compute_class_weight\nfrom keras import backend as K\nimport gc\nimport pickle\n\n\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.TPUStrategy(tpu)\n    print(\"Running on TPU successfully!\")\nexcept ValueError:\n    strategy = tf.distribute.get_strategy()  \n    print(\"Running on CPU/GPU instead.\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Setting Hyperparameters and Paths","metadata":{}},{"cell_type":"code","source":"IMG_SIZE = (256, 256)\nBATCH_SIZE = 8\nEPOCHS = 20  \nTOTAL_EPOCHS = 200  \nLEARNING_RATE = 1e-4\nN_FOLDS = 10  \n\nDATA_DIR = '/kaggle/input/aptos2019-blindness-detection/train_images'\nCSV_PATH = '/kaggle/input/aptos2019-blindness-detection/train.csv'","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Preparing the Dataset","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(CSV_PATH)\ndf['id_code'] = df['id_code'].apply(lambda x: os.path.join(DATA_DIR, f\"{x}.png\"))\ndf['diagnosis'] = df['diagnosis'].astype(str)\n\ntrain_df, temp_df = train_test_split(df, test_size=0.2, random_state=42)\nval_df, test_df = train_test_split(temp_df, test_size=0.5, random_state=42)\ntest_df['diagnosis'] = test_df['diagnosis'].astype(int)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Data Augmentation and Class Weights","metadata":{}},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    rescale=1./255,\n    zoom_range=0.15,\n    horizontal_flip=True,\n    rotation_range=20,\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\n\nval_test_datagen = ImageDataGenerator(rescale=1./255)\n\nclass_weights = compute_class_weight(\n    class_weight='balanced',\n    classes=np.unique(df['diagnosis']),\n    y=df['diagnosis']\n)\nclass_weights = dict(enumerate(class_weights))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Training with Stratified K-Fold Cross Validation","metadata":{}},{"cell_type":"code","source":"kf = KFold(n_splits=N_FOLDS, shuffle=True, random_state=42)\nfold_no = 1\n\nfor train_index, val_index in kf.split(train_df):\n    print(f\"Training for Fold {fold_no}...\")\n\n    fold_train_df = train_df.iloc[train_index]\n    fold_val_df = train_df.iloc[val_index]\n\n    train_gen = train_datagen.flow_from_dataframe(\n        fold_train_df,\n        x_col='id_code',\n        y_col='diagnosis',\n        target_size=IMG_SIZE,\n        batch_size=BATCH_SIZE,\n        class_mode='sparse'\n    )\n\n    val_gen = val_test_datagen.flow_from_dataframe(\n        fold_val_df,\n        x_col='id_code',\n        y_col='diagnosis',\n        target_size=IMG_SIZE,\n        batch_size=BATCH_SIZE,\n        class_mode='sparse'\n    )\n\n    with strategy.scope():\n        base_model = EfficientNetB0(\n            include_top=False,\n            input_shape=(256, 256, 3),\n            weights='imagenet'\n        )\n        base_model.trainable = True\n\n        model = models.Sequential([\n            base_model,\n            layers.GlobalAveragePooling2D(),\n            layers.Dropout(0.5),\n            layers.Dense(1024, activation='relu'),\n            layers.Dropout(0.4),\n            layers.Dense(5, activation='softmax')\n        ])\n\n        model.compile(\n            optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),\n            loss='sparse_categorical_crossentropy',\n            metrics=['accuracy']\n        )\n\n    checkpoint_cb = callbacks.ModelCheckpoint(f'best_model_fold_{fold_no}.keras', monitor='val_accuracy', save_best_only=True, verbose=1)\n    early_stopping_cb = callbacks.EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\n    csv_logger = callbacks.CSVLogger(f'training_log_fold_{fold_no}.csv')\n\n    history = model.fit(\n        train_gen,\n        validation_data=val_gen,\n        epochs=EPOCHS,\n        class_weight=class_weights,\n        callbacks=[checkpoint_cb, early_stopping_cb, csv_logger]\n    )\n\n    model.save(f'model_fold_{fold_no}.keras')\n    history_path = f'history_fold_{fold_no}.pkl'\n    with open(history_path, 'wb') as f:\n        pickle.dump(history.history, f)\n    K.clear_session()\n    gc.collect()\n\n    fold_no += 1","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Creating the Test Generator","metadata":{}},{"cell_type":"code","source":"test_gen = val_test_datagen.flow_from_dataframe(\n    test_df,\n    x_col='id_code',\n    y_col='diagnosis',\n    target_size=IMG_SIZE,\n    batch_size=BATCH_SIZE,\n    class_mode='sparse',\n    shuffle=False\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Evaluate the Final Model","metadata":{}},{"cell_type":"code","source":"final_model = tf.keras.models.load_model(f'model_fold_{fold_no - 1}.keras')\ntest_loss, test_acc = final_model.evaluate(test_gen)\nprint(f\"Test Loss: {test_loss}, Test Accuracy: {test_acc}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Saving the Final Model","metadata":{}},{"cell_type":"code","source":"final_model.save('final_retinopathy_model.keras')","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}