Jovian
⭐️
Sign In
In [1]:
%reload_ext autoreload
%autoreload 2
%matplotlib inline
In [2]:
from fastai.vision import *
import kaggle
import pandas as pd
import numpy as np
In [3]:
!kaggle competitions download -c dsnetxfastai -p kaggle
404 - Not Found
In [4]:
import pathlib
In [5]:
data_path = pathlib.Path('/home/jupyter/kaggle/')
In [6]:
files = []
for name in data_path.glob('train/**/*.jpg'):
    name_tokens = str(name).split('/')
    files.append((name_tokens[-3], name_tokens[-2], name_tokens[-2] + '/' + name_tokens[-1]))
In [7]:
test_files = []
for name in data_path.glob('test/*.jpg'):
    name_tokens = str(name).split('/')
    test_files.append(name_tokens[-1])

In [8]:
train_df = pd.DataFrame(files, columns=['dataset', 'label', 'image'])
test_df = pd.DataFrame(test_files, columns=['image'])
In [9]:
sample_submissions = pd.read_csv(data_path/'sample_submission.csv')
In [10]:
sample_submissions.head()
Out[10]:

Prepare DataBunch

In [11]:
def prepare_databunch(size=64, bs=128, transforms=get_transforms()):
    np.random.seed(0)
    data_source = (ImageList.from_df(df=train_df, path=data_path/'train', cols='image')
                    .split_by_rand_pct(0.1)
                    .label_from_folder())
    test_data_source = ImageList.from_df(df=sample_submissions, path=data_path/'test', cols='id')
    data = (data_source.transform(transforms, size=size)
                  .databunch(bs=bs)
                  .normalize(imagenet_stats))
    data.add_test(test_data_source)
    return data
In [12]:
data = prepare_databunch()
In [13]:
data
Out[13]:
ImageDataBunch;

Train: LabelList (15055 items)
x: ImageList
Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64)
y: CategoryList
lionel_hutz,lionel_hutz,abraham_grampa_simpson,abraham_grampa_simpson,abraham_grampa_simpson
Path: /home/jupyter/kaggle/train;

Valid: LabelList (1672 items)
x: ImageList
Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64)
y: CategoryList
milhouse_van_houten,krusty_the_clown,bart_simpson,moe_szyslak,moe_szyslak
Path: /home/jupyter/kaggle/train;

Test: LabelList (4206 items)
x: ImageList
Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64),Image (3, 64, 64)
y: EmptyLabelList
,,,,
Path: /home/jupyter/kaggle/train
In [14]:
data.c
Out[14]:
42
In [25]:
data.show_batch()
Notebook Image

Trying reset50

In [15]:
from fastai.metrics import accuracy, error_rate
import torch
In [16]:
learn = cnn_learner(data, models.resnet50, metrics=[accuracy, error_rate]).to_fp16()
In [87]:
learn.lr_find()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
In [88]:
learn.recorder.plot()
Notebook Image
In [89]:
learn.model = torch.nn.DataParallel(learn.model)
In [90]:
learn.fit_one_cycle(10, max_lr=1e-02)
In [91]:
learn.save('resnet50-freezed')
In [111]:
learn.unfreeze()
In [112]:
learn.lr_find()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
In [113]:
learn.recorder.plot()
Notebook Image
In [114]:
learn.fit_one_cycle(3, max_lr=slice(1e-06, 2e-05))
In [118]:
learn.save('resnet50-unfreezed')
In [115]:
learn.freeze()
In [116]:
learn.lr_find()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
In [117]:
learn.recorder.plot()
Notebook Image
In [119]:
learn.fit_one_cycle(5, max_lr=1e-05)

Progressive resize 128

In [122]:
learn.data = prepare_databunch(size=128, bs=256)
In [125]:
learn = learn.to_fp16()
In [126]:
learn.lr_find()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
In [127]:
learn.recorder.plot()
Notebook Image
In [128]:
learn.fit_one_cycle(10, max_lr=5e-03)
In [129]:
learn.save('resnet50-freezed-128')

224

In [17]:
learn.data = prepare_databunch(size=224, bs=256)
learn = learn.to_fp16()
In [131]:
learn.lr_find()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
In [132]:
learn.recorder.plot()
Notebook Image
In [133]:
learn.fit_one_cycle(10, max_lr=2e-04)
In [139]:
learn.save('resnet50-freezed-224')
In [20]:
learn = learn.load('resnet50-freezed-224')
In [30]:
learn = learn.to_fp16()
learn.model = torch.nn.DataParallel(learn.model)
learn.unfreeze()
learn.lr_find()
learn.recorder.plot(start_lr=1e-10)
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [31]:
learn.fit_one_cycle(3, max_lr=slice(2e-06, 4e-05))
In [34]:
learn.save('resnet50-224-unfreezed')
In [36]:
learn = learn.load('resnet50-224-unfreezed')
In [37]:
learn.freeze()
In [38]:
learn.lr_find()
learn.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [39]:
learn.fit_one_cycle(10, max_lr=8e-05)
In [40]:
learn.save('resnet50-224-final')

In [18]:
learn = learn.load('resnet50-224-final')

Trying resnet152

