Commit 4e913ea3 authored by Billy Amélie's avatar Billy Amélie
Browse files

competition score + transfer learning modification + model retraining

parent 3f0a09d4
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# CNN superposition + MLP"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"https://www.pyimagesearch.com/2019/02/04/keras-multiple-inputs-and-mixed-data/"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import os\n",
"import logging\n",
"logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A - Preprocessing : Reading Data"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"os.chdir('../')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Patient</th>\n",
" <th>Weeks</th>\n",
" <th>FVC</th>\n",
" <th>Percent</th>\n",
" <th>Age</th>\n",
" <th>Sex</th>\n",
" <th>SmokingStatus</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>ID00007637202177411956430</td>\n",
" <td>-4</td>\n",
" <td>2315</td>\n",
" <td>58.253649</td>\n",
" <td>79</td>\n",
" <td>Male</td>\n",
" <td>Ex-smoker</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>ID00007637202177411956430</td>\n",
" <td>5</td>\n",
" <td>2214</td>\n",
" <td>55.712129</td>\n",
" <td>79</td>\n",
" <td>Male</td>\n",
" <td>Ex-smoker</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>ID00007637202177411956430</td>\n",
" <td>7</td>\n",
" <td>2061</td>\n",
" <td>51.862104</td>\n",
" <td>79</td>\n",
" <td>Male</td>\n",
" <td>Ex-smoker</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>ID00007637202177411956430</td>\n",
" <td>9</td>\n",
" <td>2144</td>\n",
" <td>53.950679</td>\n",
" <td>79</td>\n",
" <td>Male</td>\n",
" <td>Ex-smoker</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>ID00007637202177411956430</td>\n",
" <td>11</td>\n",
" <td>2069</td>\n",
" <td>52.063412</td>\n",
" <td>79</td>\n",
" <td>Male</td>\n",
" <td>Ex-smoker</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Patient Weeks FVC Percent Age Sex SmokingStatus\n",
"0 ID00007637202177411956430 -4 2315 58.253649 79 Male Ex-smoker\n",
"1 ID00007637202177411956430 5 2214 55.712129 79 Male Ex-smoker\n",
"2 ID00007637202177411956430 7 2061 51.862104 79 Male Ex-smoker\n",
"3 ID00007637202177411956430 9 2144 53.950679 79 Male Ex-smoker\n",
"4 ID00007637202177411956430 11 2069 52.063412 79 Male Ex-smoker"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from preprocessing.read_load_data import read_data\n",
"\n",
"input_directory='../osic-pulmonary-fibrosis-progression'\n",
"train_df, test_df, sample_df = read_data(input_directory) \n",
"train_df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## B - Preprocessing : Loading Data"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"patients_train_ids= train_df.Patient.unique()\n",
"patient_test_list= test_df.Patient.unique()\n",
"patients_train_ids = [pat for pat in patients_train_ids]"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO:loading attributes...\n",
"INFO:loading images...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Array shape: (176, 240, 240, 4)\n",
"min value: -0.1251496147096971\n",
"max value: 0.16921848376183674\n"
]
}
],
"source": [
"from preprocessing.read_load_data import load_images\n",
"\n",
"logging.info(\"loading attributes...\")\n",
"df = pd.read_csv(f'{input_directory}/train.csv')\n",
"df = df.drop_duplicates(subset = 'Patient', keep='first')\n",
"patients_train_ids= df.Patient.unique().tolist()\n",
"df = df[df['Patient'].isin(patients_train_ids)]\n",
"\n",
"logging.info(\"loading images...\")\n",
"images = load_images(input_directory,\n",
" 'train',\n",
" patients_train_ids,\n",
" option='superposition',\n",
" outputH = 240,\n",
" outputW = 240)\n",
"\n",
"print(\"Array shape: \", images.shape)\n",
"#check value between -1,1\n",
"print('min value: ', np.amin(images))\n",
"print('max value: ', np.amax(images))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## C - Preprocessing : shuffle"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"split = train_test_split(df, images, test_size=0.2, random_state=42)\n",
"(trainAttrX, testAttrX, trainImagesX, testImagesX) = split"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## D - Preprocessing : Scaling + Encoding"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"from preprocessing.scale_data import scale_variable\n",
"\n",
"sc, trainAttrX, testAttrX = scale_variable(trainAttrX, testAttrX,'FVC')\n",
"trainY = trainAttrX.loc[:,'FVC_scaled']\n",
"testY = testAttrX.loc[:,'FVC_scaled']"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"from preprocessing.scale_data import encode_variable\n",
"\n",
"trainAttrX, testAttrX = encode_variable(trainAttrX, testAttrX,'Sex')\n",
"trainAttrX, testAttrX = encode_variable(trainAttrX, testAttrX,'SmokingStatus')\n",
"\n",
"trainAttrX.drop(columns = ['Sex','SmokingStatus','FVC','FVC_scaled','Patient'], inplace = True)\n",
"testAttrX.drop(columns = ['Sex','SmokingStatus','FVC','FVC_scaled','Patient'], inplace = True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## E - Processing : Create models"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"from processing.models import create_hybrid2"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"from processing.models import create_hybrid2\n",
"from keras.optimizers import Adam\n",
"\n",
"model = create_hybrid2(trainAttrX.shape[1], shape = (240,240,4))\n",
"opt = Adam(lr=1e-3, decay=1e-3 / 200)\n",
"model.compile(loss=\"mean_absolute_percentage_error\", optimizer=opt)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model_1\"\n",
"__________________________________________________________________________________________________\n",
"Layer (type) Output Shape Param # Connected to \n",
"==================================================================================================\n",
"input_1 (InputLayer) [(None, 240, 240, 4) 0 \n",
"__________________________________________________________________________________________________\n",
"conv2d (Conv2D) (None, 240, 240, 32) 1184 input_1[0][0] \n",
"__________________________________________________________________________________________________\n",
"activation (Activation) (None, 240, 240, 32) 0 conv2d[0][0] \n",
"__________________________________________________________________________________________________\n",
"batch_normalization (BatchNorma (None, 240, 240, 32) 128 activation[0][0] \n",
"__________________________________________________________________________________________________\n",
"max_pooling2d (MaxPooling2D) (None, 120, 120, 32) 0 batch_normalization[0][0] \n",
"__________________________________________________________________________________________________\n",
"conv2d_1 (Conv2D) (None, 120, 120, 64) 18496 max_pooling2d[0][0] \n",
"__________________________________________________________________________________________________\n",
"activation_1 (Activation) (None, 120, 120, 64) 0 conv2d_1[0][0] \n",
"__________________________________________________________________________________________________\n",
"batch_normalization_1 (BatchNor (None, 120, 120, 64) 256 activation_1[0][0] \n",
"__________________________________________________________________________________________________\n",
"max_pooling2d_1 (MaxPooling2D) (None, 60, 60, 64) 0 batch_normalization_1[0][0] \n",
"__________________________________________________________________________________________________\n",
"conv2d_2 (Conv2D) (None, 60, 60, 128) 73856 max_pooling2d_1[0][0] \n",
"__________________________________________________________________________________________________\n",
"activation_2 (Activation) (None, 60, 60, 128) 0 conv2d_2[0][0] \n",
"__________________________________________________________________________________________________\n",
"batch_normalization_2 (BatchNor (None, 60, 60, 128) 512 activation_2[0][0] \n",
"__________________________________________________________________________________________________\n",
"max_pooling2d_2 (MaxPooling2D) (None, 30, 30, 128) 0 batch_normalization_2[0][0] \n",
"__________________________________________________________________________________________________\n",
"flatten (Flatten) (None, 115200) 0 max_pooling2d_2[0][0] \n",
"__________________________________________________________________________________________________\n",
"dense_3 (Dense) (None, 16) 1843216 flatten[0][0] \n",
"__________________________________________________________________________________________________\n",
"gaussian_noise_input (InputLaye [(None, 5)] 0 \n",
"__________________________________________________________________________________________________\n",
"activation_3 (Activation) (None, 16) 0 dense_3[0][0] \n",
"__________________________________________________________________________________________________\n",
"gaussian_noise (GaussianNoise) (None, 5) 0 gaussian_noise_input[0][0] \n",
"__________________________________________________________________________________________________\n",
"batch_normalization_3 (BatchNor (None, 16) 64 activation_3[0][0] \n",
"__________________________________________________________________________________________________\n",
"dense (Dense) (None, 8) 48 gaussian_noise[0][0] \n",
"__________________________________________________________________________________________________\n",
"dropout (Dropout) (None, 16) 0 batch_normalization_3[0][0] \n",
"__________________________________________________________________________________________________\n",
"dense_1 (Dense) (None, 4) 36 dense[0][0] \n",
"__________________________________________________________________________________________________\n",
"dense_4 (Dense) (None, 4) 68 dropout[0][0] \n",
"__________________________________________________________________________________________________\n",
"dense_2 (Dense) (None, 1) 5 dense_1[0][0] \n",
"__________________________________________________________________________________________________\n",
"activation_4 (Activation) (None, 4) 0 dense_4[0][0] \n",
"__________________________________________________________________________________________________\n",
"concatenate (Concatenate) (None, 5) 0 dense_2[0][0] \n",
" activation_4[0][0] \n",
"__________________________________________________________________________________________________\n",
"dense_5 (Dense) (None, 4) 24 concatenate[0][0] \n",
"__________________________________________________________________________________________________\n",
"dense_6 (Dense) (None, 1) 5 dense_5[0][0] \n",
"==================================================================================================\n",
"Total params: 1,937,898\n",
"Trainable params: 1,937,418\n",
"Non-trainable params: 480\n",
"__________________________________________________________________________________________________\n"
]
}
],
"source": [
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/10\n",
"18/18 [==============================] - 9s 521ms/step - loss: 6067.2251 - val_loss: 2709.1370\n",
"Epoch 2/10\n",
"18/18 [==============================] - 9s 519ms/step - loss: 3588.0178 - val_loss: 1215.3599\n",
"Epoch 3/10\n",
"18/18 [==============================] - 9s 523ms/step - loss: 1767.9198 - val_loss: 575.0400\n",
"Epoch 4/10\n",
"18/18 [==============================] - 9s 519ms/step - loss: 921.6010 - val_loss: 212.0080\n",
"Epoch 5/10\n",
"18/18 [==============================] - 9s 511ms/step - loss: 495.6474 - val_loss: 94.8844\n",
"Epoch 6/10\n",
"18/18 [==============================] - 9s 525ms/step - loss: 394.5772 - val_loss: 164.4984\n",
"Epoch 7/10\n",
"18/18 [==============================] - 9s 512ms/step - loss: 245.1468 - val_loss: 201.1050\n",
"Epoch 8/10\n",
"18/18 [==============================] - 9s 514ms/step - loss: 264.4300 - val_loss: 231.4748\n",
"Epoch 9/10\n",
"18/18 [==============================] - 10s 529ms/step - loss: 232.9314 - val_loss: 210.3131\n",
"Epoch 10/10\n",
"18/18 [==============================] - 9s 514ms/step - loss: 189.8296 - val_loss: 199.3550\n",
"CPU times: user 9min 39s, sys: 24.3 s, total: 10min 4s\n",
"Wall time: 1min 39s\n"
]
}
],
"source": [
"%%time\n",
"hist = model.fit(\n",
" x=[trainAttrX, trainImagesX], y=trainY,\n",
" validation_data=([testAttrX, testImagesX], testY),\n",
" epochs=10, batch_size=8)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from postprocessing.plot_history import plot_history\n",
"\n",
"plot_history(hist)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# F - Evaluation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Training set"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"from postprocessing.evaluate import evaluate_hybrid, compute_score"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO:predicting ...\n",
"INFO:NumExpr defaulting to 8 threads.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"avg. FVC: 2771.744318181818, std FVC 835.5745106360505\n",
"mean difference : 36.84%, std: 45.71%\n",
"competition score : -4.617284040908737\n"
]
}
],
"source": [
"preds = evaluate_hybrid(model, df, trainAttrX, trainImagesX, trainY, sc)\n",
"conf, score = compute_score(trainY,preds.flatten())\n",
"print('competition score :', score)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5/5 [==============================] - 1s 273ms/step - loss: 240.9136\n"
]
},
{
"data": {
"text/plain": [
"240.91358947753906"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.evaluate([trainAttrX, trainImagesX], trainY)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Test set"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO:predicting ...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"avg. FVC: 2771.744318181818, std FVC 835.5745106360505\n",
"mean difference : 46.17%, std: 39.98%\n",
"competition score : -4.619806995461278\n"
]
}
],
"source": [
"preds = evaluate_hybrid(model, df, testAttrX, testImagesX, testY, sc)\n",
"conf, score = compute_score(testY,preds.flatten())\n",
"print('competition score :', score)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2/2 [==============================] - 0s 31ms/step - loss: 199.3550\n"
]
},
{
"data": {
"text/plain": [
"199.35498046875"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.evaluate([testAttrX, testImagesX], testY)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"_a=model.predict([trainAttrX, trainImagesX])"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"q=0.5\n",
"a = np.quantile(_a, q)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"ename": "IndexError",
"evalue": "index 1 is out of bounds for axis 1 with size 1",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-31-8ed85e029818>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0m_a\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mIndexError\u001b[0m: index 1 is out of bounds for axis 1 with size 1"
]