{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# <center>Cassava Leaf Disease Classification</center>\n# ![image](https://previews.123rf.com/images/bugning/bugning1307/bugning130700289/21226772-cassava.jpg)","metadata":{}},{"cell_type":"markdown","source":"## Contents:\n\n- [About competition](#section-one)\n- [Exploratory Data Analysis](#section-two)\n - [Class Distribution](#subsection-one)\n - [Sample Images](#subsection-two)\n - [Height, Width and Aspect ratio for all diseases](#subsection-three)\n - [Outlier Detection using Mean and Variance](#subsection-four)\n   - [CBB](#outlier-ss-1)  \n   - [CMD](#outlier-ss-2)  \n   - [CMSD](#outlier-ss-3)\n   - [CGM](#outlier-ss-4)\n   - [Healthy](#outlier-ss-5)\n  \n - [Outlier detection using K-means Clustering](#subsection-five)\n - [Feature Extraction](#section-six)\n- [Next Steps](#section-three)","metadata":{}},{"cell_type":"markdown","source":"<a id=\"section-one\"> </a>\n## About Competition\n\nCassava, or Manihot esculenta, belongs to the family Euphorbiaceae and is cultivated in tropical and subtropical regions for its edible starchy tuberous root, which is commonly dried into a powder and named tapioca.\n\nAs the second-largest provider of carbohydrates in Africa, cassava is a key food security crop grown by smallholder farmers because it can withstand harsh conditions. At least 80% of household farms in Sub-Saharan Africa grow this starchy root, but viral diseases are major sources of poor yields. With the help of data science, it may be possible to identify common diseases so they can be treated.\n\nExisting methods of disease detection require farmers to solicit the help of government-funded agricultural experts to visually inspect and diagnose the plants. This suffers from being labor-intensive, low-supply and costly. As an added challenge, effective solutions for farmers must perform well under significant constraints, since African farmers may only have access to mobile-quality cameras with low-bandwidth.\n\nIn this competition, we introduce a dataset of 21,367 labeled images collected during a regular survey in Uganda. Most images were crowdsourced from farmers taking photos of their gardens, and annotated by experts at the National Crops Resources Research Institute (NaCRRI) in collaboration with the AI lab at Makerere University, Kampala. This is in a format that most realistically represents what farmers would need to diagnose in real life.\n\n### HEALTH BENEFITS\n\nTapioca has been associated with some health benefits, such as **healthy weight gain, increased red blood cell count, improved digestion, preventing diabetes, protecting bone mineral density, preventing Alzheimer’s disease and maintaining fluid balance within the body.**\n\n### EVALUATION\n**$$Accuracy=\\frac{TP + TN}{TP + FP + TN + FN}$$**\n\nwhere,  \n - TP: True Positive\n - FP: False Positive\n - TN: True Negative\n - FN: False Negative","metadata":{}},{"cell_type":"markdown","source":"<a id=\"section-two\"></a>\n## Exploratory Data Analysis","metadata":{}},{"cell_type":"code","source":"!pip install -q imutils","metadata":{"execution":{"iopub.status.busy":"2021-10-05T16:50:01.172338Z","iopub.execute_input":"2021-10-05T16:50:01.172749Z","iopub.status.idle":"2021-10-05T16:50:12.102996Z","shell.execute_reply.started":"2021-10-05T16:50:01.172717Z","shell.execute_reply":"2021-10-05T16:50:12.101904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os,json\nfrom tqdm.notebook import tqdm\nimport time\n\n#for graphs and images\nimport plotly.graph_objects as go\nfrom plotly.subplots import make_subplots\nimport plotly.figure_factory as ff\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport cv2,imutils\n\n#k-means\nfrom scipy.cluster.vq import kmeans,whiten\nfrom scipy.stats import zscore\n\n#pytorch(feature-extraction)\nfrom torchvision import models\nimport torch\n\nfrom albumentations import *\nfrom albumentations.pytorch import ToTensor\n\n#train_valid split\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.decomposition import PCA\nfrom sklearn.manifold import TSNE","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-10-05T16:51:11.059734Z","iopub.execute_input":"2021-10-05T16:51:11.060112Z","iopub.status.idle":"2021-10-05T16:51:12.938513Z","shell.execute_reply.started":"2021-10-05T16:51:11.060076Z","shell.execute_reply":"2021-10-05T16:51:12.937460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_path = '../input/nut-snacks/nut_snacks/nut_snacks/dataset/'","metadata":{"execution":{"iopub.status.busy":"2021-10-05T16:52:21.720043Z","iopub.execute_input":"2021-10-05T16:52:21.720712Z","iopub.status.idle":"2021-10-05T16:52:21.726920Z","shell.execute_reply.started":"2021-10-05T16:52:21.720669Z","shell.execute_reply":"2021-10-05T16:52:21.725493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#reading the train.csv file\ntrain_df = pd.read_csv(input_path+'train.csv')\nprint(train_df.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#maping the class labels mentioned in json file wiht its respective disease name\ndisease_names = open(input_path+'label_num_to_disease_map.json')\ndisease_names = json.load(disease_names)\ntrain_df['disease_name'] = train_df['label'].apply(lambda x: disease_names[str(x)])\n#visualize the top five rows from table\ntrain_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='subsection-one'></a>\n### Class Labels Distribution","metadata":{}},{"cell_type":"code","source":"fig = make_subplots(rows=1, cols=2,\n            specs=[[{\"type\": \"xy\"}, {\"type\": \"domain\"}]],)\n# value_counts: to count number of images in each class with respect to disease_name column\n# Bar plot \nt1 = go.Bar(x=train_df['disease_name'].value_counts().index, \n            y=train_df['disease_name'].value_counts().values,\n            text=train_df['disease_name'].value_counts().values,\n            textposition='auto',name='Count',\n           marker_color='indianred')\n#Pie chart with labels and counts\nt2 = go.Pie(labels=train_df['disease_name'].value_counts().index,\n           values=train_df['disease_name'].value_counts().values,\n           hole=0.3)\nfig.add_trace(t1,row=1, col=1)\nfig.add_trace(t2,row=1, col=2)\nfig.update_layout(title='Distribution of Class Labels')\nfig.show()","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"subsection-two\"></a>\n### Sample Images from each class","metadata":{}},{"cell_type":"code","source":"#random seed is used to replicate the same images in every run\nnp.random.seed(2020)\n#plotting 5 random samples for each class with image name and disease name as title\nfor class_name in train_df['disease_name'].unique():\n    plt.figure(figsize=(20,50))\n    for idx,img_name in enumerate(np.random.choice(train_df[train_df['disease_name'] == class_name]['image_id'].values,\n                                                   size=5,replace=False)):\n        plt.subplot(1,5,idx+1)\n        #reading the image and converting BGR color space to RGB\n        img = cv2.cvtColor(cv2.imread(input_path+'train_images/'+img_name), cv2.COLOR_BGR2RGB)\n        plt.imshow(img)\n        plt.axis('off')\n        plt.title(r\"$\\bf{\"+class_name + \"}$\"+'\\n'+img_name )\n    plt.show()","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"subsection-three\"></a>\n### Height, Width and Aspect ratio for all diseases","metadata":{}},{"cell_type":"markdown","source":"Check for the distribution of image size. which inturn will be helpful for defining the model Input shape.\n\n - In this dataset the image size (600 x 800) is same for all the images","metadata":{}},{"cell_type":"code","source":"df = pd.DataFrame()\nidx = 0\nfor cl_ in tqdm(os.listdir(input_path)):\n    \n    images = os.listdir(os.path.join(input_path, cl_))\n    \n    for image in images:\n        img_name = os.path.join(input_path, cl_, image)\n        #reading the image and converting BGR color space to RGB\n        img = cv2.cvtColor(cv2.imread(img_name), cv2.COLOR_BGR2RGB)\n\n        #normalize the image in the range [0,1]\n        norm_image = cv2.normalize(img, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)\n\n        width,height,depth = img.shape\n    \n        #adding new column to the tabel with width height and aspect ratio for every image\n        df.loc[idx , 'Image Name'] = img_name\n        df.loc[idx,'Width'] = width\n        df.loc[idx,'Height'] = height\n        df.loc[idx,'Aspect Ratio'] = width/height\n\n        #calculate mean and standart deviation for each image\n        df.loc[idx,'Mean'] = img.mean()\n        df.loc[idx,'SD'] = img.std()\n\n        #calculate mean and standart deviation for each normalized image\n        df.loc[idx,'Normalized_Mean'] = norm_image.mean()\n        df.loc[idx,'Normalized_SD'] = norm_image.std()\n        \n        idx+=1","metadata":{"execution":{"iopub.status.busy":"2021-10-05T17:28:52.090002Z","iopub.execute_input":"2021-10-05T17:28:52.090470Z","iopub.status.idle":"2021-10-05T17:30:31.595666Z","shell.execute_reply.started":"2021-10-05T17:28:52.090430Z","shell.execute_reply":"2021-10-05T17:30:31.594447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"subsection-four\"></a>\n### Outlier Detection using Mean and Standard Deviation","metadata":{}},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2021-10-05T17:37:22.790415Z","iopub.execute_input":"2021-10-05T17:37:22.790835Z","iopub.status.idle":"2021-10-05T17:37:22.810037Z","shell.execute_reply.started":"2021-10-05T17:37:22.790802Z","shell.execute_reply":"2021-10-05T17:37:22.808749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"2*194","metadata":{"execution":{"iopub.status.busy":"2021-10-05T17:37:25.073077Z","iopub.execute_input":"2021-10-05T17:37:25.073670Z","iopub.status.idle":"2021-10-05T17:37:25.078956Z","shell.execute_reply.started":"2021-10-05T17:37:25.073634Z","shell.execute_reply":"2021-10-05T17:37:25.078290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[df['Mean']>220]['Image Name'][8186]","metadata":{"execution":{"iopub.status.busy":"2021-10-05T17:40:50.448517Z","iopub.execute_input":"2021-10-05T17:40:50.449076Z","iopub.status.idle":"2021-10-05T17:40:50.456464Z","shell.execute_reply.started":"2021-10-05T17:40:50.449042Z","shell.execute_reply":"2021-10-05T17:40:50.455265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig =  make_subplots(rows=2,cols=1,subplot_titles=['Original Image', 'Normalized Image'])\ncolors = ['rgb(13, 200, 58)','rgb(13, 160, 200)','rgb(190, 81, 249)','rgb(248, 104, 73)','rgb(243, 247, 15)']\n\nfor idx,i in enumerate(range(1)):\n    #scatter plot between mean and variance of the images for every disease\n    fig.add_trace(go.Scatter(x=df['Mean'],\n                             y=df['SD'],\n                            mode = 'markers',name='Standard Mean',\n                            marker_color=colors[idx]),1,1)\n    \n    #scatter plot between mean and variance of the normalized images for every disease\n    fig.add_trace(go.Scatter(x=df['Normalized_Mean'],\n                             y=df['Normalized_SD'],\n                            mode = 'markers',name='Normalized',\n                            marker_color=colors[idx], showlegend=False),2,1)\n#x-axis and y axis title\nfig.update_xaxes(title_text=\"Mean\", row=1, col=1)\nfig.update_yaxes(title_text=\"Standard Deviation\", row=1, col=1)\n\nfig.update_xaxes(title_text=\"Mean\", row=2, col=1)\nfig.update_yaxes(title_text=\"Standard Deviation\", row=2, col=1)\nfig.show()\n    ","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-05T17:37:27.193603Z","iopub.execute_input":"2021-10-05T17:37:27.194234Z","iopub.status.idle":"2021-10-05T17:37:27.324428Z","shell.execute_reply.started":"2021-10-05T17:37:27.194196Z","shell.execute_reply":"2021-10-05T17:37:27.323374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**From the Scatter Plot,** \n\n- it is very clear that there are **outliers in dataset** with mean greater than 0.7 and less than 0.15. But to have a clear picture of outliers for each class will use **Box Plot**","metadata":{}},{"cell_type":"code","source":"fig = make_subplots(rows=2,cols=2,\n                    subplot_titles=['Mean','Standard Deviation','Normalized Mean','Normalized Standard Deviation'],\n                    shared_xaxes=True)\ncolors = ['rgb(13, 200, 58)','rgb(13, 160, 200)','rgb(190, 81, 249)','rgb(248, 104, 73)','rgb(243, 247, 15)']\nfor idx,class_name in enumerate(train_df['disease_name'].unique()):\n    fig.add_trace(go.Box(y=train_df[train_df['disease_name'] == class_name]['Mean'],\n                        name=class_name,showlegend=False,\n                        marker_color=colors[idx]),1,1)\n    fig.add_trace(go.Box(y=train_df[train_df['disease_name'] == class_name]['Normalized_Mean'],\n                        name=class_name,showlegend=False,\n                        marker_color=colors[idx]),2,1)\n    fig.add_trace(go.Box(y=train_df[train_df['disease_name'] == class_name]['SD'],\n                        name=class_name,showlegend=False,\n                        marker_color=colors[idx]),1,2)\n    fig.add_trace(go.Box(y=train_df[train_df['disease_name'] == class_name]['Normalized_SD'],\n                        name=class_name,showlegend=False,\n                        marker_color=colors[idx]),2,2)\nfig.update_layout(title='Outlier Detection - Box Plot')\nfig.show()","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"outlier-ss-1\"></a>\n#### Outliers in Cassava Bacterial Blight (CBB)","metadata":{}},{"cell_type":"code","source":"#filtering only Cassava Bacterial Blight (CBB) class from original data\nCBB  = train_df[train_df['disease_name'] ==  'Cassava Bacterial Blight (CBB)']\nprint('Number of Images in Cassava Bacterial Blight (CBB) Class: '+str(len(CBB)))\n\n#filtering the CBB data for which mean is between -0.85e-6 and 0.820e-6(observation from box plot)\noutliers_CBB = CBB[CBB['Normalized_Mean'].between(0.17,0.58,inclusive=True)]\n# filter only the rows which are not in above list of images\noutliers_CBB = CBB[~CBB['image_id'].isin(outliers_CBB['image_id'])]\nprint('Number of Outlier Images in Cassava Bacterial Blight (CBB) Class: '+str(len(outliers_CBB))+'\\n')\nprint(input_path+'train_images/'+outliers_CBB['image_id'].astype(str).values)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"c = 0\n#plot all the outlier images based on Mean value\nfor i,idx in enumerate(outliers_CBB.index):\n    # a condition a change the row number in subplot\n    if int(i/3) == c:\n        c+=1\n        plt.figure(figsize=(25,30))\n    plt.subplot(c,3,i%3+1)\n    img_name = outliers_CBB.loc[idx,'image_id']\n    img = cv2.cvtColor(cv2.imread(os.path.join(input_path,'train_images',img_name)),cv2.COLOR_BGR2RGB)\n    plt.imshow(img)\n    plt.title(img_name+'\\n'+'Mean: '+ str(outliers_CBB.loc[idx,'Normalized_Mean'].round(2)) + '\\n'+\\\n              'Standard Deviation: '+str(outliers_CBB.loc[idx,'Normalized_SD'].round(2)))\n    plt.axis('off')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"outlier-ss-2\"></a>\n#### Outliers in 'Cassava Mosaic Disease (CMD)'","metadata":{}},{"cell_type":"code","source":"#filtering only Cassava Mosaic Disease (CMD) class from original data\nCMD  = train_df[train_df['disease_name'] ==  'Cassava Mosaic Disease (CMD)']\nprint('Number of Images in Cassava Mosaic Disease (CMD) Class: '+str(len(CMD)))\n\n#filtering the CMD data for which Mean is between 0.19 and 0.64(observation from box plot)\noutliers_CMD = CMD[CMD['Normalized_Mean'].between(0.19,0.64,inclusive=True)]\n# filter only the rows which are not in above list of images\noutliers_CMD = CMD[~CMD['image_id'].isin(outliers_CMD['image_id'])]\nprint('Number of Outlier Images in Cassava Mosaic Disease (CMD) Class: '+str(len(outliers_CMD))+'\\n')\nprint(input_path+'train_images/'+outliers_CMD['image_id'].values)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"c = 0\n#plot all the outlier images based on Mean value\nfor i,idx in enumerate(outliers_CMD.index):\n    # a condition a change the row number in subplot\n    if int(i/3) == c:\n        c+=1\n        plt.figure(figsize=(25,30))\n    plt.subplot(c,3,i%6+1)\n    img_name = outliers_CMD.loc[idx,'image_id']\n    img = cv2.cvtColor(cv2.imread(os.path.join(input_path,'train_images',img_name)),cv2.COLOR_BGR2RGB)\n    plt.imshow(img)\n    plt.title(img_name+'\\n'+'Mean: '+ str(outliers_CMD.loc[idx,'Normalized_Mean'].round(2)) + '\\n'+\\\n              'Standard Deviation: '+str(outliers_CMD.loc[idx,'Normalized_SD'].round(2))+ '\\n')\n    plt.axis('off')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"outlier-ss-3\"></a>\n#### Outliers in 'Cassava Brown Streak Disease (CBSD)'","metadata":{}},{"cell_type":"code","source":"#filtering only  'Cassava Brown Streak Disease (CBSD)' class from original data\nCBSD  = train_df[train_df['disease_name'] ==   'Cassava Brown Streak Disease (CBSD)']\nprint('Number of Images in  Cassava Brown Streak Disease (CBSD) Class: '+str(len(CBSD)))\n\n#filtering the CBSD data for which Normalized Mean is between 0.158 and 0.64(observation from box plot)\noutliers_CBSD = CBSD[CBSD['Normalized_Mean'].between(0.158,0.64,inclusive=True)]\n# filter only the rows which are not in above list of images\noutliers_CBSD = CBSD[~CBSD['image_id'].isin(outliers_CBSD['image_id'])]\nprint('Number of Outlier Images in  Cassava Brown Streak Disease (CBSD) Class: '+str(len(outliers_CBSD))+'\\n')\nprint(input_path+'train_images/'+outliers_CBSD['image_id'].values)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#plot all the outlier images based on Mean value\nplt.figure(figsize=(20,30))\nfor i,idx in enumerate(outliers_CBSD.index):\n    plt.subplot(1,3,i%3+1)\n    img_name = outliers_CBSD.loc[idx,'image_id']\n    img = cv2.cvtColor(cv2.imread(os.path.join(input_path,'train_images',img_name)),cv2.COLOR_BGR2RGB)\n    plt.imshow(img)\n    plt.title(img_name+'\\n'+'Mean: '+ str(outliers_CBSD.loc[idx,'Normalized_Mean'].round(2)) + '\\n'+\\\n              'Standard Deviation: '+str(outliers_CBSD.loc[idx,'Normalized_SD'].round(2))+ '\\n')\n    plt.axis('off')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"outlier-ss-4\"></a>\n#### Outliers in 'Cassava Green Mottle (CGM)'","metadata":{}},{"cell_type":"code","source":"#filtering only   'Cassava Green Mottle (CGM)' class from original data\nCGM  = train_df[train_df['disease_name'] ==    'Cassava Green Mottle (CGM)']\nprint('Number of Images in Cassava Green Mottle (CGM) Class: '+str(len(CGM)))\n\n#filtering the CMD data for which Mean is between 0.2 and 0.64(observation from box plot)\noutliers_CGM = CGM[CGM['Normalized_Mean'].between(0.2,0.64,inclusive=True)]\n# filter only the rows which are not in above list of images\noutliers_CGM = CGM[~CGM['image_id'].isin(outliers_CGM['image_id'])]\nprint('Number of Outlier Images in Cassava Green Mottle (CGM) Class: '+str(len(outliers_CGM))+'\\n')\nprint(input_path+'train_images/'+outliers_CGM['image_id'].values)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,30))\n#plot all the outlier images based on Mean value\nfor i,idx in enumerate(outliers_CGM.index):\n    plt.subplot(1,3,i%3+1)\n    img_name = outliers_CGM.loc[idx,'image_id']\n    img = cv2.cvtColor(cv2.imread(os.path.join(input_path,'train_images',img_name)),cv2.COLOR_BGR2RGB)\n    plt.imshow(img)\n    plt.title(img_name+'\\n'+'Mean: '+ str(outliers_CGM.loc[idx,'Normalized_Mean'].round(2)) + '\\n'+\\\n              'Standard Deviation: '+str(outliers_CGM.loc[idx,'Normalized_SD'].round(2)))\n    plt.axis('off')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"outlier-ss-5\"></a>\n#### Outliers in 'Healthy'","metadata":{}},{"cell_type":"code","source":"#filtering only   'Healthy' class from original data\nHealthy  = train_df[train_df['disease_name'] ==    'Healthy']\nprint('Number of Images in Healthy Class: '+str(len(Healthy)))\n\n#filtering the CMD data for which Mean is between 0.175 and 0.64 (observation from box plot)\noutliers_Healthy = Healthy[Healthy['Normalized_Mean'].between(0.175,0.64,inclusive=True)]\n# filter only the rows which are not in above list of images\noutliers_Healthy = Healthy[~Healthy['image_id'].isin(outliers_Healthy['image_id'])]\nprint('Number of Outlier Images in Healthy Class: '+str(len(outliers_Healthy))+'\\n')\nprint(input_path+'train_images/'+outliers_Healthy['image_id'].values)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"c = 0\n#plot all the outlier images based on Mean value\nfor i,idx in enumerate(outliers_Healthy.index):\n    # a condition a change the row number in subplot\n    if int(i/4) == c:\n        c+=1\n        plt.figure(figsize=(25,30))\n    plt.subplot(c,4,i%4+1)\n    img_name = outliers_Healthy.loc[idx,'image_id']\n    img = cv2.cvtColor(cv2.imread(os.path.join(input_path,'train_images',img_name)),cv2.COLOR_BGR2RGB)\n    plt.imshow(img)\n    plt.title(img_name+'\\n'+'Mean: '+ str(outliers_Healthy.loc[idx,'Normalized_Mean'].round(2)) + '\\n'+\\\n              'Standard Deviation: '+str(outliers_Healthy.loc[idx,'Normalized_SD'].round(2)))\n    plt.axis('off')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"subsection-five\"></a>\n### Outliers Detection using K-Means Clustering","metadata":{}},{"cell_type":"code","source":"# create an dict to store all k_means_colr values for all the images with flatten structure\nk_means_cluster_colors = {'Cassava Bacterial Blight (CBB)':[],\n                          'Cassava Mosaic Disease (CMD)':[],\n                          'Cassava Brown Streak Disease (CBSD)':[],\n                          'Cassava Green Mottle (CGM)':[],\n                          'Healthy' : []}\nimages = {'Cassava Bacterial Blight (CBB)':[],\n                          'Cassava Mosaic Disease (CMD)':[],\n                          'Cassava Brown Streak Disease (CBSD)':[],\n                          'Cassava Green Mottle (CGM)':[],\n                          'Healthy' : []}\n\nfor class_name in tqdm(train_df['disease_name'].unique()):\n    \n    #filter different classes\n    df = train_df[train_df['disease_name'] == class_name]\n    \n    for idx in tqdm(df.index,desc=class_name):\n        #read image\n        img_name = train_df.loc[idx,'image_id']\n        img = cv2.cvtColor(cv2.imread(input_path+'train_images/'+img_name), cv2.COLOR_BGR2RGB)\n        img = imutils.resize(img,height=150)\n        #normalize the given image\n        norm_img = cv2.normalize(img, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)\n        images[class_name].append(img_name) \n  \n        #k-means chstering with cluster size of 5\n        cluster_centers, distortion = kmeans(norm_img.reshape((-1,3)),5)\n\n        #standard deviation for each color band\n        std = np.expand_dims(img.reshape((-1,3)).std(axis=0),1) \n\n        k_means_cluster_colors[class_name].append((np.matmul(cluster_centers,std).T).astype(int)[0])\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"ss-k-1\"></a>\n#### Z-Score\n\nZ score is an important concept in statistics. Z score is also called standard score. This score helps to understand if a data value is greater or smaller than mean and how far away it is from the mean. More specifically, Z score tells how many standard deviations away a data point is from the mean.If the z score of a data point is more than 3, it indicates that the data point is quite different from the other data points. Such a data point can be an outlier.\n\n**$$Zscore=\\frac{x-Mean}{Standart Deviation}$$**\n","metadata":{}},{"cell_type":"code","source":"colors = ['rgb(13, 200, 58)','rgb(13, 160, 200)','rgb(190, 81, 249)','rgb(248, 104, 73)','rgb(243, 247, 15)']\nfor idx,class_name in enumerate(k_means_cluster_colors):\n    x = np.sum(k_means_cluster_colors[class_name],axis=1)\n    z_score = zscore(x)\n    fig=go.Figure()\n    fig.add_trace(go.Histogram(x=z_score,\n                              marker_color=colors[idx]))\n    fig.update_layout(title=class_name)\n    fig.show()","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"k_means_outliers = {'Cassava Bacterial Blight (CBB)':[],\n                          'Cassava Mosaic Disease (CMD)':[],\n                          'Cassava Brown Streak Disease (CBSD)':[],\n                          'Cassava Green Mottle (CGM)':[],\n                          'Healthy' : []}\nprint('Outliers based on K-Means result')\nfor idx,class_name in enumerate(k_means_cluster_colors):\n    x = np.sum(k_means_cluster_colors[class_name],axis=1)\n    z_score = zscore(x)\n    k_means_outliers[class_name].append(list(np.where((z_score>3))[0]) + list(np.where((z_score<-3))[0]))\n    print('Number of Outliers from '+class_name+': '+str(len(k_means_outliers[class_name][0])))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### Visulaizing 5 random images from K-Means Method","metadata":{}},{"cell_type":"code","source":"for class_name in k_means_outliers:\n    print('Outliers: '+ class_name)\n    plt.figure(figsize=(20,5))\n    imgs = []\n    for idx,img_name in enumerate(np.random.choice(k_means_outliers[class_name][0],5,replace=False)):\n        img_name=  images[class_name][img_name]\n        img = cv2.cvtColor(cv2.imread(input_path+'train_images/'+img_name),cv2.COLOR_BGR2RGB)\n        plt.subplot(1,5,idx%5+1)\n        plt.imshow(img)\n        plt.axis('off')\n        plt.title(class_name+'\\n'+img_name)\n    plt.show()\n    print('Image Names: '+'\\n')\n    for idx in k_means_outliers[class_name][0]:\n        imgs.append(images[class_name][idx])\n    print(', '.join(imgs)+'\\n\\n')\n        ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"section-six\"></a>\n## Feature Extraction","metadata":{}},{"cell_type":"markdown","source":"In this part, we will be extracting features from pretrained networks and find the important fetures using PCA and t-sne (Dimensionality reduction methods)","metadata":{}},{"cell_type":"markdown","source":"<a id=\"ss-fe-1\"></a>\n#### VGG","metadata":{}},{"cell_type":"code","source":"class Load_Dataset(torch.utils.data.Dataset):\n    def __init__(self,df):\n        self.image_paths = df['image_id']\n        self.labels = df['label']\n        self.default_transform = Compose([\n            Normalize((0.485, 0.456, 0.406),\n                                 (0.229, 0.224, 0.225),always_apply=True),\n            Resize(224,224),\n            ToTensor()\n        ])\n        \n    def __len__(self):\n        return self.image_paths.shape[0]\n    \n    def __getitem__(self,i):\n        image_name = self.image_paths[i]\n        img_path = os.path.join('../input/cassava-leaf-disease-classification/train_images',image_name)\n        image = cv2.cvtColor(cv2.imread(img_path),cv2.COLOR_BGR2RGB)\n        image = self.default_transform(image=image)['image']\n        label = torch.tensor(self.labels[i])\n\n        return image,label","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Load dataset\ntrain_data = Load_Dataset(train_df)\ntrain_loader = torch.utils.data.DataLoader(train_data,batch_size=128)\n\n#loading pretrained model for vgg19\nvgg_m = models.vgg19(pretrained=True)\n#taking only the first layer from classifier (4096)\nvgg_m.classifier = torch.nn.Sequential(vgg_m.classifier[0])\noutput_descriptor = np.zeros((1,4096))\noutput_label = np.zeros((1))\ndevice = 'cuda'\nvgg_m.to(device)\nwith torch.no_grad():\n    for _, (images,labels) in tqdm(enumerate(train_loader)):\n        \n        images,labels = images.to(device),labels.to(device)\n        #evaluating the image with pretrained model\n        vgg_m.eval()\n        pred = vgg_m(images)\n        #concatenating all the outputs and labels as a batch of 128 and store in a variable\n        output_descriptor =np.concatenate((output_descriptor,pred.cpu().numpy().squeeze()),0)\n        output_label = np.concatenate((output_label,labels.cpu().numpy()))\noutput_descriptor = output_descriptor[1:]\noutput_label = output_label[1:]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### PCA","metadata":{}},{"cell_type":"code","source":"st_time = time.time()\n#extracting top 5 principal component features\npca = PCA(n_components=5)\npca_result_train = pca.fit_transform(output_descriptor)\n\nprint('PCA done; Time take {} seconds'.format(time.time()-st_time))\nprint('Variance: {}'.format(pca.explained_variance_ratio_))\nprint('Sum of variance in data by first top ten components: {:.2f}%'.format(100*(pca.explained_variance_ratio_.sum())))\n\n##PCA df\npca_tr = pd.DataFrame()\nfor idx in range(pca_result_train.shape[1]):\n    pca_tr['pca'+str(idx+1)] = pca_result_train[:,idx]\n\npca_tr['label'] = output_label.astype(int)\npca_tr['disease_name'] = pca_tr['label'].apply(lambda x: disease_names[str(x)])\npca_tr.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = go.Figure()\ncolors = ['rgb(13, 200, 58)','rgb(13, 160, 200)','rgb(190, 81, 249)','rgb(248, 104, 73)','rgb(243, 247, 15)']\nfor idx,dn in enumerate(pca_tr['disease_name'].unique()):\n    df = pca_tr[pca_tr['disease_name'] == dn]\n    fig.add_trace(go.Scatter3d(x=df['pca1'],y=df['pca2'],z=df['pca3'],mode='markers',marker_color = colors[idx],name=dn))\nfig.update_layout(title='PCA 1 Vs PCA 2 Vs PCA 3')\nfig.show()","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### T-SNE","metadata":{}},{"cell_type":"code","source":"st_time = time.time()\nt_sne = TSNE(random_state=2020)\nt_sne_tr = t_sne.fit_transform(output_descriptor)\nprint('TNSE done; Time take {} seconds'.format(time.time()-st_time))\n\n##T-SNE df\ntsne_tr = pd.DataFrame()\nfor idx in range(t_sne_tr.shape[1]):\n    tsne_tr['t_sne'+str(idx+1)] = t_sne_tr[:,idx]\ntsne_tr['label'] = output_label.astype(int)\ntsne_tr['disease_name'] = tsne_tr['label'].apply(lambda x: disease_names[str(x)])\ntsne_tr.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = go.Figure()\ncolors = ['rgb(13, 200, 58)','rgb(13, 160, 200)','rgb(190, 81, 249)','rgb(248, 104, 73)','rgb(243, 247, 15)']\nfor idx,dn in enumerate(tsne_tr['disease_name'].unique()):\n    df = tsne_tr[tsne_tr['disease_name'] == dn]\n    fig.add_trace(go.Scatter(x=df['t_sne1'],y=df['t_sne2'],mode='markers',marker_color = colors[idx],name=dn))\nfig.update_layout(title='TSNE 1 Vs TSNE 2')\nfig.update_xaxes(title_text=\"TSNE_1\")\nfig.update_yaxes(title_text=\"TSNE_2\")\nfig.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Please give your feedbacks and comments and Do **\"Upvote\"** !!!","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}