In [19]:
data64 = prepare_databunch(size=64)
In [20]:
learn152 = cnn_learner(data64, models.resnet152, metrics=[accuracy, error_rate]).to_fp16()
In [32]:
learn152.model = torch.nn.DataParallel(learn152.model)
In [33]:
learn152.lr_find()
learn152.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [34]:
learn152.fit_one_cycle(10, max_lr=4e-03)
In [35]:
data128 = prepare_databunch(size=128)
In [38]:
learn152.data = data128
learn152 = learn152.to_fp16()
In [39]:
learn152.lr_find()
learn152.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [40]:
learn152.fit_one_cycle(10, max_lr=1e-03)
In [41]:
learn152.save('resnet152-128-freezed')
In [22]:
data224 = prepare_databunch(size=224)
In [43]:
learn152.data = data224
learn152 = learn152.to_fp16()
In [44]:
learn152.lr_find()
learn152.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [45]:
learn152.fit_one_cycle(10, max_lr=2e-03)
In [46]:
learn152.save('resnet152-224-freezed')
In [22]:
data310 = prepare_databunch(size=310)
In [23]:
learn152.data = data310
learn152 = learn152.to_fp16()
In [49]:
learn152.lr_find()
learn152.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [50]:
learn152.fit_one_cycle(10, max_lr=2e-03)
In [51]:
learn152.save('resnet152-310-freezed')
In [53]:
learn152.unfreeze()
In [54]:
learn152.lr_find()
learn152.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [56]:
learn152.fit_one_cycle(3, max_lr=slice(4e-06, 3e-05))
In [57]:
learn152.freeze()
In [58]:
learn152.save('resnet152-310-unfreezed')
In [65]:
learn152 = learn152.load('resnet152-310-unfreezed')
In [66]:
learn152.lr_find(start_lr=1e-10)
learn152.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [67]:
learn152.fit_one_cycle(5, max_lr=2e-04)
In [68]:
learn152.save('resnet152-final-310')
In [24]:
learn152 = learn152.load('resnet152-final-310')

Trying Transforms

In [61]:
np.random.seed(0)
tmfs = zoom_crop(scale=(0.75,2), do_rand=True)
data_trans = prepare_databunch(size=310, bs=256, transforms=tmfs)
In [62]:
learn_trans = cnn_learner(data_trans, models.resnet152, metrics=[accuracy, error_rate]).to_fp16()
In [63]:
learn_trans.model = torch.nn.DataParallel(learn_trans.model)
In [64]:
learn_trans = learn_trans.load('resnet152-final-310')
In [65]:
learn_trans.lr_find()
learn_trans.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [66]:
learn_trans.fit_one_cycle(10, max_lr=6e-04)
In [68]:
learn_trans.save('resnet152-tran-freezed')
In [73]:
learn_trans = learn_trans.load('resnet152-tran-freezed')
In [74]:
learn_trans.unfreeze()
In [75]:
learn_trans.lr_find(start_lr=1e-10)
learn_trans.recorder.plot()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
Notebook Image
In [76]:
learn_trans.fit_one_cycle(5, max_lr=slice(4e-08, 1e-07))
In [80]:
learn_trans.freeze()
In [81]:
learn_trans.save('resnet152-tran-unfreezed')
In [82]:
learn_trans.lr_find()
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
In [83]:
learn_trans.recorder.plot()
Notebook Image
In [84]:
learn_trans.fit_one_cycle(10, max_lr=6e-04)
In [88]:
learn_trans.save('resnet152-tran-freezed2')

Ensembling

In [85]:
def get_predictions(learner, dataset='test', get_classes=False):
    dataset_map = {
        'train': DatasetType.Train,
        'valid': DatasetType.Valid,
        'test': DatasetType.Test
    }
    dataset = dataset_map[dataset]
    preds = learner.get_preds(dataset)
    class_labels = np.argmax(preds[0], 1)
    if get_classes:
        predictions = [learner.data.classes[i] for i in class_labels]
    else:
        predictions = class_labels
    return predictions, preds[0]

def ensemble_models(learners):
    valid_y = torch.from_numpy(list(learners.values())[0].data.valid_ds.y.items)
    valid_pred_scores = []
    test_pred_scores = []
    for name, learner in learners.items():
        valid_predictions, valid_scores = get_predictions(learner, 'valid')
        print(f'{name} validation accuracy {(valid_predictions == valid_y).float().mean()}')
        test_predictions, test_scores = get_predictions(learner, 'test')
        valid_pred_scores.append(valid_scores)
        test_pred_scores.append(test_scores)
    ensemble_valid_scores = sum(valid_pred_scores)/len(valid_pred_scores)
    ensemble_test_scores = sum(test_pred_scores)/len(test_pred_scores)
    ensemble_valid_predictions = np.argmax(ensemble_valid_scores, 1)
    ensemble_test_predictions = np.argmax(ensemble_test_scores, 1)
    print(f'ensemble valid accuracy {(ensemble_valid_predictions == valid_y).float().mean()}')
    return ensemble_test_predictions
In [86]:
learners = {
    'resnet50': learn,
    'resnet152': learn152,
    'resnet152_trans': learn_trans
}
In [87]:
test_predictions = ensemble_models(learners)
ensemble valid accuracy 0.9868420958518982
In [133]:
test_predictions_classes = [learn.data.classes[x] for x in test_predictions]
In [134]:
sample_submissions['predicted_class'] = test_predictions_classes
In [138]:
sample_submissions.to_csv('r152_r50_ensemble_transforms3.csv', index=False)
In [140]:
# !kaggle competitions submit -c dsnetxfastai -f r152_r50_ensemble_transforms2.csv -m "reset152 ensemble with transforms2 "