{"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":"code","source":"!pip install -Uqq fastai","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:06.609218Z","iopub.execute_input":"2022-05-05T10:05:06.609746Z","iopub.status.idle":"2022-05-05T10:05:27.425784Z","shell.execute_reply.started":"2022-05-05T10:05:06.609656Z","shell.execute_reply":"2022-05-05T10:05:27.424978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nfrom fastai.vision.all import *\nfrom sklearn.model_selection import StratifiedKFold","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-05T10:05:27.428065Z","iopub.execute_input":"2022-05-05T10:05:27.428334Z","iopub.status.idle":"2022-05-05T10:05:30.138264Z","shell.execute_reply.started":"2022-05-05T10:05:27.428302Z","shell.execute_reply":"2022-05-05T10:05:30.137517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = Path('../input/sorghum-id-fgvc-9')","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.139339Z","iopub.execute_input":"2022-05-05T10:05:30.140287Z","iopub.status.idle":"2022-05-05T10:05:30.144499Z","shell.execute_reply.started":"2022-05-05T10:05:30.140257Z","shell.execute_reply":"2022-05-05T10:05:30.143770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(path/'train_cultivar_mapping.csv')","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.147064Z","iopub.execute_input":"2022-05-05T10:05:30.147861Z","iopub.status.idle":"2022-05-05T10:05:30.189656Z","shell.execute_reply.started":"2022-05-05T10:05:30.147823Z","shell.execute_reply":"2022-05-05T10:05:30.188989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.describe()","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.190738Z","iopub.execute_input":"2022-05-05T10:05:30.191061Z","iopub.status.idle":"2022-05-05T10:05:30.235399Z","shell.execute_reply.started":"2022-05-05T10:05:30.191025Z","shell.execute_reply":"2022-05-05T10:05:30.234661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Cleaning","metadata":{}},{"cell_type":"code","source":"train_df.dropna(inplace=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.236597Z","iopub.execute_input":"2022-05-05T10:05:30.237062Z","iopub.status.idle":"2022-05-05T10:05:30.248093Z","shell.execute_reply.started":"2022-05-05T10:05:30.237020Z","shell.execute_reply":"2022-05-05T10:05:30.247407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.shape","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.249314Z","iopub.execute_input":"2022-05-05T10:05:30.249632Z","iopub.status.idle":"2022-05-05T10:05:30.257494Z","shell.execute_reply.started":"2022-05-05T10:05:30.249597Z","shell.execute_reply":"2022-05-05T10:05:30.256671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.describe()","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.259147Z","iopub.execute_input":"2022-05-05T10:05:30.260070Z","iopub.status.idle":"2022-05-05T10:05:30.289590Z","shell.execute_reply.started":"2022-05-05T10:05:30.260033Z","shell.execute_reply":"2022-05-05T10:05:30.288831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = train_df.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.290790Z","iopub.execute_input":"2022-05-05T10:05:30.291049Z","iopub.status.idle":"2022-05-05T10:05:30.295327Z","shell.execute_reply.started":"2022-05-05T10:05:30.291017Z","shell.execute_reply":"2022-05-05T10:05:30.294540Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.296864Z","iopub.execute_input":"2022-05-05T10:05:30.297412Z","iopub.status.idle":"2022-05-05T10:05:30.307776Z","shell.execute_reply.started":"2022-05-05T10:05:30.297353Z","shell.execute_reply":"2022-05-05T10:05:30.307002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Getting the unique values of cultivar and their counts","metadata":{}},{"cell_type":"code","source":"\ntrain_df.cultivar.unique()","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.311479Z","iopub.execute_input":"2022-05-05T10:05:30.312137Z","iopub.status.idle":"2022-05-05T10:05:30.320819Z","shell.execute_reply.started":"2022-05-05T10:05:30.312101Z","shell.execute_reply":"2022-05-05T10:05:30.320071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.cultivar.value_counts().reset_index()","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.321792Z","iopub.execute_input":"2022-05-05T10:05:30.323500Z","iopub.status.idle":"2022-05-05T10:05:30.339717Z","shell.execute_reply.started":"2022-05-05T10:05:30.323476Z","shell.execute_reply":"2022-05-05T10:05:30.338988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# K Fold Splitting","metadata":{}},{"cell_type":"code","source":"N_SPLITS = 5","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.341678Z","iopub.execute_input":"2022-05-05T10:05:30.342147Z","iopub.status.idle":"2022-05-05T10:05:30.345648Z","shell.execute_reply.started":"2022-05-05T10:05:30.342113Z","shell.execute_reply":"2022-05-05T10:05:30.345006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nskf = StratifiedKFold(n_splits=N_SPLITS, shuffle=True)\ntrain_df[\"kfold\"] = -1\nfor fold, (_, val_index) in enumerate(skf.split(X = train_df.image.values, y = train_df.cultivar.values)):\n    train_df.iloc[val_index, -1] = fold","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.346912Z","iopub.execute_input":"2022-05-05T10:05:30.347657Z","iopub.status.idle":"2022-05-05T10:05:30.406600Z","shell.execute_reply.started":"2022-05-05T10:05:30.347622Z","shell.execute_reply":"2022-05-05T10:05:30.405900Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.407865Z","iopub.execute_input":"2022-05-05T10:05:30.408125Z","iopub.status.idle":"2022-05-05T10:05:30.417088Z","shell.execute_reply.started":"2022-05-05T10:05:30.408092Z","shell.execute_reply":"2022-05-05T10:05:30.416250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def splitter(df, fold=0):\n    train_idx = df.index[df.kfold != fold].tolist()\n    valid_idx = df.index[df.kfold == fold].tolist()\n    return [train_idx, valid_idx]","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.418696Z","iopub.execute_input":"2022-05-05T10:05:30.419319Z","iopub.status.idle":"2022-05-05T10:05:30.425849Z","shell.execute_reply.started":"2022-05-05T10:05:30.419283Z","shell.execute_reply":"2022-05-05T10:05:30.425071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(N_SPLITS):\n    print(train_df[train_df.kfold == i].shape)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.427464Z","iopub.execute_input":"2022-05-05T10:05:30.427761Z","iopub.status.idle":"2022-05-05T10:05:30.443271Z","shell.execute_reply.started":"2022-05-05T10:05:30.427726Z","shell.execute_reply":"2022-05-05T10:05:30.442649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DataLoaders, Training and Inference","metadata":{}},{"cell_type":"code","source":"def get_data(fold=0):\n    datablock = DataBlock(\n        blocks = (ImageBlock, CategoryBlock),\n        get_x = ColReader('image', path/'train_images'),\n        get_y = ColReader('cultivar'),\n        splitter = splitter,\n        item_tfms = Resize(225)\n    )\n    dls = datablock.dataloaders(train_df)\n    return dls","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.445744Z","iopub.execute_input":"2022-05-05T10:05:30.446278Z","iopub.status.idle":"2022-05-05T10:05:30.451427Z","shell.execute_reply.started":"2022-05-05T10:05:30.446240Z","shell.execute_reply":"2022-05-05T10:05:30.450760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Training the model for 5 epochs for each fold and using K Fold Cross Validation technique, then performing the inference for each fold and appending the predictions in a list.","metadata":{}},{"cell_type":"code","source":"predictions = []\nfor i in range(N_SPLITS):\n    dls = get_data(i)\n    learn = vision_learner(dls, resnet34, metrics = accuracy)\n    learn.fine_tune(5)\n    try:\n        learn.export(f'path/model_fold_{i}.pkl')\n        print(f'Model for fold {i} is saved.')\n    except:\n        print(f'Model for fold {i} is not saved.')\n    \n    test_images = get_image_files(path/'test')\n    test_dataloader = learn.dls.test_dl(test_images)\n    preds, _ = learn.get_preds(dl=test_dataloader)\n    predictions.append(preds)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T10:05:30.454091Z","iopub.execute_input":"2022-05-05T10:05:30.454734Z","iopub.status.idle":"2022-05-05T19:18:39.020612Z","shell.execute_reply.started":"2022-05-05T10:05:30.454699Z","shell.execute_reply":"2022-05-05T19:18:39.019832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(predictions), predictions[0].shape","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:39.022424Z","iopub.execute_input":"2022-05-05T19:18:39.022700Z","iopub.status.idle":"2022-05-05T19:18:39.029258Z","shell.execute_reply.started":"2022-05-05T19:18:39.022664Z","shell.execute_reply":"2022-05-05T19:18:39.028439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions[0][0]","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:39.030665Z","iopub.execute_input":"2022-05-05T19:18:39.030919Z","iopub.status.idle":"2022-05-05T19:18:39.065675Z","shell.execute_reply.started":"2022-05-05T19:18:39.030887Z","shell.execute_reply":"2022-05-05T19:18:39.065007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.stack(predictions).shape","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:39.068506Z","iopub.execute_input":"2022-05-05T19:18:39.068858Z","iopub.status.idle":"2022-05-05T19:18:39.107032Z","shell.execute_reply.started":"2022-05-05T19:18:39.068831Z","shell.execute_reply":"2022-05-05T19:18:39.106191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Finding the mean of each predcitions","metadata":{}},{"cell_type":"code","source":"pred_idxs = torch.mean(torch.stack(predictions), axis=0)\npred_idxs.shape","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:39.108366Z","iopub.execute_input":"2022-05-05T19:18:39.108685Z","iopub.status.idle":"2022-05-05T19:18:39.152456Z","shell.execute_reply.started":"2022-05-05T19:18:39.108648Z","shell.execute_reply":"2022-05-05T19:18:39.151674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Finding the class having maximum probability","metadata":{}},{"cell_type":"code","source":"class_idxs = torch.argmax(pred_idxs, axis=1)\nclass_idxs.shape","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:39.153780Z","iopub.execute_input":"2022-05-05T19:18:39.154216Z","iopub.status.idle":"2022-05-05T19:18:39.174455Z","shell.execute_reply.started":"2022-05-05T19:18:39.154178Z","shell.execute_reply":"2022-05-05T19:18:39.173810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_idxs[0]","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:39.175582Z","iopub.execute_input":"2022-05-05T19:18:39.175913Z","iopub.status.idle":"2022-05-05T19:18:39.182800Z","shell.execute_reply.started":"2022-05-05T19:18:39.175869Z","shell.execute_reply":"2022-05-05T19:18:39.181981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dls.vocab[class_idxs]","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:39.184361Z","iopub.execute_input":"2022-05-05T19:18:39.184803Z","iopub.status.idle":"2022-05-05T19:18:39.423758Z","shell.execute_reply.started":"2022-05-05T19:18:39.184771Z","shell.execute_reply":"2022-05-05T19:18:39.423117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results = [dls.vocab[i] for i in class_idxs]","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:39.425132Z","iopub.execute_input":"2022-05-05T19:18:39.425381Z","iopub.status.idle":"2022-05-05T19:18:41.272304Z","shell.execute_reply.started":"2022-05-05T19:18:39.425348Z","shell.execute_reply":"2022-05-05T19:18:41.271573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(class_idxs)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:41.273645Z","iopub.execute_input":"2022-05-05T19:18:41.273891Z","iopub.status.idle":"2022-05-05T19:18:41.280631Z","shell.execute_reply.started":"2022-05-05T19:18:41.273848Z","shell.execute_reply":"2022-05-05T19:18:41.279996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(test_images)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:41.282083Z","iopub.execute_input":"2022-05-05T19:18:41.282571Z","iopub.status.idle":"2022-05-05T19:18:41.291888Z","shell.execute_reply.started":"2022-05-05T19:18:41.282535Z","shell.execute_reply":"2022-05-05T19:18:41.291233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(results)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:41.294510Z","iopub.execute_input":"2022-05-05T19:18:41.294687Z","iopub.status.idle":"2022-05-05T19:18:41.302485Z","shell.execute_reply.started":"2022-05-05T19:18:41.294667Z","shell.execute_reply":"2022-05-05T19:18:41.301759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Saving predictions in a dataframe and then to a csv file","metadata":{}},{"cell_type":"markdown","source":"Creating a dataframe containg predictions for each image","metadata":{}},{"cell_type":"code","source":"images = [img.name for img in (path/'test').ls()]\nsubmissions = pd.DataFrame(list(zip(images, results)), columns = ['filename', 'cultivar'])","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:41.303580Z","iopub.execute_input":"2022-05-05T19:18:41.303786Z","iopub.status.idle":"2022-05-05T19:18:41.393844Z","shell.execute_reply.started":"2022-05-05T19:18:41.303763Z","shell.execute_reply":"2022-05-05T19:18:41.393165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submissions.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:41.398712Z","iopub.execute_input":"2022-05-05T19:18:41.398913Z","iopub.status.idle":"2022-05-05T19:18:41.411350Z","shell.execute_reply.started":"2022-05-05T19:18:41.398889Z","shell.execute_reply":"2022-05-05T19:18:41.410482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Saving the dataframe in the csv format","metadata":{}},{"cell_type":"code","source":"submissions.to_csv('submission.csv', index = False)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T19:18:41.413054Z","iopub.execute_input":"2022-05-05T19:18:41.413521Z","iopub.status.idle":"2022-05-05T19:18:41.468797Z","shell.execute_reply.started":"2022-05-05T19:18:41.413484Z","shell.execute_reply":"2022-05-05T19:18:41.468092Z"},"trusted":true},"execution_count":null,"outputs":[]}]}