{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Fit FastAI models\n"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(os.listdir(\".\"))","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from fastai import *\nfrom fastai.vision import *\nfrom fastai.vision.data import *\nimport librosa\nimport librosa.display\nimport torch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.cuda.is_available()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bs = 150","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path = Path(\"../input/freesound-audio-tagging-2019\")\nmodel_path = Path(\".\")\ntest_path = path/'test'\ntrain_path = path/'train_curated'\ntrain2_path = path/'train_noisy'\n#sample_submission_csv =path/'sample_submission.csv'\ntest_df = pd.read_csv(path/'sample_submission.csv')\ntrain_df = pd.read_csv(path/'train_curated.csv')\ntrain2_df = pd.read_csv(path/'train_noisy.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = train_df[~train_df.fname.isin(['f76181c4.wav', '77b925c2.wav', '6a1f682a.wav', 'c7db12aa.wav', '7752cc8a.wav'])].reindex()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# lwlrap metric definition"},{"metadata":{"trusted":true},"cell_type":"code","source":"# from official code https://colab.research.google.com/drive/1AgPdhSp7ttY18O3fEoHOQKlt_3HJDLi8#scrollTo=cRCaCIb9oguU\ndef _one_sample_positive_class_precisions(scores, truth):\n    \"\"\"Calculate precisions for each true class for a single sample.\n\n    Args:\n      scores: np.array of (num_classes,) giving the individual classifier scores.\n      truth: np.array of (num_classes,) bools indicating which classes are true.\n\n    Returns:\n      pos_class_indices: np.array of indices of the true classes for this sample.\n      pos_class_precisions: np.array of precisions corresponding to each of those\n        classes.\n    \"\"\"\n    num_classes = scores.shape[0]\n    pos_class_indices = np.flatnonzero(truth > 0)\n    # Only calculate precisions if there are some true classes.\n    if not len(pos_class_indices):\n        return pos_class_indices, np.zeros(0)\n    # Retrieval list of classes for this sample.\n    retrieved_classes = np.argsort(scores)[::-1]\n    # class_rankings[top_scoring_class_index] == 0 etc.\n    class_rankings = np.zeros(num_classes, dtype=np.int)\n    class_rankings[retrieved_classes] = range(num_classes)\n    # Which of these is a true label?\n    retrieved_class_true = np.zeros(num_classes, dtype=np.bool)\n    retrieved_class_true[class_rankings[pos_class_indices]] = True\n    # Num hits for every truncated retrieval list.\n    retrieved_cumulative_hits = np.cumsum(retrieved_class_true)\n    # Precision of retrieval list truncated at each hit, in order of pos_labels.\n    precision_at_hits = (\n            retrieved_cumulative_hits[class_rankings[pos_class_indices]] /\n            (1 + class_rankings[pos_class_indices].astype(np.float)))\n    return pos_class_indices, precision_at_hits\n\n\ndef calculate_per_class_lwlrap(truth, scores):\n    \"\"\"Calculate label-weighted label-ranking average precision.\n\n    Arguments:\n      truth: np.array of (num_samples, num_classes) giving boolean ground-truth\n        of presence of that class in that sample.\n      scores: np.array of (num_samples, num_classes) giving the classifier-under-\n        test's real-valued score for each class for each sample.\n\n    Returns:\n      per_class_lwlrap: np.array of (num_classes,) giving the lwlrap for each\n        class.\n      weight_per_class: np.array of (num_classes,) giving the prior of each\n        class within the truth labels.  Then the overall unbalanced lwlrap is\n        simply np.sum(per_class_lwlrap * weight_per_class)\n    \"\"\"\n    assert truth.shape == scores.shape\n    num_samples, num_classes = scores.shape\n    # Space to store a distinct precision value for each class on each sample.\n    # Only the classes that are true for each sample will be filled in.\n    precisions_for_samples_by_classes = np.zeros((num_samples, num_classes))\n    for sample_num in range(num_samples):\n        pos_class_indices, precision_at_hits = (\n            _one_sample_positive_class_precisions(scores[sample_num, :],\n                                                  truth[sample_num, :]))\n        precisions_for_samples_by_classes[sample_num, pos_class_indices] = (\n            precision_at_hits)\n    labels_per_class = np.sum(truth > 0, axis=0)\n    weight_per_class = labels_per_class / float(np.sum(labels_per_class))\n    # Form average of each column, i.e. all the precisions assigned to labels in\n    # a particular class.\n    per_class_lwlrap = (np.sum(precisions_for_samples_by_classes, axis=0) /\n                        np.maximum(1, labels_per_class))\n    # overall_lwlrap = simple average of all the actual per-class, per-sample precisions\n    #                = np.sum(precisions_for_samples_by_classes) / np.sum(precisions_for_samples_by_classes > 0)\n    #           also = weighted mean of per-class lwlraps, weighted by class label prior across samples\n    #                = np.sum(per_class_lwlrap * weight_per_class)\n    return per_class_lwlrap, weight_per_class\n\n\n# Wrapper for fast.ai library\ndef lwlrap(scores, truth, **kwargs):\n    score, weight = calculate_per_class_lwlrap(to_np(truth), to_np(scores))\n    return torch.Tensor([(score * weight).sum()])\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Functions to read audio and convert to image"},{"metadata":{"trusted":true},"cell_type":"code","source":"def read_audio(conf, pathname, trim_long_data):\n    y, sr = librosa.load(pathname, sr=conf.sampling_rate)\n    # trim silence\n    if 0 < len(y): # workaround: 0 length causes error\n        y, _ = librosa.effects.trim(y) # trim, top_db=default(60)\n    # make it unified length to conf.samples\n    if len(y) > conf.samples: # long enough\n        if trim_long_data:\n            y = y[0:0+conf.samples]\n    else: # pad blank\n        padding = conf.samples - len(y)    # add padding at both ends\n        offset = padding // 2\n        y = np.pad(y, (offset, conf.samples - len(y) - offset), 'constant')\n    return y\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def audio_to_melspectrogram(conf, audio):\n    spectrogram = librosa.feature.melspectrogram(audio, \n                                                 sr=conf.sampling_rate,\n                                                 n_mels=conf.n_mels,\n                                                 hop_length=conf.hop_length,\n                                                 n_fft=conf.n_fft,\n                                                 fmin=conf.fmin,\n                                                 fmax=conf.fmax)\n    spectrogram = librosa.power_to_db(spectrogram)\n    spectrogram = spectrogram.astype(np.float32)\n    return spectrogram\n\ndef show_melspectrogram(conf, mels, title='Log-frequency power spectrogram'):\n    librosa.display.specshow(mels, x_axis='time', y_axis='mel', \n                             sr=conf.sampling_rate, hop_length=conf.hop_length,\n                            fmin=conf.fmin, fmax=conf.fmax)\n    plt.colorbar(format='%+2.0f dB')\n    plt.title(title)\n    plt.show()\n\ndef read_as_melspectrogram(conf, pathname, trim_long_data, debug_display=False):\n    x = read_audio(conf, pathname, trim_long_data)\n    mels = audio_to_melspectrogram(conf, x)\n    if debug_display:\n        IPython.display.display(IPython.display.Audio(x, rate=conf.sampling_rate))\n        show_melspectrogram(conf, mels)\n    return mels\n\n\nclass conf:\n    # Preprocessing settings for using 224 dim images\n    sampling_rate = 44100\n    duration = 4 \n    #hop_length = 347*duration # to make time steps 128   \n    fmin = 20\n    fmax = sampling_rate // 2\n    n_mels = 224\n    n_fft = n_mels * 20\n    samples = int(sampling_rate * duration)\n    hop_length = n_fft//6","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndef mono_to_color(X, mean=None, std=None, norm_max=None, norm_min=None, eps=1e-6):\n    # Stack X as [X,X,X]\n    X = np.stack([X, X, X], axis=-1)\n\n    # Standardize\n    mean = mean or X.mean()\n    std = std or X.std()\n    Xstd = (X - mean) / (std + eps)\n    _min, _max = Xstd.min(), Xstd.max()\n    norm_max = norm_max or _max\n    norm_min = norm_min or _min\n    if (_max - _min) > eps:\n        # Scale to [0, 255]\n        V = Xstd\n        V[V < norm_min] = norm_min\n        V[V > norm_max] = norm_max\n        V = 255 * (V - norm_min) / (norm_max - norm_min)\n        V = V.astype(np.uint8)\n    else:\n        # Just zero\n        V = np.zeros_like(Xstd, dtype=np.uint8)\n    return V\n\ndef convert_wav_to_image(df, source):\n    X = []\n    #for i, row in tqdm_notebook(df.iterrows()):\n    for i in progress_bar(df.index):\n        x = read_as_melspectrogram(conf, source/str(df.loc[i].fname), trim_long_data=False)\n        x_color = mono_to_color(x)\n        X.append(x_color)\n    return X\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nX_train = convert_wav_to_image(train_df, source=train_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#data_df = pd.concat([train_df, test_df], ignore_index=True, sort=False)\ndata_df=train_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# hack to make fastai open the images from memory rather than a file.\n#CUR_X_FILES, CUR_X = list(data_df.fname.values), (X_train + X_test)\nCUR_X_FILES, CUR_X = list(data_df.fname.values), (X_train)\ndef open_fat2019_image(fn, convert_mode, after_open)->Image:\n    # open\n    idx = CUR_X_FILES.index(fn.split('/')[-1])\n    x = PIL.Image.fromarray(CUR_X[idx])\n    #if x.size[0]<= x.size[1]:\n        #print(\"fn=\",fn,\" time dim=\",x.size[0], \" base dim=\",x.size[1])\n    # crop\n    time_dim, base_dim = x.size\n    crop_x = random.randint(0, time_dim - base_dim)\n    x = x.crop([crop_x, 0, crop_x+base_dim, base_dim])    \n    # standardize\n    return Image(pil2tensor(x, np.float32).div_(255))\n\nvision.data.open_image = open_fat2019_image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MixUpCallback(LearnerCallback):\n    \"Callback that creates the mixed-up input and target.\"\n    def __init__(self, learn:Learner, alpha:float=0.4, stack_x:bool=False, stack_y:bool=True):\n        super().__init__(learn)\n        self.alpha,self.stack_x,self.stack_y = alpha,stack_x,stack_y\n    \n    def on_train_begin(self, **kwargs):\n        if self.stack_y: self.learn.loss_func = MixUpLoss(self.learn.loss_func)\n        \n    def on_batch_begin(self, last_input, last_target, train, **kwargs):\n        \"Applies mixup to `last_input` and `last_target` if `train`.\"\n        if not train: return\n        lambd = np.random.beta(self.alpha, self.alpha, last_target.size(0))\n        lambd = np.concatenate([lambd[:,None], 1-lambd[:,None]], 1).max(1)\n        lambd = last_input.new(lambd)\n        shuffle = torch.randperm(last_target.size(0)).to(last_input.device)\n        x1, y1 = last_input[shuffle], last_target[shuffle]\n        if self.stack_x:\n            new_input = [last_input, last_input[shuffle], lambd]\n        else: \n            new_input = (last_input * lambd.view(lambd.size(0),1,1,1) + x1 * (1-lambd).view(lambd.size(0),1,1,1))\n        if self.stack_y:\n            new_target = torch.cat([last_target[:,None].float(), y1[:,None].float(), lambd[:,None].float()], 1)\n        else:\n            if len(last_target.shape) == 2:\n                lambd = lambd.unsqueeze(1).float()\n            new_target = last_target.float() * lambd + y1.float() * (1-lambd)\n        return {'last_input': new_input, 'last_target': new_target}  \n    \n    def on_train_end(self, **kwargs):\n        if self.stack_y: self.learn.loss_func = self.learn.loss_func.get_old()\n        \n\nclass MixUpLoss(nn.Module):\n    \"Adapt the loss function `crit` to go with mixup.\"\n    \n    def __init__(self, crit, reduction='mean'):\n        super().__init__()\n        if hasattr(crit, 'reduction'): \n            self.crit = crit\n            self.old_red = crit.reduction\n            setattr(self.crit, 'reduction', 'none')\n        else: \n            self.crit = partial(crit, reduction='none')\n            self.old_crit = crit\n        self.reduction = reduction\n        \n    def forward(self, output, target):\n        if len(target.size()) == 2:\n            loss1, loss2 = self.crit(output,target[:,0].long()), self.crit(output,target[:,1].long())\n            d = (loss1 * target[:,2] + loss2 * (1-target[:,2])).mean()\n        else:  d = self.crit(output, target)\n        if self.reduction == 'mean': return d.mean()\n        elif self.reduction == 'sum':            return d.sum()\n        return d\n    \n    def get_old(self):\n        if hasattr(self, 'old_crit'):  return self.old_crit\n        elif hasattr(self, 'old_red'): \n            setattr(self.crit, 'reduction', self.old_red)\n            return self.crit\n\ndef mixup(learn:Learner, alpha:float=0.4, stack_x:bool=False, stack_y:bool=True) -> Learner:\n    \"Add mixup https://arxiv.org/abs/1710.09412 to `learn`.\"\n    learn.callback_fns.append(partial(MixUpCallback, alpha=alpha, stack_x=stack_x, stack_y=stack_y))\n    return learn\nLearner.mixup = mixup","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n\ntfms = get_transforms(do_flip=False, max_rotate=0, max_lighting=0.2, max_zoom=0, max_warp=0)\n\n\n#train = ImageList.from_csv(\".\", path/\"train_curated.csv\", folder='train_curated')\ntrain = ImageList.from_df(path=\".\", df=train_df, folder='train_curated')\nsrc = train.split_by_rand_pct(0.2).label_from_df(label_delim=',')\n\n#data = (src.transform(tfms, size=224).add_test(test).databunch(bs=bs)\ndata = (src.transform(tfms, size=224).databunch(bs=bs)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# new code - note that this is fp_16 (for local models) or fp_32(for kaggle models)\nlearn=None\ngc.collect()\ntorch.cuda.empty_cache()\nnp.random.seed(42)\n#learn = cnn_learner(data=data, base_arch=models.resnet18, pretrained=False, metrics=[lwlrap]).to_fp16()\nlearn = cnn_learner(data=data, base_arch=models.resnet34, pretrained=False,metrics=[lwlrap]).mixup(stack_y=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Fitting code (when running on Kaggle Kernel)"},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.freeze()\nlearn.fit_one_cycle(10,max_lr=slice(1e-6,1e-2))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('res34-kaggle-1')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.unfreeze()\nlearn.lr_find()\nlearn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(25,max_lr=slice(5e-4,1e-2))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('res34-kaggle-2')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(30,max_lr=slice(1e-5,1e-2))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('res34-kaggle-3')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train some more with noisy data based on misclassified classes of first model"},{"metadata":{},"cell_type":"markdown","source":"## Identify misclassified classes"},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.load('res34-kaggle-3')\n#learn.to_fp32()\ninterp = ClassificationInterpretation.from_learner(learn)\nlosses,idxs = interp.top_losses()\nsamples=20\nfigsize=(8,8)\n    \n#losses, idxs = self.top_losses(self.data.c)\nl_dim = len(losses.size())\nif l_dim == 1: losses, idxs = interp.top_losses()\ninfolist, ordlosses_idxs, mismatches_idxs, mismatches, losses_mismatches, mismatchescontainer = [],[],[],[],[],[]\ntruthlabels = np.asarray(interp.y_true, dtype=int)\nclasses_ids = [k for k in enumerate(interp.data.classes)]\npredclass = np.asarray(interp.pred_class)\nfor i,pred in enumerate(predclass):\n    where_truth = np.nonzero((truthlabels[i]>0))[0]\n    mismatch = np.all(pred!=where_truth)\n    if mismatch:\n        mismatches_idxs.append(i)\n        if l_dim > 1 : losses_mismatches.append((losses[i][pred], i))\n        else: losses_mismatches.append((losses[i], i))\n    if l_dim > 1: infotup = (i, pred, where_truth, losses[i][pred], np.round(interp.probs[i], decimals=3)[pred], mismatch)\n    else: infotup = (i, pred, where_truth, losses[i], np.round(interp.probs[i], decimals=3)[pred], mismatch)\n    infolist.append(infotup)\nds = interp.data.dl(interp.ds_type).dataset\nmismatches = ds[mismatches_idxs]\nordlosses = sorted(losses_mismatches, key = lambda x: x[0], reverse=True)\nfor w in ordlosses: ordlosses_idxs.append(w[1])\nmismatches_ordered_byloss = ds[ordlosses_idxs]\nprint(f'{str(len(mismatches))} misclassified samples over {str(len(interp.data.valid_ds))} samples in the validation set.')\nsamples = min(samples, len(mismatches))\nfor ima in range(len(mismatches_ordered_byloss)):\n    mismatchescontainer.append(mismatches_ordered_byloss[ima][0])\n    \npoor_classes=[]\np_i=0\nfor sampleN in range(samples):\n    actualclasses = ''\n    for clas in infolist[ordlosses_idxs[sampleN]][2]:\n        actualclasses = f'{actualclasses} -- {str(classes_ids[clas][1])}'\n        poor_classes= poor_classes + [str(classes_ids[clas][1])]\n        \n    \n    poor_classes= poor_classes + [str(classes_ids[infolist[ordlosses_idxs[sampleN]][1]][1])]\n    \n    \n    #imag = mismatches_ordered_byloss[sampleN][0]\n    #imag = show_image(imag, figsize=figsize)\n    #imag.set_title(f\"\"\"Predicted: {classes_ids[infolist[ordlosses_idxs[sampleN]][1]][1]} \\nActual: {actualclasses}\\nLoss: {infolist[ordlosses_idxs[sampleN]][3]}\\nProbability: {infolist[ordlosses_idxs[sampleN]][4]}\"\"\",\n    #                loc='left')\n    plt.show()\n\n    print(f\"\"\"Predicted: {classes_ids[infolist[ordlosses_idxs[sampleN]][1]][1]} Actual: {actualclasses}Loss: {infolist[ordlosses_idxs[sampleN]][3]} Probability: {infolist[ordlosses_idxs[sampleN]][4]}\"\"\")\n\npoor_classes=list(set(poor_classes))\n    \n    \nprint(poor_classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = train2_df.copy()\ndf['singled'] = ~df.labels.str.contains(',')\nsingles_df = df[df.singled]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_addition_df= pd.DataFrame(columns=singles_df.columns)\nfor p in poor_classes:\n    #print(p)\n    #print(singles_df[singles_df.labels == p])\n    sel=(singles_df.labels == p)\n    train_addition_df = pd.concat([train_addition_df, singles_df[sel][:150]])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train2 = convert_wav_to_image(train_addition_df, source=train2_path)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_df = pd.concat([train_df, train_addition_df], ignore_index=True, sort=False)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# hack to make fastai open the images from memory rather than a file.\nCUR_X_FILES, CUR_X = list(data_df.fname.values), (X_train + X_train2)\n\ndef open_fat2019_image(fn, convert_mode, after_open)->Image:\n    # open\n    idx = CUR_X_FILES.index(fn.split('/')[-1])\n    x = PIL.Image.fromarray(CUR_X[idx])\n    #if x.size[0]<= x.size[1]:\n        #print(\"fn=\",fn,\" time dim=\",x.size[0], \" base dim=\",x.size[1])\n    # crop\n    time_dim, base_dim = x.size\n    crop_x = random.randint(0, time_dim - base_dim)\n    x = x.crop([crop_x, 0, crop_x+base_dim, base_dim])    \n    # standardize\n    return Image(pil2tensor(x, np.float32).div_(255))\n\nvision.data.open_image = open_fat2019_image","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Fit the additional data"},{"metadata":{"trusted":true},"cell_type":"code","source":"tfms = get_transforms(do_flip=False, max_rotate=0, max_lighting=0.2, max_zoom=0, max_warp=0)\n\n\n#train = ImageList.from_csv(\".\", path/\"train_curated.csv\", folder='train_curated')\ntrain = ImageList.from_df(path=\".\", df=data_df, folder='train_curated')\nsrc = train.split_by_rand_pct(0.2).label_from_df(label_delim=',')\n\n#data = (src.transform(tfms, size=224).add_test(test).databunch(bs=bs)\ndata = (src.transform(tfms, size=224).databunch(bs=bs)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn=None\ngc.collect()\ntorch.cuda.empty_cache()\nnp.random.seed(42)\n#learn = cnn_learner(data=data, base_arch=models.resnet18, pretrained=False, metrics=[lwlrap]).to_fp16()\nlearn = cnn_learner(data=data, base_arch=models.resnet34, pretrained=False,metrics=[lwlrap]).mixup(stack_y=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.load('res34-kaggle-3')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(25,max_lr=slice(1e-4,1e-2))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('res34-kaggle-4')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(25,max_lr=slice(5e-4,1e-2))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('res34-kaggle-5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(str(learn.metrics))\nlearn.validate()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Prediction code"},{"metadata":{"trusted":true},"cell_type":"code","source":"del X_train, X_train2\n\nX_test = convert_wav_to_image(test_df, source=test_path)\n\ntest = ImageList.from_csv(path, \"sample_submission.csv\", folder='test')\ndata.add_test(test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_test = convert_wav_to_image(test_df, source=test, img_dest=img_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_df = test_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# hack to make fastai open the images from memory rather than a file.\nCUR_X_FILES, CUR_X = list(data_df.fname.values), (X_test)\n\ndef open_fat2019_image(fn, convert_mode, after_open)->Image:\n    # open\n    idx = CUR_X_FILES.index(fn.split('/')[-1])\n    x = PIL.Image.fromarray(CUR_X[idx])\n    #if x.size[0]<= x.size[1]:\n        #print(\"fn=\",fn,\" time dim=\",x.size[0], \" base dim=\",x.size[1])\n    # crop\n    time_dim, base_dim = x.size\n    crop_x = random.randint(0, time_dim - base_dim)\n    x = x.crop([crop_x, 0, crop_x+base_dim, base_dim])    \n    # standardize\n    return Image(pil2tensor(x, np.float32).div_(255))\n\nvision.data.open_image = open_fat2019_image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def _tta_only(learn:Learner, ds_type:DatasetType=DatasetType.Valid, num_pred:int=5) -> Iterator[List[Tensor]]:\n    \"Computes the outputs for several augmented inputs for TTA\"\n    dl = learn.dl(ds_type)\n    ds = dl.dataset\n    old = ds.tfms\n    aug_tfms = [o for o in learn.data.train_ds.tfms]\n    try:\n        pbar = master_bar(range(num_pred))\n        for i in pbar:\n            ds.tfms = aug_tfms\n            yield get_preds(learn.model, dl, pbar=pbar)[0]\n    finally: ds.tfms = old\n\nLearner.tta_only = _tta_only\n\ndef _TTA(learn:Learner, beta:float=0, ds_type:DatasetType=DatasetType.Valid, num_pred:int=5, with_loss:bool=False) -> Tensors:\n    \"Applies TTA to predict on `ds_type` dataset.\"\n    preds,y = learn.get_preds(ds_type)\n    all_preds = list(learn.tta_only(ds_type=ds_type, num_pred=num_pred))\n    avg_preds = torch.stack(all_preds).mean(0)\n    if beta is None: return preds,avg_preds,y\n    else:            \n        final_preds = preds*beta + avg_preds*(1-beta)\n        if with_loss: \n            with NoneReduceOnCPU(learn.loss_func) as lf: loss = lf(final_preds, y)\n            return final_preds, y, loss\n        return final_preds, y\n\nLearner.TTA = _TTA","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nfrom shutil import copyfile\n\n#os.mkdir(\"models\")\n\n#copyfile(\"../input/res18stage4/res18-stage-4.pth\", \"models/res18-stage4.pth\")\n#learn.load('res18-stage4')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#learn.load('res18-kaggle-2')\n#learn.to_fp32()\nlearn.TTA()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds, _ = learn.get_preds(ds_type=DatasetType.Test)\ntest_df[learn.data.classes] = preds\ntest_df.to_csv('submission.csv', index=False)\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}