{"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":"none","dataSources":[{"sourceId":13836,"databundleVersionId":1718836,"sourceType":"competition"}],"dockerImageVersionId":30646,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\n\ndataset_directory = '/kaggle/input/'","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-02-07T15:56:50.630682Z","iopub.execute_input":"2024-02-07T15:56:50.631023Z","iopub.status.idle":"2024-02-07T15:56:50.637256Z","shell.execute_reply.started":"2024-02-07T15:56:50.630988Z","shell.execute_reply":"2024-02-07T15:56:50.635794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(os.path.join(dataset_directory, \"cassava-leaf-disease-classification/train.csv\"))","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:56:50.638868Z","iopub.execute_input":"2024-02-07T15:56:50.639289Z","iopub.status.idle":"2024-02-07T15:56:50.685176Z","shell.execute_reply.started":"2024-02-07T15:56:50.639249Z","shell.execute_reply":"2024-02-07T15:56:50.684098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:56:50.687059Z","iopub.execute_input":"2024-02-07T15:56:50.687463Z","iopub.status.idle":"2024-02-07T15:56:50.705902Z","shell.execute_reply.started":"2024-02-07T15:56:50.687431Z","shell.execute_reply":"2024-02-07T15:56:50.704473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\n\n# Read json to get the dictionary of the label names\nwith open(os.path.join(dataset_directory, \"cassava-leaf-disease-classification/label_num_to_disease_map.json\")) as file:\n    data = json.load(file)\n\nprint(data)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:56:50.707555Z","iopub.execute_input":"2024-02-07T15:56:50.707926Z","iopub.status.idle":"2024-02-07T15:56:50.718159Z","shell.execute_reply.started":"2024-02-07T15:56:50.707896Z","shell.execute_reply":"2024-02-07T15:56:50.717061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[\"label\"] = df_train[\"label\"].astype(str)\ndf_train['Label name'] = df_train['label'].map(data)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:56:50.723281Z","iopub.execute_input":"2024-02-07T15:56:50.723604Z","iopub.status.idle":"2024-02-07T15:56:50.746462Z","shell.execute_reply.started":"2024-02-07T15:56:50.723579Z","shell.execute_reply":"2024-02-07T15:56:50.745218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:56:50.747873Z","iopub.execute_input":"2024-02-07T15:56:50.748281Z","iopub.status.idle":"2024-02-07T15:56:50.759012Z","shell.execute_reply.started":"2024-02-07T15:56:50.748241Z","shell.execute_reply":"2024-02-07T15:56:50.757935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nvalue_counts = df_train[\"Label name\"].value_counts()\n\nvalue_counts.plot(kind='bar')\nplt.ylabel('Frequency')\nplt.title('Type of Disease')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:56:50.760538Z","iopub.execute_input":"2024-02-07T15:56:50.760804Z","iopub.status.idle":"2024-02-07T15:56:51.267974Z","shell.execute_reply.started":"2024-02-07T15:56:50.760783Z","shell.execute_reply":"2024-02-07T15:56:51.267049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Plot some images\nimport cv2\ndirectory = os.path.join(dataset_directory, \"cassava-leaf-disease-classification\", \"train_images\")\nimage_files = [os.path.join(directory, f) \n               for f in os.listdir(directory) if os.path.isfile(os.path.join(directory,f))]","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:56:51.269423Z","iopub.execute_input":"2024-02-07T15:56:51.270346Z","iopub.status.idle":"2024-02-07T15:58:15.797402Z","shell.execute_reply.started":"2024-02-07T15:56:51.270314Z","shell.execute_reply":"2024-02-07T15:58:15.796558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_files_example = image_files[1:10]","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:15.798632Z","iopub.execute_input":"2024-02-07T15:58:15.799331Z","iopub.status.idle":"2024-02-07T15:58:15.802978Z","shell.execute_reply.started":"2024-02-07T15:58:15.799303Z","shell.execute_reply":"2024-02-07T15:58:15.802232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set the number of images per row\nimages_per_row = 3\n\n# Rows needed\nnum_rows = len(image_files_example) // images_per_row + (1 if len(image_files_example) % images_per_row else 0)\n\n# Plot each image\nplt.figure(figsize=(20,10)) \nfor idx, image_path in enumerate(image_files_example):\n    img = cv2.imread(image_path)\n    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # Convert from BGR to RGB for matplotlib\n\n    plt.subplot(num_rows, images_per_row, idx + 1)\n    plt.imshow(img_rgb)\n    plt.title(\"Class \"+df_train[\"label\"].loc[idx]+ \":\" +df_train[\"Label name\"].loc[idx])\n    plt.axis('off')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:15.803896Z","iopub.execute_input":"2024-02-07T15:58:15.804233Z","iopub.status.idle":"2024-02-07T15:58:17.568543Z","shell.execute_reply.started":"2024-02-07T15:58:15.804185Z","shell.execute_reply":"2024-02-07T15:58:17.567026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Shape of Images\nimage_example = cv2.imread(image_files_example[1])\n","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:17.569719Z","iopub.execute_input":"2024-02-07T15:58:17.570071Z","iopub.status.idle":"2024-02-07T15:58:17.581162Z","shell.execute_reply.started":"2024-02-07T15:58:17.570043Z","shell.execute_reply":"2024-02-07T15:58:17.580251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_example.shape","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:17.582318Z","iopub.execute_input":"2024-02-07T15:58:17.582570Z","iopub.status.idle":"2024-02-07T15:58:17.588354Z","shell.execute_reply.started":"2024-02-07T15:58:17.582549Z","shell.execute_reply":"2024-02-07T15:58:17.587403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ResNet50\nimport tensorflow as tf\nfrom tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras import layers","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:17.589343Z","iopub.execute_input":"2024-02-07T15:58:17.589644Z","iopub.status.idle":"2024-02-07T15:58:17.598306Z","shell.execute_reply.started":"2024-02-07T15:58:17.589615Z","shell.execute_reply":"2024-02-07T15:58:17.597531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Importing base model without input layer\nbase_model = ResNet50(weights='imagenet', include_top=False,input_shape=(600, 800, 3))","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:17.599226Z","iopub.execute_input":"2024-02-07T15:58:17.599435Z","iopub.status.idle":"2024-02-07T15:58:19.293455Z","shell.execute_reply.started":"2024-02-07T15:58:17.599416Z","shell.execute_reply":"2024-02-07T15:58:19.292501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = base_model.output\nx = GlobalAveragePooling2D()(x)  # Add a global spatial average pooling layer\nx = Dense(1024, activation='relu')(x)  # Add a fully-connected layer\npredictions = Dense(5, activation='softmax')(x) #The output layer, with 5 classes","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:19.294511Z","iopub.execute_input":"2024-02-07T15:58:19.294754Z","iopub.status.idle":"2024-02-07T15:58:19.334071Z","shell.execute_reply.started":"2024-02-07T15:58:19.294733Z","shell.execute_reply":"2024-02-07T15:58:19.333092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Model(inputs=base_model.input, outputs=predictions)\n\n# Freeze the layers of the base model\nfor layer in base_model.layers:\n    layer.trainable = False\n\n# Compile model\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:19.335054Z","iopub.execute_input":"2024-02-07T15:58:19.335340Z","iopub.status.idle":"2024-02-07T15:58:19.375384Z","shell.execute_reply.started":"2024-02-07T15:58:19.335317Z","shell.execute_reply":"2024-02-07T15:58:19.374447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:19.376733Z","iopub.execute_input":"2024-02-07T15:58:19.377184Z","iopub.status.idle":"2024-02-07T15:58:19.819068Z","shell.execute_reply.started":"2024-02-07T15:58:19.377159Z","shell.execute_reply":"2024-02-07T15:58:19.817624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train['image_path'] = df_train['image_id'].apply(lambda x: f'{directory}/{x}')\n\n# Initialize the ImageDataGenerator\ndata_generator = ImageDataGenerator(\n    preprocessing_function=preprocess_input,\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    horizontal_flip=True,\n    validation_split=0.2  #80% training, 20% Validation\n)\n\n# Now, use flow_from_dataframe to link your DataFrame with the generator\ntrain_generator = data_generator.flow_from_dataframe(\n    dataframe=df_train,\n    directory=None,  # Set to None because 'image_path' contains full paths\n    x_col='image_path',  # Column with image paths\n    y_col='label',  # Column with labels\n    #target_size=(224, 224),  # ResNet50 and VGG16 input size\n    batch_size=64,\n    class_mode='categorical', \n    subset='training'  \n)\nvalidation_generator = data_generator.flow_from_dataframe(\n    dataframe=df_train,\n    directory=None,  \n    x_col='image_path',  \n    y_col='label',  \n    #target_size=(224, 224),  \n    batch_size=64,\n    class_mode='categorical',  \n    subset='validation' \n)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:19.820612Z","iopub.execute_input":"2024-02-07T15:58:19.820912Z","iopub.status.idle":"2024-02-07T15:58:47.535111Z","shell.execute_reply.started":"2024-02-07T15:58:19.820885Z","shell.execute_reply":"2024-02-07T15:58:47.533813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Plotting image from image generator\nimages, labels = next(train_generator)\n\n# Select the first image from the batch\nimage = images[1]\nimage = (image - np.min(image)) / (np.max(image) - np.min(image))\n\n# Display the image\nplt.imshow(image)\nplt.axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:47.536918Z","iopub.execute_input":"2024-02-07T15:58:47.537411Z","iopub.status.idle":"2024-02-07T15:58:49.311228Z","shell.execute_reply.started":"2024-02-07T15:58:47.537375Z","shell.execute_reply":"2024-02-07T15:58:49.309961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(\n    train_generator,\n    steps_per_epoch=train_generator.samples // train_generator.batch_size,\n    validation_data=validation_generator,\n    validation_steps=validation_generator.samples // validation_generator.batch_size,\n    epochs=7\n)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:58:49.312599Z","iopub.execute_input":"2024-02-07T15:58:49.312921Z","iopub.status.idle":"2024-02-07T21:30:38.848832Z","shell.execute_reply.started":"2024-02-07T15:58:49.312894Z","shell.execute_reply":"2024-02-07T21:30:38.843995Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_accuracy = history.history['accuracy']\n\nval_accuracy = history.history['val_accuracy']\n\nprint(f\"Training Accuracy: {train_accuracy[0]}\")\nprint(f\"Validation Accuracy: {val_accuracy[0]}\")","metadata":{"execution":{"iopub.status.busy":"2024-02-07T21:30:38.855621Z","iopub.execute_input":"2024-02-07T21:30:38.856162Z","iopub.status.idle":"2024-02-07T21:30:38.869302Z","shell.execute_reply.started":"2024-02-07T21:30:38.856110Z","shell.execute_reply":"2024-02-07T21:30:38.868446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('ResNet50_trained_model.keras')","metadata":{"execution":{"iopub.status.busy":"2024-02-07T22:08:22.968984Z","iopub.execute_input":"2024-02-07T22:08:22.969378Z","iopub.status.idle":"2024-02-07T22:08:23.924580Z","shell.execute_reply.started":"2024-02-07T22:08:22.969351Z","shell.execute_reply":"2024-02-07T22:08:23.922591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pathlib import Path\n\n# Path\nmodel_path = 'ResNet50_trained_model.keras'\n\nmodel_file = Path(model_path)\nprint(model_file)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T22:09:37.321469Z","iopub.execute_input":"2024-02-07T22:09:37.321880Z","iopub.status.idle":"2024-02-07T22:09:37.329493Z","shell.execute_reply.started":"2024-02-07T22:09:37.321850Z","shell.execute_reply":"2024-02-07T22:09:37.328246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Graph\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\n# Plotting training and validation accuracy\nplt.figure(figsize=(12, 5))\nplt.subplot(1, 2, 1)\nplt.plot(epochs, acc, label='Training Accuracy')\nplt.plot(epochs, val_acc, label='Validation Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\n\n# Plotting training and validation loss\nplt.subplot(1, 2, 2)\nplt.plot(epochs, loss, label='Training Loss')\nplt.plot(epochs, val_loss, label='Validation Loss')\nplt.title('Training and Validation Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T22:06:40.985347Z","iopub.execute_input":"2024-02-07T22:06:40.985734Z","iopub.status.idle":"2024-02-07T22:06:41.452535Z","shell.execute_reply.started":"2024-02-07T22:06:40.985706Z","shell.execute_reply":"2024-02-07T22:06:41.451773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Prediction\ntest_image_path = os.path.join(dataset_directory, \"cassava-leaf-disease-classification/test_images/2216849948.jpg\")\ntest_image = cv2.imread(test_image_path)\nprint(test_image.shape)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T22:21:04.854189Z","iopub.execute_input":"2024-02-07T22:21:04.854555Z","iopub.status.idle":"2024-02-07T22:21:04.871979Z","shell.execute_reply.started":"2024-02-07T22:21:04.854530Z","shell.execute_reply":"2024-02-07T22:21:04.870477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_batch = np.expand_dims(test_image, axis=0)\npredictions = model.predict(image_batch)\n\npredicted_class = np.argmax(predictions, axis=1)\nprint(\"Predicted class:\", predicted_class)\nprint(type(predicted_class))","metadata":{"execution":{"iopub.status.busy":"2024-02-07T22:47:46.232702Z","iopub.execute_input":"2024-02-07T22:47:46.233358Z","iopub.status.idle":"2024-02-07T22:47:46.928792Z","shell.execute_reply.started":"2024-02-07T22:47:46.233324Z","shell.execute_reply":"2024-02-07T22:47:46.928087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predicted_class_str = (data[str(predicted_class[0])])\n\nposition = (10, 50)  \nthickness = 2\nannotated_image = cv2.putText(test_image.copy(), f\"Predicted Class: {predicted_class_str}\", position, thickness, cv2.LINE_AA)\nannotated_image_rgb = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB)\n\nplt.imshow(annotated_image_rgb)\nplt.axis('off') \nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T22:51:19.461326Z","iopub.execute_input":"2024-02-07T22:51:19.461693Z","iopub.status.idle":"2024-02-07T22:51:19.659525Z","shell.execute_reply.started":"2024-02-07T22:51:19.461667Z","shell.execute_reply":"2024-02-07T22:51:19.658100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}