{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Model Using Extracted Histogram features","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"This kernel uses features generated from the pixel histograms. I preprocessed the features for the train set here: https://www.kaggle.com/jameschapman19/histogram-features.\n\nSince in test submission we need to generate all features 'on-the-fly', all of the relevant code to generate these features is reproduced in this kernel too.","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import cv2\nimport copy\nfrom pathlib import Path\nfrom skimage.segmentation import clear_border\nfrom skimage.morphology import ball, disk, dilation, binary_erosion, remove_small_objects, erosion, closing, reconstruction, binary_closing\nfrom skimage.measure import label, regionprops\nfrom skimage.segmentation import clear_border\nfrom skimage.filters import roberts, sobel\nfrom scipy import ndimage as ndi\nfrom skimage import measure, morphology\nfrom scipy.stats import kurtosis\nimport seaborn as sns\nimport scipy\nimport os\nfrom tqdm import tqdm\nfrom skimage import measure, morphology\nfrom tqdm.notebook import tqdm\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport torch\nimport torch.nn as nn\nfrom torch import optim\nimport random\nfrom torchvision import models\nimport torch.multiprocessing as mp\nfrom torch.nn import functional as F\nimport matplotlib.pyplot as plt\nplt.style.use('ggplot')\nimport pydicom.pixel_data_handlers.gdcm_handler as gdcm_handler \nimport pydicom\nfrom torch.utils.data import DataLoader, Dataset\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def seed_all(seed=42):\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    \nseed_all()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def calc_metric_loss(pred_fvc,sigma,true_fvc):\n    true_fvc=np.reshape(true_fvc,pred_fvc.shape)\n    sigma[sigma<70]=70\n    delta=np.abs(pred_fvc-true_fvc)\n    delta[delta>1000]=1000\n    metric=-(np.sqrt(2)*delta/sigma)-np.log(np.sqrt(2)*sigma)\n    return -metric","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Model\nTried to align the model here with the main public kernels for comparison purposes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class main_model(nn.Module):\n    def __init__(self, n_additional_features, n_outputs):\n        super(main_model, self).__init__()\n        self.fc1 = nn.Linear(n_additional_features, 100)\n        self.fc2 = nn.Linear(100, 100)\n        self.fc3 = nn.Linear(100, n_outputs)\n\n    def forward(self, additional_features):\n        out=additional_features\n        out = F.relu(self.fc1(out))\n        out = F.relu(self.fc2(out))\n        out = self.fc3(out)\n        return out\n    \n    def metric_loss(self,pred_fvc,true_fvc):\n        #Implementation of the metric in pytorch\n        sigma = pred_fvc[:, 2] - pred_fvc[:, 0]\n        true_fvc=torch.reshape(true_fvc,pred_fvc[:,1].shape)\n        sigma_clipped=torch.clamp(sigma,min=70)\n        delta=torch.clamp(torch.abs(pred_fvc[:,1]-true_fvc),max=1000)\n        metric=torch.div(-torch.sqrt(torch.tensor([2.0]).to(device))*delta,sigma_clipped)-torch.log(torch.sqrt(torch.tensor([2.0]).to(device))*sigma_clipped)\n        return -metric\n    \n    def fvc_loss(self,pred_fvc,true_fvc):\n        #Absolute loss in FVC values\n        true_fvc=torch.reshape(true_fvc,pred_fvc[:,1].shape)\n        fvc_err=torch.abs(pred_fvc-true_fvc)\n        return fvc_err\n    \n    def quantile_loss(self,preds, target, quantiles):\n        #The 'quantile' loss\n        assert not target.requires_grad\n        assert preds.size(0) == target.size(0)\n        losses = []\n        for i, q in enumerate(quantiles):\n            errors = target - preds[:, i]\n            losses.append(torch.max((q - 1) * errors, q * errors).unsqueeze(1))\n\n        loss = torch.mean(torch.sum(torch.cat(losses, dim=1), dim=1))\n        return loss","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Image processing steps (for test data)","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"All credit to https://www.kaggle.com/gzuidhof/full-preprocessing-tutorial and https://www.kaggle.com/arnavkj95/candidate-generation-and-luna16-preprocessing\n\n### Loading Scans and use the first couple of slice locations to estimate thickness for the whole scan\n\n### Convert pixels to hounsfield units\n\n### Resample the images so that all scans have the same size (i.e. higher resolution images downsampled)\n\n### Segment the lungs\n\n### Generate histograms and statistics","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load the scans in given folder path\ndef load_scan(path):\n\n    #slices = [pydicom.read_file(path / s) for s in os.listdir(path)]\n    slices = [pydicom.read_file(path / s) for s in os.listdir(path)]\n    slices.sort(key = lambda x: float(x.ImagePositionPatient[2]))\n    try:\n        slice_thickness = np.abs(slices[0].ImagePositionPatient[2] - slices[1].ImagePositionPatient[2])\n    except:\n        slice_thickness = np.abs(slices[0].SliceLocation - slices[1].SliceLocation)\n    if slice_thickness==0:\n        slice_thickness=slices[0].SliceThickness\n    for s in slices:\n        s.SliceThickness = slice_thickness\n        \n    return slices\n\ndef get_pixels_hu(slices):\n    image = np.stack([np.array(s.pixel_array,dtype=np.int16) for s in slices])\n    # Convert to int16 (from sometimes int16), \n    # should be possible as values should always be low enough (<32k)\n    image = image.astype(np.int16)\n\n    # Set outside-of-scan pixels to 0\n    # The intercept is usually -1024, so air is approximately 0\n    image[image == -2000] = 0\n    \n    # Convert to Hounsfield units (HU)\n    for slice_number in range(len(slices)):\n        \n        intercept = slices[slice_number].RescaleIntercept\n        slope = slices[slice_number].RescaleSlope\n        \n        if slope != 1:\n            image[slice_number] = slope * image[slice_number].astype(np.float64)\n            image[slice_number] = image[slice_number].astype(np.int16)\n            \n        image[slice_number] += np.int16(intercept)\n    \n    return np.array(image, dtype=np.int16)\n\ndef resample(image, scan, new_spacing=[1,1,1]):\n    # Determine current pixel spacing\n    #spacing = np.array([scan[0].SliceThickness] + scan[0].PixelSpacing, dtype=np.float32)\n    spacing = np.array([scan[0].SliceThickness] + list(scan[0].PixelSpacing), dtype=np.float32)\n    resize_factor = spacing / new_spacing\n    new_real_shape = image.shape * resize_factor\n    new_shape = np.round(new_real_shape)\n    real_resize_factor = new_shape / image.shape\n    new_spacing = spacing / real_resize_factor\n    \n    image = scipy.ndimage.interpolation.zoom(image, real_resize_factor, mode='nearest')\n    return image, new_spacing\n\ndef get_segmented_lungs(im, plot=False):\n    \n    '''\n    This funtion segments the lungs from the given 2D slice.\n    '''\n    if plot == True:\n        f, plots = plt.subplots(8, 1, figsize=(5, 40))\n    '''\n    Step 1: Convert into a binary image. \n    '''\n    binary = im < -200\n    if plot == True:\n        plots[0].axis('off')\n        plots[0].imshow(binary, cmap=plt.cm.bone) \n    '''\n    Step 2: Remove the blobs connected to the border of the image.\n    '''\n    cleared = clear_border(binary)\n    if plot == True:\n        plots[1].axis('off')\n        plots[1].imshow(cleared, cmap=plt.cm.bone) \n    '''\n    Step 3: Label the image.\n    '''\n    label_image = label(cleared)\n    if plot == True:\n        plots[2].axis('off')\n        plots[2].imshow(label_image, cmap=plt.cm.bone) \n    '''\n    Step 4: Keep the labels with 2 largest areas.\n    '''\n    areas = [r.area for r in regionprops(label_image)]\n    areas.sort()\n    if len(areas) > 2:\n        for region in regionprops(label_image):\n            if region.area < areas[-2]:\n                for coordinates in region.coords:                \n                       label_image[coordinates[0], coordinates[1]] = 0\n    binary = label_image > 0\n    if plot == True:\n        plots[3].axis('off')\n        plots[3].imshow(binary, cmap=plt.cm.bone) \n    '''\n    Step 5: Erosion operation with a disk of radius 2. This operation is \n    seperate the lung nodules attached to the blood vessels.\n    '''\n    selem = disk(2)\n    binary = binary_erosion(binary, selem)\n    if plot == True:\n        plots[4].axis('off')\n        plots[4].imshow(binary, cmap=plt.cm.bone) \n    '''\n    Step 6: Closure operation with a disk of radius 10. This operation is \n    to keep nodules attached to the lung wall.\n    '''\n    selem = disk(10)\n    binary = binary_closing(binary, selem)\n    if plot == True:\n        plots[5].axis('off')\n        plots[5].imshow(binary, cmap=plt.cm.bone) \n    '''\n    Step 7: Fill in the small holes inside the binary mask of lungs.\n    '''\n    edges = roberts(binary)\n    binary = ndi.binary_fill_holes(edges)\n    if plot == True:\n        plots[6].axis('off')\n        plots[6].imshow(binary, cmap=plt.cm.bone) \n    '''\n    Step 8: Superimpose the binary mask on the input image.\n    '''\n    get_high_vals = binary == 0\n    im[get_high_vals] = 0\n    if plot == True:\n        plots[7].axis('off')\n        plots[7].imshow(im, cmap=plt.cm.bone) \n        \n    return im\n\ndef get_kurtosis_stats(ids,ctscans_dir):\n    kurt=[]\n    std=[]\n    mean=[]\n    median=[]\n    for i in ids:\n        print(i)\n        #try:\n        patient_path= ctscans_dir / i\n        scan = load_scan(patient_path)\n        image=get_pixels_hu(scan)\n        image, new_spacing = resample(image, scan, new_spacing=[2,2,2])\n        image=np.asarray([get_segmented_lungs(slice) for slice in image])\n        kurt_i=kurtosis(image.ravel()[image.ravel() < -200])\n        std_i=image.ravel()[image.ravel() < -200].std()\n        mean_i=image.ravel()[image.ravel() < -200].mean()\n        median_i=np.median(image.ravel()[image.ravel() < -200])\n        print('Kurtosis: ', kurt_i)\n        print('Standard Deviation: ', std_i)\n        kurt.append(kurt_i)\n        std.append(std_i)\n        mean.append(mean_i)\n        median.append(median_i)\n        ax=sns.kdeplot(image.ravel()[(image.ravel() < 0)&(image.ravel() > -1200)], bw=0.5)\n        ax.set(xlabel='HU', ylabel='% voxels',title='Histogram of voxel characteristics')\n        plt.show()\n        plt.imshow(image[round(image.shape[0]/2),:,:])\n        plt.show()\n        #except:\n            #print('error')\n            #kurt.append(np.nan)\n            #std.append(np.nan)\n            #mean.append(np.nan)\n            #median.append(np.nan)\n    return kurt,std,mean,median","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Helper Function to plot training losses","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_training_loss(train, val,title='loss'):\n    plt.figure()\n    plt.plot(train, label='Train')\n    plt.plot(val, label='Val')\n    if title=='loss':\n        plt.title('Model Training Loss')\n    else:\n        plt.title('Model Metric Loss')\n    plt.xlabel('Epoch')\n    plt.ylabel('Loss')\n    plt.yscale('log')\n    plt.legend()\n    plt.savefig('training_loss')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Load and preprocess Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train=pd.read_csv('../input/osic-pulmonary-fibrosis-progression/train.csv')\ntest=pd.read_csv('../input/osic-pulmonary-fibrosis-progression/test.csv')\nsubmission=pd.read_csv('../input/osic-pulmonary-fibrosis-progression/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Prepare Training Data (Tabular)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train['base_Weeks']=train.groupby(['Patient'])['Weeks'].transform('min')\nbase=train[train.Weeks==train.base_Weeks]\nbase = base.rename(columns={'FVC': 'base_FVC','Percent': 'base_Percent'})\nbase.drop_duplicates(subset=['Patient', 'Weeks'], keep='first',inplace=True)\ntrain=train.merge(base[['Patient','base_FVC','base_Percent']],on='Patient',how='left')\ntrain['Week_passed'] = train['Weeks'] - train['base_Weeks']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Prepare Test Data (tabular)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"test = test.rename(columns={'Weeks': 'base_Weeks', 'FVC': 'base_FVC','Percent': 'base_Percent'})\n\n# Adding Sample Submission\nsubmission = pd.read_csv(\"../input/osic-pulmonary-fibrosis-progression/sample_submission.csv\")\n\n# In submisison file, format: ID_'week', using lambda to split the ID\nsubmission['Patient'] = submission['Patient_Week'].apply(lambda x:x.split('_')[0])\n\n# In submisison file, format: ID_'week', using lambda to split the Week\nsubmission['Weeks'] = submission['Patient_Week'].apply(lambda x:x.split('_')[1]).astype(int)\n\ntest = submission.drop(columns = [\"FVC\", \"Confidence\"]).merge(test, on = 'Patient')\n\ntest['Week_passed'] = test['Weeks'] - test['base_Weeks']\n\ntest=test[train.columns.drop(['FVC','Percent'])]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### OH Encode Sex and Smoking\nWith thanks to https://www.kaggle.com/ulrich07/osic-keras-starter-with-custom-metrics","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"COLS = ['Sex','SmokingStatus']\nfor col in COLS:\n    for mod in train[col].unique():\n        train[mod] = (train[col] == mod).astype(int)\n        \n        test[mod] = (test[col] == mod).astype(int)\n    train.drop(col,axis=1,inplace=True)\n    test.drop(col,axis=1,inplace=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Rescale based on train data","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"### Add in the preprocessed histogram features","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"pixel_stats=pd.read_csv('../input/osic-histogram-features/train_pixel_stats.csv')\ntrain=train.merge(pixel_stats[['Patient','kurtosis','std','mean','median']],how='left',on='Patient')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"@alexj21 pointed out I hadn't rescaled the histogram features. A bit ugly but I've done it here and inside the Dataset for the test. ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn import preprocessing\nrobust_scaler = preprocessing.RobustScaler()\ntrain[train.columns.difference(['Patient','FVC','Percent','Weeks','base_Weeks'])]=robust_scaler.fit_transform(train[train.columns.difference(['Patient','FVC','Percent','Weeks','base_Weeks'])])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Create the dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class OSIC(Dataset):\n    def __init__(self,patient_ids,df,train=True):\n        root_dir = Path('/kaggle/input/osic-pulmonary-fibrosis-progression')\n        self.df=df[df.Patient.isin(patient_ids)]\n        if not train:\n            ct_scans_dir=root_dir/'test'\n            pixel_stats=self.df.copy()\n            k,s,m,me=get_kurtosis_stats(patient_ids,ct_scans_dir)\n            pixel_stats=pixel_stats.drop_duplicates(subset=['Patient'])\n            pixel_stats['kurtosis']=np.array(k)\n            pixel_stats['std']=np.array(s)\n            pixel_stats['mean']=np.array(m)\n            pixel_stats['median']=np.array(me)\n            self.df=self.df.merge(pixel_stats[['Patient','kurtosis','std','mean','median']],how='left',on='Patient')\n            self.df[self.df.columns.difference(['Patient','FVC','Percent','Weeks','base_Weeks'])]=robust_scaler.transform(self.df[self.df.columns.difference(['Patient','FVC','Percent','Weeks','base_Weeks'])])\n        else:\n            ctscans_dir=root_dir/'train'\n        self.data=self.df[self.df.columns.difference(['FVC','Patient','Percent'])].values\n        col_mean = np.nanmean(self.data, axis=0)\n        inds = np.where(np.isnan(self.data))\n        self.data[inds] = np.take(col_mean, inds[1])\n        self.patients=self.df['Patient'].values\n        self.train=train\n        if self.train:\n            self.fvc=self.df['FVC'].values\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        if self.train:\n            data = {'fvc': self.fvc[idx],\n                   'data': self.data[idx]}\n        else:\n            \n            data = {'data': self.data[idx]}\n        return data","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Set some training parameters","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs=300\nbatch_size=64\nnum_workers=3\nquantiles = (0.2, 0.5, 0.8)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Split training data into train and val by patient (80:20)\n'ID00011637202177653955184' has no images we can load. Therefore I'm going to drop.\n\nWe shuffle the train data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ids=train.Patient.unique()\nindex = np.argwhere(ids=='ID00011637202177653955184')\nids = list(np.delete(ids, index))\nrandom.shuffle(ids)\nids=np.array(ids)\n\ntrain_ids,val_ids=np.split(ids, [int(round(0.9 * len(ids), 0))])\n\ntrain_dataset = OSIC(train_ids,train)  \ntrain_dataloader = DataLoader(train_dataset, batch_size=batch_size,shuffle=True,num_workers=num_workers)\n\nval_dataset = OSIC(val_ids,train)  \nval_dataloader = DataLoader(val_dataset, batch_size=batch_size,shuffle=True,num_workers=num_workers)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = main_model(train_dataset.data.shape[1], 3).to(device)\nprint('Number of parameters:')\nprint(sum(p.numel() for p in model.parameters() if p.requires_grad))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = optim.Adam(model.parameters())\nepoch_train_metric=[]\nepoch_val_metric=[]\nepoch_train_loss=[]\nepoch_val_loss=[]\nepoch=0\nmin_val_loss = 1e+100\nearly_stop = False\npatience=10\n#Start by training for fvc\nwhile epoch<epochs and not early_stop:\n    epoch+=1\n    train_loss=0\n    train_metric=0\n    model.train()\n    for batch_idx, data in enumerate(train_dataloader):\n        optimizer.zero_grad()\n        model_output = model(data['data'].float().to(device))\n        quantile_loss = model.quantile_loss(model_output, data['fvc'].to(device), quantiles)\n        metric_loss = model.metric_loss(model_output,data['fvc'].to(device)).mean()\n        loss=quantile_loss\n        loss.backward()\n        train_loss += loss.item()\n        train_metric += metric_loss.item()\n        optimizer.step()\n    print('====> Epoch: {} Average train quantile loss: {:.4f}'.format(\n                        epoch, train_loss / len(train_dataloader)))\n    print('====> Epoch: {} Average train metric: {:.4f}'.format(\n                        epoch, train_metric / len(train_dataloader)))\n    \n    val_loss=0\n    val_metric=0\n    model.eval()\n    with torch.no_grad():\n        for batch_idx, data in enumerate(val_dataloader):\n            model_output = model(data['data'].float().to(device))\n            quantile_loss = model.quantile_loss(model_output, data['fvc'].to(device), quantiles)\n            metric_loss = model.metric_loss(model_output,data['fvc'].to(device)).mean()\n            loss=quantile_loss\n            val_loss += loss.item()\n            val_metric += metric_loss.item()\n        print('====> Epoch: {} Average val quantile loss: {:.4f}'.format(\n                        epoch, val_loss / len(val_dataloader)))\n        print('====> Epoch: {} Average val metric: {:.4f}'.format(\n                        epoch, val_metric / len(val_dataloader)))\n    \n    epoch_train_loss.append(train_loss/ len(train_dataloader))\n    epoch_val_loss.append(val_loss / len(val_dataloader))\n    epoch_train_metric.append(train_metric/ len(train_dataloader))\n    epoch_val_metric.append(val_metric / len(val_dataloader))\n    \n    if val_loss < min_val_loss:\n        min_val_loss = val_loss\n        best_model = copy.deepcopy(model.state_dict())\n        print('Min loss %0.2f' % min_val_loss)\n        epochs_no_improve = 0\n\n    else:\n        epochs_no_improve += 1\n        # Check early stopping condition\n        if epochs_no_improve == patience:\n            print('Early stopping!')\n            early_stop = True\n            model.load_state_dict(best_model)\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Plot training curves","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_training_loss(epoch_train_loss, epoch_val_loss)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"possibly a learning rate problem/something to do with the different scaling of percent and fvc","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_training_loss(epoch_train_metric, epoch_val_metric,title='metric')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Test Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"submission=pd.read_csv('../input/osic-pulmonary-fibrosis-progression/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_ids=test.Patient.unique()\ntest_dataset = OSIC(test_ids,test,train=False)  \ntest_dataloader = DataLoader(test_dataset, batch_size=batch_size,shuffle=False,num_workers=num_workers)\nmodel.eval()\nfvc_pred = []\nsigma_pred = []\nwith torch.no_grad():\n    for batch_idx, data in enumerate(test_dataloader):\n        model_output = model(data['data'].float().to(device))\n        fvc_pred.append(model_output[:,1])\n        sigma_pred.append(model_output[:,2]-model_output[:,0])\nfvc_pred=torch.cat(fvc_pred, dim=0)\nsigma_pred=torch.cat(sigma_pred, dim=0)\ntest['FVC']=fvc_pred.cpu().numpy()\ntest['Confidence']=sigma_pred.cpu().numpy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test['Patient_Week']=test[\"Patient\"] + '_' + test['Weeks'].apply(str)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission=submission[['Patient_Week']].merge(test[['Patient_Week','FVC','Confidence']],on='Patient_Week')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv', index=False, float_format='%.1f')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Post-Match Analysis","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Test Predictions","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.scatter(submission['FVC'],submission['Confidence'])\nplt.title('Test')\nplt.xlabel('FVC')\nplt.ylabel('Confidence')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"fvc_pred = []\nsigma_pred = []\ntrain_dataloader = DataLoader(train_dataset, batch_size=batch_size,shuffle=False,num_workers=num_workers)\nwith torch.no_grad():\n    for batch_idx, data in enumerate(train_dataloader):\n        model_output = model(data['data'].float().to(device))\n        fvc_pred.append(model_output[:,1])\n        sigma_pred.append(model_output[:,2]-model_output[:,0])\nfvc_pred_train=torch.cat(fvc_pred, dim=0)\nsigma_pred_train=torch.cat(sigma_pred, dim=0)\n\nprint('train metric', calc_metric_loss(fvc_pred_train.cpu().numpy(),sigma_pred_train.cpu().numpy(),train_dataset.fvc).mean())\n\nplt.scatter(fvc_pred_train.cpu().numpy(),sigma_pred_train.cpu().numpy())\nplt.title('Train')\nplt.xlabel('FVC')\nplt.ylabel('Confidence')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Val","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"fvc_pred = []\nsigma_pred = []\nval_dataloader = DataLoader(val_dataset, batch_size=batch_size,shuffle=False,num_workers=num_workers)\nwith torch.no_grad():\n    for batch_idx, data in enumerate(val_dataloader):\n        model_output = model(data['data'].float().to(device))\n        fvc_pred.append(model_output[:,1])\n        sigma_pred.append(model_output[:,2]-model_output[:,0])\nfvc_pred_val=torch.cat(fvc_pred, dim=0)\nsigma_pred_val=torch.cat(sigma_pred, dim=0)\n\nprint('val metric', calc_metric_loss(fvc_pred_val.cpu().numpy(),sigma_pred_val.cpu().numpy(),val_dataset.fvc).mean())\n\nplt.scatter(fvc_pred_val.cpu().numpy(),sigma_pred_val.cpu().numpy())\nplt.title('Val')\nplt.xlabel('FVC')\nplt.ylabel('Confidence')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## All","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.hist(submission['FVC'], alpha=0.5,label='test')\nplt.hist(fvc_pred_train.cpu().numpy(), alpha=0.5,label='train')\nplt.hist(fvc_pred_val.cpu().numpy(), alpha=0.5,label='val')\nplt.legend()\nplt.title('Histogram of FVC predictions')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.hist(submission['Confidence'], alpha=0.5,label='test')\nplt.hist(sigma_pred_train.cpu().numpy(), alpha=0.5,label='train')\nplt.hist(sigma_pred_val.cpu().numpy(), alpha=0.5,label='val')\nplt.legend()\nplt.title('Histogram of Confidence predictions')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}