{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":13836,"databundleVersionId":1718836,"sourceType":"competition"}],"dockerImageVersionId":30699,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport random\nfrom sklearn.model_selection import train_test_split\nfrom shutil import copyfile\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\nfrom tensorflow.keras.optimizers import SGD, RMSprop, Adam\nfrom tensorflow.keras.callbacks import LearningRateScheduler\nimport tensorflow as tf\nfrom tensorflow.keras.layers import Input","metadata":{"execution":{"iopub.status.busy":"2024-05-31T03:07:22.586962Z","iopub.execute_input":"2024-05-31T03:07:22.587317Z","iopub.status.idle":"2024-05-31T03:07:22.594033Z","shell.execute_reply.started":"2024-05-31T03:07:22.587283Z","shell.execute_reply":"2024-05-31T03:07:22.592972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install tensorflow --upgrade\n!pip install keras --upgrade\n!pip install --upgrade tensorflow keras","metadata":{"editable":false,"execution":{"iopub.status.busy":"2024-05-31T03:07:23.78642Z","iopub.execute_input":"2024-05-31T03:07:23.7868Z","iopub.status.idle":"2024-05-31T03:09:26.757277Z","shell.execute_reply.started":"2024-05-31T03:07:23.786773Z","shell.execute_reply":"2024-05-31T03:09:26.756159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"original_train_dir = '/kaggle/input/cassava-leaf-disease-classification/train_images'\nlabels_path = '/kaggle/input/cassava-leaf-disease-classification/train.csv'\nreduced_train_dir = 'dataset/reduced_train'\nreduced_test_dir = 'dataset/reduced_test'\nsample_size_per_class = 1000","metadata":{"editable":false,"execution":{"iopub.status.busy":"2024-05-31T03:09:48.792387Z","iopub.execute_input":"2024-05-31T03:09:48.792758Z","iopub.status.idle":"2024-05-31T03:09:48.797534Z","shell.execute_reply.started":"2024-05-31T03:09:48.792731Z","shell.execute_reply":"2024-05-31T03:09:48.796521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.read_csv(labels_path)\ntrain_labels, test_labels = train_test_split(labels, test_size=0.2, random_state=42)\nos.makedirs(reduced_train_dir, exist_ok=True)\nos.makedirs(reduced_test_dir, exist_ok=True)\nfor label in labels['label'].unique():\n    os.makedirs(os.path.join(reduced_train_dir, str(label)), exist_ok=True)\n    os.makedirs(os.path.join(reduced_test_dir, str(label)), exist_ok=True)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2024-05-31T03:09:49.747729Z","iopub.execute_input":"2024-05-31T03:09:49.748152Z","iopub.status.idle":"2024-05-31T03:09:49.803596Z","shell.execute_reply.started":"2024-05-31T03:09:49.748122Z","shell.execute_reply":"2024-05-31T03:09:49.802852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def copy_images(labels_df, dataset_type, sample_size_per_class):\n    for label in labels_df['label'].unique():\n        label_df = labels_df[labels_df['label'] == label]\n        sampled_df = label_df.sample(n=min(len(label_df), sample_size_per_class), random_state=42)\n        for _, row in sampled_df.iterrows():\n            src = os.path.join(original_train_dir, row['image_id'])\n            dst = os.path.join('dataset', dataset_type, str(row['label']), row['image_id'])\n            copyfile(src, dst)\n\ncopy_images(train_labels, 'reduced_train', sample_size_per_class)\ncopy_images(test_labels, 'reduced_test', sample_size_per_class)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2024-05-31T03:09:50.492545Z","iopub.execute_input":"2024-05-31T03:09:50.492924Z","iopub.status.idle":"2024-05-31T03:11:08.554939Z","shell.execute_reply.started":"2024-05-31T03:09:50.492896Z","shell.execute_reply":"2024-05-31T03:11:08.55413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_examples(labels_df, dataset_dir, num_examples=2):\n    unique_labels = labels_df['label'].unique()\n    num_labels = len(unique_labels)\n    fig, axes = plt.subplots(num_labels, num_examples, figsize=(20, 8 * num_labels // num_examples))\n\n    for i, label in enumerate(unique_labels):\n        label_dir = os.path.join(dataset_dir, str(label))\n        image_ids = random.sample(os.listdir(label_dir), num_examples)\n        for j, image_id in enumerate(image_ids):\n            image_path = os.path.join(label_dir, image_id)\n            img = plt.imread(image_path)\n            ax = axes[i, j] if num_labels > 1 else axes[j]\n            ax.imshow(img)\n            ax.set_title(f\"Label: {label}\")\n            ax.axis('off')\n    plt.tight_layout()\n    plt.show()\n\ndisplay_examples(train_labels, reduced_train_dir)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2024-05-31T03:11:08.556513Z","iopub.execute_input":"2024-05-31T03:11:08.556805Z","iopub.status.idle":"2024-05-31T03:11:11.087768Z","shell.execute_reply.started":"2024-05-31T03:11:08.556781Z","shell.execute_reply":"2024-05-31T03:11:11.086802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_cnn_model(input_shape=(224, 224, 3), num_classes=5):\n    model = Sequential()\n    model.add(Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))\n    model.add(MaxPooling2D((2, 2)))\n    model.add(Conv2D(64, (3, 3), activation='relu'))\n    model.add(MaxPooling2D((2, 2)))\n    model.add(Conv2D(128, (3, 3), activation='relu'))\n    model.add(MaxPooling2D((2, 2)))\n    model.add(Flatten())\n    model.add(Dense(128, activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(num_classes, activation='softmax'))\n    return model","metadata":{"editable":false,"execution":{"iopub.status.busy":"2024-05-31T03:11:11.088952Z","iopub.execute_input":"2024-05-31T03:11:11.089231Z","iopub.status.idle":"2024-05-31T03:11:11.0979Z","shell.execute_reply.started":"2024-05-31T03:11:11.089207Z","shell.execute_reply":"2024-05-31T03:11:11.096895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(model, optimizer, train_generator, validation_generator, epochs=10, use_scheduler=False):\n    if use_scheduler:\n        def scheduler(epoch, lr):\n            if epoch < 5:\n                return lr\n            else:\n                return lr * 0.1\n\n        lr_scheduler = LearningRateScheduler(scheduler)\n        callbacks = [lr_scheduler]\n    else:\n        callbacks = []\n\n    model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])\n    history = model.fit(train_generator, validation_data=validation_generator, epochs=epochs, callbacks=callbacks)\n    return history\n\ninput_shape = (224, 224, 3)\nnum_classes = 5\nbatch_size = 32\nepochs = 20\n\ntrain_datagen = ImageDataGenerator(rescale=1./255)\ntrain_generator = train_datagen.flow_from_directory(reduced_train_dir, target_size=(224, 224), batch_size=batch_size, class_mode='categorical')\n\nvalidation_datagen = ImageDataGenerator(rescale=1./255)\nvalidation_generator = validation_datagen.flow_from_directory(reduced_test_dir, target_size=(224, 224), batch_size=batch_size, class_mode='categorical')\n\nmodel = create_cnn_model(input_shape, num_classes)\n\noptimizer_rmsprop = RMSprop(learning_rate=0.001)\nhistory_rmsprop = train_model(model, optimizer_rmsprop, train_generator, validation_generator, epochs)\n\noptimizer_adam = Adam(learning_rate=0.001)\nhistory_adam = train_model(model, optimizer_adam, train_generator, validation_generator, epochs)\n\nhistory_rmsprop_sched = train_model(model, optimizer_rmsprop, train_generator, validation_generator, epochs, use_scheduler=True)\n\nhistory_adam_sched = train_model(model, optimizer_adam, train_generator, validation_generator, epochs, use_scheduler=True)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2024-05-31T03:11:47.80645Z","iopub.execute_input":"2024-05-31T03:11:47.807284Z","iopub.status.idle":"2024-05-31T03:51:26.647794Z","shell.execute_reply.started":"2024-05-31T03:11:47.807253Z","shell.execute_reply":"2024-05-31T03:51:26.646968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"augmented_train_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    fill_mode='nearest'\n)\n\naugmented_train_generator = augmented_train_datagen.flow_from_directory(\n    reduced_train_dir,\n    target_size=(224, 224),\n    batch_size=batch_size,\n    class_mode='categorical'\n)\n\noptimizer_adam = Adam(learning_rate=0.01)\n\nmodel.compile(optimizer=optimizer_adam, loss='categorical_crossentropy', metrics=['accuracy'])\n\nhistory_finetune = model.fit(\n    augmented_train_generator,\n    validation_data=validation_generator,\n    epochs=20\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T03:55:20.615385Z","iopub.execute_input":"2024-05-31T03:55:20.615789Z","iopub.status.idle":"2024-05-31T04:20:25.528919Z","shell.execute_reply.started":"2024-05-31T03:55:20.615761Z","shell.execute_reply":"2024-05-31T04:20:25.528055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install --upgrade tensorflow keras","metadata":{"execution":{"iopub.status.busy":"2024-05-31T04:21:04.291942Z","iopub.execute_input":"2024-05-31T04:21:04.292917Z","iopub.status.idle":"2024-05-31T04:21:17.226786Z","shell.execute_reply.started":"2024-05-31T04:21:04.292884Z","shell.execute_reply":"2024-05-31T04:21:17.225577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nbatch_size = 32\nnum_classes = 5\nepochs = 20\n\nbase_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))\n\nx = base_model.output\nx = GlobalAveragePooling2D()(x)\nx = Dense(1024, activation='relu')(x)\nx = Dense(num_classes, activation='softmax')(x)\n\nmodel = Model(inputs=base_model.input, outputs=x)\n\nfor layer in base_model.layers:\n    layer.trainable = False\n\nmodel.compile(optimizer=Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'])\n\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    fill_mode='nearest'\n)\n\nvalidation_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = train_datagen.flow_from_directory(\n    reduced_train_dir,\n    target_size=(224, 224),\n    batch_size=batch_size,\n    class_mode='categorical'\n)\n\nvalidation_generator = validation_datagen.flow_from_directory(\n    reduced_test_dir,\n    target_size=(224, 224),\n    batch_size=batch_size,\n    class_mode='categorical'\n)\n\nhistory = model.fit(\n    train_generator,\n    validation_data=validation_generator,\n    epochs=epochs\n)\n\nfor layer in base_model.layers[:143]:\n    layer.trainable = False\nfor layer in base_model.layers[143:]:\n    layer.trainable = True\n\nmodel.compile(optimizer=Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'])\n\nhistory_resnet = model.fit(\n    train_generator,\n    validation_data=validation_generator,\n    epochs=epochs\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T04:21:24.554224Z","iopub.execute_input":"2024-05-31T04:21:24.555038Z","iopub.status.idle":"2024-05-31T05:12:35.450574Z","shell.execute_reply.started":"2024-05-31T04:21:24.555003Z","shell.execute_reply":"2024-05-31T05:12:35.44976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_training_history(history, title):\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n    epochs = range(1, len(acc) + 1)\n\n    plt.figure(figsize=(14, 5))\n    plt.subplot(1, 2, 1)\n    plt.plot(epochs, acc, 'b', label='Training acc')\n    plt.plot(epochs, val_acc, 'r', label='Validation acc')\n    plt.title(f'Training and validation accuracy - {title}')\n    plt.legend()\n\n    plt.subplot(1, 2, 2)\n    plt.plot(epochs, loss, 'b', label='Training loss')\n    plt.plot(epochs, val_loss, 'r', label='Validation loss')\n    plt.title(f'Training and validation loss - {title}')\n    plt.legend()\n\n    plt.show()\n\nplot_training_history(history_rmsprop, 'RMSProp')\nplot_training_history(history_adam, 'Adam')\nplot_training_history(history_rmsprop_sched, 'RMSProp with Scheduler')\nplot_training_history(history_adam_sched, 'Adam with Scheduler')\nplot_training_history(history_finetune, 'Fine-tuned Adam with Augmentation')\nplot_training_history(history_resnet, 'ResNet50')\n\nresults = {\n    'Model': ['RMSProp', 'Adam', 'RMSProp with Scheduler', 'Adam with Scheduler', 'Fine-tuned Adam with Augmentation', 'ResNet50'],\n    'Training Accuracy': [\n        max(history_rmsprop.history['accuracy']),\n        max(history_adam.history['accuracy']),\n        max(history_rmsprop_sched.history['accuracy']),\n        max(history_adam_sched.history['accuracy']),\n        max(history_finetune.history['accuracy']),\n        max(history_resnet.history['accuracy'])\n    ],\n    'Validation Accuracy': [\n        max(history_rmsprop.history['val_accuracy']),\n        max(history_adam.history['val_accuracy']),\n        max(history_rmsprop_sched.history['val_accuracy']),\n        max(history_adam_sched.history['val_accuracy']),\n        max(history_finetune.history['val_accuracy']),\n        max(history_resnet.history['val_accuracy'])\n    ]\n}\n\nresults_df = pd.DataFrame(results)\nprint(results_df)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T05:12:44.795186Z","iopub.execute_input":"2024-05-31T05:12:44.795703Z","iopub.status.idle":"2024-05-31T05:12:47.851062Z","shell.execute_reply.started":"2024-05-31T05:12:44.795664Z","shell.execute_reply":"2024-05-31T05:12:47.850118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}