{"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":"## Importing the Library","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"from fastai.vision.all import *","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:56.334815Z","iopub.execute_input":"2021-08-04T01:10:56.335224Z","iopub.status.idle":"2021-08-04T01:10:58.972526Z","shell.execute_reply.started":"2021-08-04T01:10:56.335138Z","shell.execute_reply":"2021-08-04T01:10:58.9717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"set the random, torch, and numpy seeds with the set_seed function","metadata":{}},{"cell_type":"code","source":"set_seed(16)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:58.974072Z","iopub.execute_input":"2021-08-04T01:10:58.974413Z","iopub.status.idle":"2021-08-04T01:10:58.978491Z","shell.execute_reply.started":"2021-08-04T01:10:58.974377Z","shell.execute_reply":"2021-08-04T01:10:58.97769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Setting up our data\n","metadata":{}},{"cell_type":"code","source":"path = Path(\"../input\")","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:58.980255Z","iopub.execute_input":"2021-08-04T01:10:58.980777Z","iopub.status.idle":"2021-08-04T01:10:58.989224Z","shell.execute_reply.started":"2021-08-04T01:10:58.98074Z","shell.execute_reply":"2021-08-04T01:10:58.988156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### ls fxn is used to see all files and directories inhere","metadata":{}},{"cell_type":"code","source":"path.ls()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:58.991115Z","iopub.execute_input":"2021-08-04T01:10:58.991662Z","iopub.status.idle":"2021-08-04T01:10:59.003551Z","shell.execute_reply.started":"2021-08-04T01:10:58.991521Z","shell.execute_reply":"2021-08-04T01:10:59.002754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_path = path/'cassava-leaf-disease-classification'\ndata_path.ls()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.006481Z","iopub.execute_input":"2021-08-04T01:10:59.006722Z","iopub.status.idle":"2021-08-04T01:10:59.0158Z","shell.execute_reply.started":"2021-08-04T01:10:59.0067Z","shell.execute_reply":"2021-08-04T01:10:59.015053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### loading train.csv with the help of pandas","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(data_path/'train.csv')","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.017149Z","iopub.execute_input":"2021-08-04T01:10:59.017557Z","iopub.status.idle":"2021-08-04T01:10:59.048745Z","shell.execute_reply.started":"2021-08-04T01:10:59.017519Z","shell.execute_reply":"2021-08-04T01:10:59.047913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Sample data","metadata":{}},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.050024Z","iopub.execute_input":"2021-08-04T01:10:59.050608Z","iopub.status.idle":"2021-08-04T01:10:59.069319Z","shell.execute_reply.started":"2021-08-04T01:10:59.050565Z","shell.execute_reply":"2021-08-04T01:10:59.068487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We have an `image_id` and a `label`. We're going to modify our values in `image_id` to make our lives easier when it comes to running inference. \n\nWhy? \n\n\nIn fastai we have a `get_x` and a `get_y` and this will dictate how it will *always* look for our data, regardless of how it is stored. If we built a `get_y` based on the current `DataFrame`, it would look something like so:","metadata":{}},{"cell_type":"code","source":"def get_x(row): return data_path/'train_images'/row['image_id']","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.072085Z","iopub.execute_input":"2021-08-04T01:10:59.072421Z","iopub.status.idle":"2021-08-04T01:10:59.076124Z","shell.execute_reply.started":"2021-08-04T01:10:59.07239Z","shell.execute_reply":"2021-08-04T01:10:59.075172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PILImage.create(get_x(df.iloc[0]))","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.078642Z","iopub.execute_input":"2021-08-04T01:10:59.079053Z","iopub.status.idle":"2021-08-04T01:10:59.277459Z","shell.execute_reply.started":"2021-08-04T01:10:59.079018Z","shell.execute_reply":"2021-08-04T01:10:59.27644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.iloc[0]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.27883Z","iopub.execute_input":"2021-08-04T01:10:59.27925Z","iopub.status.idle":"2021-08-04T01:10:59.287416Z","shell.execute_reply.started":"2021-08-04T01:10:59.279209Z","shell.execute_reply":"2021-08-04T01:10:59.286513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" ***But*** there is a very large issue here. We always have our `get_x` tied to the training directory which makes it more complicated for us to work with our `test_images` directory.\n\nWhat's the solution? \n\nAdd `train_images` into the dataframe through a `lambda` function:","metadata":{}},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.288897Z","iopub.execute_input":"2021-08-04T01:10:59.289553Z","iopub.status.idle":"2021-08-04T01:10:59.300493Z","shell.execute_reply.started":"2021-08-04T01:10:59.289463Z","shell.execute_reply":"2021-08-04T01:10:59.299637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['image_id'] = df['image_id'].apply(lambda x: f'train_images/{x}')","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.301532Z","iopub.execute_input":"2021-08-04T01:10:59.30203Z","iopub.status.idle":"2021-08-04T01:10:59.318844Z","shell.execute_reply.started":"2021-08-04T01:10:59.301992Z","shell.execute_reply":"2021-08-04T01:10:59.318053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.31998Z","iopub.execute_input":"2021-08-04T01:10:59.320463Z","iopub.status.idle":"2021-08-04T01:10:59.331253Z","shell.execute_reply.started":"2021-08-04T01:10:59.320428Z","shell.execute_reply":"2021-08-04T01:10:59.330473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now we won't run into an issue when we're testing. ","metadata":{}},{"cell_type":"markdown","source":"### Adjusting our label\n\nWhat else can we do?\n\nLet's change our lables into something more readable through a dictionary (these come from the `json` file):","metadata":{}},{"cell_type":"code","source":"idx2lbl = {0:\"Cassava Bacterial Blight (CBB)\",\n          1:\"Cassava Brown Streak Disease (CBSD)\",\n          2:\"Cassava Green Mottle (CGM)\",\n          3:\"Cassava Mosaic Disease (CMD)\",\n          4:\"Healthy\"}\n\ndf['label'].replace(idx2lbl, inplace=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.332356Z","iopub.execute_input":"2021-08-04T01:10:59.332797Z","iopub.status.idle":"2021-08-04T01:10:59.341487Z","shell.execute_reply.started":"2021-08-04T01:10:59.332762Z","shell.execute_reply":"2021-08-04T01:10:59.340273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.343054Z","iopub.execute_input":"2021-08-04T01:10:59.343702Z","iopub.status.idle":"2021-08-04T01:10:59.356609Z","shell.execute_reply.started":"2021-08-04T01:10:59.34364Z","shell.execute_reply":"2021-08-04T01:10:59.35571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Building the `DataBlock`\n​\nLet's think about how our problem looks. `fastai` provides blocks to center around *most* situations, and this is no exception.\n​\nWe know our input is an image and our output is a category, so let's use `ImageBlock` and `CategoryBlock`:","metadata":{}},{"cell_type":"code","source":"blocks = (ImageBlock, CategoryBlock)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.357876Z","iopub.execute_input":"2021-08-04T01:10:59.358431Z","iopub.status.idle":"2021-08-04T01:10:59.362677Z","shell.execute_reply.started":"2021-08-04T01:10:59.358391Z","shell.execute_reply":"2021-08-04T01:10:59.361541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next we'll want to split our data somehow. We'll use a `RandomSplitter` and split our data 80/20","metadata":{}},{"cell_type":"code","source":"splitter = RandomSplitter(valid_pct=0.2)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.364236Z","iopub.execute_input":"2021-08-04T01:10:59.364989Z","iopub.status.idle":"2021-08-04T01:10:59.372305Z","shell.execute_reply.started":"2021-08-04T01:10:59.364862Z","shell.execute_reply":"2021-08-04T01:10:59.370991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Our `DataBlock` is also going to want to know how to get our data. Since our data all stems from a `csv`, we will make a `get_x` and `get_y` function:\n(we already made our `get_x`)","metadata":{}},{"cell_type":"code","source":"def get_x(row): return data_path/row['image_id']\n\ndef get_y(row): return row['label']","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.3739Z","iopub.execute_input":"2021-08-04T01:10:59.374629Z","iopub.status.idle":"2021-08-04T01:10:59.381069Z","shell.execute_reply.started":"2021-08-04T01:10:59.374585Z","shell.execute_reply":"2021-08-04T01:10:59.380179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can see that when we write custom `get_` functions, it will accept one *row* of our `DataFrame` to look at, and so we can filter as a result.\n\nNext we'll come up with some basic data augmentations. \n\nOur `item_tfms` should ensure everything is ready to go into a batch, so we will use `Resize`.\n\nOur `batch_tfms` should apply any extra augmentations we may want. We'll use `RandomResizedCropGPU`, `aug_transforms`, and apply our `Normalize`:\n> We will normalize our data based on ImageNet, since that is what our pretrained model was trained with","metadata":{}},{"cell_type":"code","source":"item_tfms = [Resize(448)]\nbatch_tfms = [RandomResizedCropGPU(224), *aug_transforms(), Normalize.from_stats(*imagenet_stats)]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:10:59.382606Z","iopub.execute_input":"2021-08-04T01:10:59.383251Z","iopub.status.idle":"2021-08-04T01:11:03.597117Z","shell.execute_reply.started":"2021-08-04T01:10:59.383212Z","shell.execute_reply":"2021-08-04T01:11:03.596246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Lets Build our first DataBlock","metadata":{}},{"cell_type":"code","source":"block = DataBlock(blocks = blocks,\n                 get_x = get_x,\n                 get_y = get_y,\n                 splitter = splitter,\n                 item_tfms = item_tfms,\n                 batch_tfms = batch_tfms)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:11:03.600309Z","iopub.execute_input":"2021-08-04T01:11:03.600586Z","iopub.status.idle":"2021-08-04T01:11:03.607162Z","shell.execute_reply.started":"2021-08-04T01:11:03.600558Z","shell.execute_reply":"2021-08-04T01:11:03.606322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"And now we can turn this into some `DataLoaders`. We're going to pass in some items (which in our case is our `DataFrame`) and a batch size to use. We will use 64:","metadata":{}},{"cell_type":"code","source":"dls = block.dataloaders(df, bs=64)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:11:03.608526Z","iopub.execute_input":"2021-08-04T01:11:03.609067Z","iopub.status.idle":"2021-08-04T01:11:07.908195Z","shell.execute_reply.started":"2021-08-04T01:11:03.60903Z","shell.execute_reply":"2021-08-04T01:11:07.90736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dls.show_batch(figsize=(12,12))","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:11:07.909477Z","iopub.execute_input":"2021-08-04T01:11:07.909837Z","iopub.status.idle":"2021-08-04T01:11:10.636753Z","shell.execute_reply.started":"2021-08-04T01:11:07.909799Z","shell.execute_reply":"2021-08-04T01:11:10.635995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training Model","metadata":{"execution":{"iopub.status.busy":"2021-08-04T00:55:13.811185Z","iopub.execute_input":"2021-08-04T00:55:13.81157Z","iopub.status.idle":"2021-08-04T00:55:13.815745Z","shell.execute_reply.started":"2021-08-04T00:55:13.811538Z","shell.execute_reply":"2021-08-04T00:55:13.814624Z"}}},{"cell_type":"code","source":"# Making pretrained weights work without needing to find the default filename\nif not os.path.exists('/root/.cache/torch/hub/checkpoints/'):\n        os.makedirs('/root/.cache/torch/hub/checkpoints/')\n!cp '../input/resnet50/resnet50.pth' '/root/.cache/torch/hub/checkpoints/resnet50-19c8e357.pth'","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:11:10.639771Z","iopub.execute_input":"2021-08-04T01:11:10.640326Z","iopub.status.idle":"2021-08-04T01:11:13.977817Z","shell.execute_reply.started":"2021-08-04T01:11:10.640279Z","shell.execute_reply":"2021-08-04T01:11:13.976607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now that our weights are setup, let's look at how to use `cnn_learner`. We're going to use a few tricks during our training that fastai can help us out with. \n\nSpecifically we will be using the `ranger` optimizer function and `LabelSmoothingCrossEntropy` as our loss function.\n\nAlong with these we'll be using the `accuracy` metric as this is how this competition will grade our results with:","metadata":{}},{"cell_type":"code","source":"learn = cnn_learner(dls, resnet50, opt_func=ranger, loss_func=LabelSmoothingCrossEntropy(), metrics=accuracy)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:11:13.97966Z","iopub.execute_input":"2021-08-04T01:11:13.980014Z","iopub.status.idle":"2021-08-04T01:11:15.15185Z","shell.execute_reply.started":"2021-08-04T01:11:13.979972Z","shell.execute_reply":"2021-08-04T01:11:15.150995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fine_tune(self:Learner, epochs, base_lr=2e-3, freeze_epochs=1, lr_mult=100,\n              pct_start=0.3, div=5.0, **kwargs):\n    \"Fine tune with `freeze` for `freeze_epochs` then with `unfreeze` from `epochs` using discriminative LR\"\n    self.freeze()\n    self.fit_one_cycle(freeze_epochs, slice(base_lr), pct_start=0.99, **kwargs)\n    base_lr /= 2\n    self.unfreeze()\n    self.fit_one_cycle(epochs, slice(base_lr/lr_mult, base_lr), pct_start=pct_start, div=div, **kwargs)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:11:15.153224Z","iopub.execute_input":"2021-08-04T01:11:15.153557Z","iopub.status.idle":"2021-08-04T01:11:15.159196Z","shell.execute_reply.started":"2021-08-04T01:11:15.15352Z","shell.execute_reply":"2021-08-04T01:11:15.158362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@patch\ndef fine_tune_flat(self:Learner, epochs, base_lr=4e-3, freeze_epochs=1, lr_mult=100, pct_start=0.75, \n                   first_callbacks = [], second_callbacks = [], **kwargs):\n    \"Fine-tune applied to `fit_flat_cos`\"\n    self.freeze()\n    self.fit_flat_cos(freeze_epochs, slice(base_lr), pct_start=0.99, cbs=first_callbacks, **kwargs)\n    base_lr /= 2\n    self.unfreeze()\n    self.fit_flat_cos(epochs, slice(base_lr/lr_mult, base_lr), pct_start=pct_start, cbs=second_callbacks)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:18:19.695285Z","iopub.execute_input":"2021-08-04T01:18:19.695649Z","iopub.status.idle":"2021-08-04T01:18:19.701337Z","shell.execute_reply.started":"2021-08-04T01:18:19.695617Z","shell.execute_reply":"2021-08-04T01:18:19.700507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.lr_find()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:11:22.740923Z","iopub.execute_input":"2021-08-04T01:11:22.74129Z","iopub.status.idle":"2021-08-04T01:13:14.910064Z","shell.execute_reply.started":"2021-08-04T01:11:22.741257Z","shell.execute_reply":"2021-08-04T01:13:14.909221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cbs1 = [MixUp(alpha = 0.7)]\ncbs2 = [MixUp(alpha = 0.3)]","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:15:22.063944Z","iopub.execute_input":"2021-08-04T01:15:22.06433Z","iopub.status.idle":"2021-08-04T01:15:22.069945Z","shell.execute_reply.started":"2021-08-04T01:15:22.064298Z","shell.execute_reply":"2021-08-04T01:15:22.068899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.fine_tune_flat(5, base_lr=1e-3, pct_start=0.72, first_callbacks=cbs1, second_callbacks=cbs2)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:20:47.203552Z","iopub.execute_input":"2021-08-04T01:20:47.203896Z","iopub.status.idle":"2021-08-04T01:52:47.249419Z","shell.execute_reply.started":"2021-08-04T01:20:47.203863Z","shell.execute_reply":"2021-08-04T01:52:47.248532Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submitting some results\n","metadata":{}},{"cell_type":"markdown","source":"Let's look at the sample submission dataframe first:","metadata":{}},{"cell_type":"code","source":"sample_df = pd.read_csv(data_path/'sample_submission.csv')\nsample_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:53:53.574806Z","iopub.execute_input":"2021-08-04T01:53:53.575169Z","iopub.status.idle":"2021-08-04T01:53:53.597411Z","shell.execute_reply.started":"2021-08-04T01:53:53.575133Z","shell.execute_reply":"2021-08-04T01:53:53.596653Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's look at the sample submission dataframe first:","metadata":{}},{"cell_type":"code","source":"sample_copy = sample_df.copy()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:54:09.551752Z","iopub.execute_input":"2021-08-04T01:54:09.552135Z","iopub.status.idle":"2021-08-04T01:54:09.557922Z","shell.execute_reply.started":"2021-08-04T01:54:09.552076Z","shell.execute_reply":"2021-08-04T01:54:09.556694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_copy['image_id'] = sample_copy['image_id'].apply(lambda x: f'test_images/{x}')","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:54:13.831146Z","iopub.execute_input":"2021-08-04T01:54:13.831505Z","iopub.status.idle":"2021-08-04T01:54:13.837314Z","shell.execute_reply.started":"2021-08-04T01:54:13.831476Z","shell.execute_reply":"2021-08-04T01:54:13.836228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next we'll make an inference dataloader through the `test_dl` method:","metadata":{}},{"cell_type":"code","source":"test_dl = learn.dls.test_dl(sample_copy)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:54:16.809453Z","iopub.execute_input":"2021-08-04T01:54:16.809774Z","iopub.status.idle":"2021-08-04T01:54:16.81758Z","shell.execute_reply.started":"2021-08-04T01:54:16.809747Z","shell.execute_reply":"2021-08-04T01:54:16.816728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We'll look at a batch of data to make sure it all looks okay:","metadata":{}},{"cell_type":"code","source":"test_dl.show_batch()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:54:21.250594Z","iopub.execute_input":"2021-08-04T01:54:21.250912Z","iopub.status.idle":"2021-08-04T01:54:21.360839Z","shell.execute_reply.started":"2021-08-04T01:54:21.250883Z","shell.execute_reply":"2021-08-04T01:54:21.360015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next we'll grab some predictions. We will use the `.tta` method to run test-time-augmentation which can help boost our accuracy some:","metadata":{}},{"cell_type":"code","source":"preds, _ = learn.tta(dl=test_dl)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:54:29.480876Z","iopub.execute_input":"2021-08-04T01:54:29.481249Z","iopub.status.idle":"2021-08-04T01:54:31.130927Z","shell.execute_reply.started":"2021-08-04T01:54:29.481217Z","shell.execute_reply":"2021-08-04T01:54:31.130106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"And now we can submit them:","metadata":{}},{"cell_type":"code","source":"sample_df['label'] = preds.argmax(dim=-1).numpy()","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:54:41.280262Z","iopub.execute_input":"2021-08-04T01:54:41.280724Z","iopub.status.idle":"2021-08-04T01:54:41.289083Z","shell.execute_reply.started":"2021-08-04T01:54:41.280674Z","shell.execute_reply":"2021-08-04T01:54:41.288171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2021-08-04T01:54:43.610856Z","iopub.execute_input":"2021-08-04T01:54:43.611208Z","iopub.status.idle":"2021-08-04T01:54:43.619299Z","shell.execute_reply.started":"2021-08-04T01:54:43.611175Z","shell.execute_reply":"2021-08-04T01:54:43.618433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}