Commit c9f6290b authored by Bannier Delphine's avatar Bannier Delphine
Browse files

set up kfold

parent 20c0e823
......@@ -11,7 +11,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"https://www.pyimagesearch.com/2019/02/04/keras-multiple-inputs-and-mixed-data/"
"https://www.pyimagesearch.com/2019/02/04/keras-multiple-inputs-and-mixed-data/\n",
"\n",
"https://www.kaggle.com/franklemuchahary/basic-cnn-keras-with-cross-validation"
]
},
{
......@@ -312,13 +314,6 @@
"print(len(train_dataset),len(test_dataset))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
......@@ -335,6 +330,9 @@
"from preprocessing.scale_data import scale_variable\n",
"\n",
"sc, trainAttrX, testAttrX = scale_variable(trainAttrX, testAttrX,'Target_FVC')\n",
"sc1, trainAttrX, testAttrX = scale_variable(trainAttrX, testAttrX,'First_FVC')\n",
"sc2, trainAttrX, testAttrX = scale_variable(trainAttrX, testAttrX,'Age')\n",
"\n",
"trainY = trainAttrX.loc[:,'Target_FVC_scaled']\n",
"testY = testAttrX.loc[:,'Target_FVC_scaled']"
]
......@@ -350,8 +348,11 @@
"trainAttrX, testAttrX = encode_variable(trainAttrX, testAttrX,'Sex')\n",
"trainAttrX, testAttrX = encode_variable(trainAttrX, testAttrX,'SmokingStatus')\n",
"\n",
"trainAttrX.drop(columns = ['Sex','SmokingStatus','Target_FVC','Target_FVC_scaled','PatientID'], inplace = True)\n",
"testAttrX.drop(columns = ['Sex','SmokingStatus','Target_FVC','Target_FVC_scaled','PatientID'], inplace = True)"
"for dft in [trainAttrX,testAttrX]:\n",
" dft.drop(columns = ['Sex','SmokingStatus','Target_FVC','Target_FVC_scaled',\n",
" 'PatientID','First_FVC','Age'], inplace = True)\n",
" dft.loc[:,'First_Percent'] = dft.loc[:,'First_Percent']/100\n",
" dft.loc[:,'Delta_week'] = dft.loc[:,'Delta_week']/133"
]
},
{
......@@ -380,10 +381,10 @@
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Age</th>\n",
" <th>First_FVC</th>\n",
" <th>First_Percent</th>\n",
" <th>Delta_week</th>\n",
" <th>First_FVC_scaled</th>\n",
" <th>Age_scaled</th>\n",
" <th>Sex_le</th>\n",
" <th>SmokingStatus_le</th>\n",
" </tr>\n",
......@@ -391,46 +392,46 @@
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>79</td>\n",
" <td>2315</td>\n",
" <td>58.253649</td>\n",
" <td>9</td>\n",
" <td>0.582536</td>\n",
" <td>0.067669</td>\n",
" <td>-0.631784</td>\n",
" <td>1.684379</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>79</td>\n",
" <td>2315</td>\n",
" <td>58.253649</td>\n",
" <td>11</td>\n",
" <td>0.582536</td>\n",
" <td>0.082707</td>\n",
" <td>-0.631784</td>\n",
" <td>1.684379</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>79</td>\n",
" <td>2315</td>\n",
" <td>58.253649</td>\n",
" <td>13</td>\n",
" <td>0.582536</td>\n",
" <td>0.097744</td>\n",
" <td>-0.631784</td>\n",
" <td>1.684379</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>79</td>\n",
" <td>2315</td>\n",
" <td>58.253649</td>\n",
" <td>15</td>\n",
" <td>0.582536</td>\n",
" <td>0.112782</td>\n",
" <td>-0.631784</td>\n",
" <td>1.684379</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>79</td>\n",
" <td>2315</td>\n",
" <td>58.253649</td>\n",
" <td>21</td>\n",
" <td>0.582536</td>\n",
" <td>0.157895</td>\n",
" <td>-0.631784</td>\n",
" <td>1.684379</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
......@@ -439,12 +440,19 @@
"</div>"
],
"text/plain": [
" Age First_FVC First_Percent Delta_week Sex_le SmokingStatus_le\n",
"0 79 2315 58.253649 9 1 1\n",
"1 79 2315 58.253649 11 1 1\n",
"2 79 2315 58.253649 13 1 1\n",
"3 79 2315 58.253649 15 1 1\n",
"4 79 2315 58.253649 21 1 1"
" First_Percent Delta_week First_FVC_scaled Age_scaled Sex_le \\\n",
"0 0.582536 0.067669 -0.631784 1.684379 1 \n",
"1 0.582536 0.082707 -0.631784 1.684379 1 \n",
"2 0.582536 0.097744 -0.631784 1.684379 1 \n",
"3 0.582536 0.112782 -0.631784 1.684379 1 \n",
"4 0.582536 0.157895 -0.631784 1.684379 1 \n",
"\n",
" SmokingStatus_le \n",
"0 1 \n",
"1 1 \n",
"2 1 \n",
"3 1 \n",
"4 1 "
]
},
"execution_count": 12,
......@@ -560,67 +568,251 @@
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n",
"\n",
"#set early stopping criteria\n",
"pat = 5 #this is the number of epochs with no improvment after which the training will stop\n",
"es = EarlyStopping(monitor='val_loss', patience=pat, verbose=1)\n",
"\n",
"#define the model checkpoint callback -> this will keep on saving the model as a physical file\n",
"cp = ModelCheckpoint('superposition_injection.h5', verbose=1, save_best_only=True)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"def custom_shuffle_split(trainAttrX,train_dataset,trainY,test_size = 0.1 ):\n",
" cut = int(len(trainY)*test_size)\n",
" arr = list(np.arange(len(trainY)))\n",
" np.random.shuffle(arr)\n",
" trainidx = arr[cut:]\n",
" testidx = arr[:cut]\n",
" train_x, train_y = [trainAttrX.iloc[trainidx], train_dataset[trainidx]] , trainY[trainidx]\n",
" val_x, val_y = [trainAttrX.iloc[testidx], train_dataset[testidx]] , trainY[testidx]\n",
" return train_x, val_x, train_y, val_y"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/50\n",
" 84/137 [=================>............] - ETA: 27s - loss: 198187.9375"
"Training on Fold: 1\n",
"Epoch 1/30\n",
"111/111 [==============================] - ETA: 0s - loss: 316.5363\n",
"Epoch 00001: val_loss improved from inf to 107.96893, saving model to superposition_injection.h5\n",
"111/111 [==============================] - 56s 503ms/step - loss: 316.5363 - val_loss: 107.9689\n",
"Epoch 2/30\n",
"111/111 [==============================] - ETA: 0s - loss: 197.5600\n",
"Epoch 00002: val_loss improved from 107.96893 to 100.10335, saving model to superposition_injection.h5\n",
"111/111 [==============================] - 55s 495ms/step - loss: 197.5600 - val_loss: 100.1033\n",
"Epoch 3/30\n",
"111/111 [==============================] - ETA: 0s - loss: 220.9793\n",
"Epoch 00003: val_loss improved from 100.10335 to 99.90191, saving model to superposition_injection.h5\n",
"111/111 [==============================] - 54s 485ms/step - loss: 220.9793 - val_loss: 99.9019\n",
"Epoch 4/30\n",
"111/111 [==============================] - ETA: 0s - loss: 126.4834\n",
"Epoch 00004: val_loss did not improve from 99.90191\n",
"111/111 [==============================] - 55s 498ms/step - loss: 126.4834 - val_loss: 100.0706\n",
"Epoch 5/30\n",
"111/111 [==============================] - ETA: 0s - loss: 130.7720\n",
"Epoch 00005: val_loss improved from 99.90191 to 99.70051, saving model to superposition_injection.h5\n",
"111/111 [==============================] - 54s 485ms/step - loss: 130.7720 - val_loss: 99.7005\n",
"Epoch 6/30\n",
"111/111 [==============================] - ETA: 0s - loss: 164.4418\n",
"Epoch 00006: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 54s 483ms/step - loss: 164.4418 - val_loss: 100.6682\n",
"Epoch 7/30\n",
"111/111 [==============================] - ETA: 0s - loss: 119.5080\n",
"Epoch 00007: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 55s 497ms/step - loss: 119.5080 - val_loss: 101.0239\n",
"Epoch 8/30\n",
"111/111 [==============================] - ETA: 0s - loss: 151.3392\n",
"Epoch 00008: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 56s 505ms/step - loss: 151.3392 - val_loss: 100.1579\n",
"Epoch 9/30\n",
"111/111 [==============================] - ETA: 0s - loss: 105.6256\n",
"Epoch 00009: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 55s 492ms/step - loss: 105.6256 - val_loss: 100.2133\n",
"Epoch 10/30\n",
"111/111 [==============================] - ETA: 0s - loss: 114.8794\n",
"Epoch 00010: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 54s 491ms/step - loss: 114.8794 - val_loss: 100.3191\n",
"Epoch 00010: early stopping\n",
"4/4 [==============================] - 1s 200ms/step - loss: 100.1156\n",
"Val Score: 100.11563110351562\n",
"====================================================================================\n",
"\n",
"\n",
"Training on Fold: 2\n",
"Epoch 1/30\n",
"111/111 [==============================] - ETA: 0s - loss: 168.3844\n",
"Epoch 00001: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 55s 494ms/step - loss: 168.3844 - val_loss: 107.7039\n",
"Epoch 2/30\n",
"111/111 [==============================] - ETA: 0s - loss: 111.5110\n",
"Epoch 00002: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 56s 507ms/step - loss: 111.5110 - val_loss: 109.4569\n",
"Epoch 3/30\n",
"111/111 [==============================] - ETA: 0s - loss: 114.4467\n",
"Epoch 00003: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 56s 505ms/step - loss: 114.4467 - val_loss: 101.8173\n",
"Epoch 4/30\n",
"111/111 [==============================] - ETA: 0s - loss: 112.2941\n",
"Epoch 00004: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 55s 492ms/step - loss: 112.2941 - val_loss: 109.3902\n",
"Epoch 5/30\n",
"111/111 [==============================] - ETA: 0s - loss: 112.2740\n",
"Epoch 00005: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 56s 503ms/step - loss: 112.2740 - val_loss: 101.4342\n",
"Epoch 6/30\n",
"111/111 [==============================] - ETA: 0s - loss: 111.4760\n",
"Epoch 00006: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 55s 500ms/step - loss: 111.4760 - val_loss: 99.8436\n",
"Epoch 7/30\n",
"111/111 [==============================] - ETA: 0s - loss: 110.4311\n",
"Epoch 00007: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 56s 503ms/step - loss: 110.4311 - val_loss: 110.9042\n",
"Epoch 8/30\n",
"111/111 [==============================] - ETA: 0s - loss: 107.2995\n",
"Epoch 00008: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 58s 520ms/step - loss: 107.2995 - val_loss: 100.7832\n",
"Epoch 9/30\n",
"111/111 [==============================] - ETA: 0s - loss: 103.8186\n",
"Epoch 00009: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 56s 500ms/step - loss: 103.8186 - val_loss: 103.2870\n",
"Epoch 10/30\n",
"111/111 [==============================] - ETA: 0s - loss: 101.8159\n",
"Epoch 00010: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 54s 489ms/step - loss: 101.8159 - val_loss: 100.8220\n",
"Epoch 11/30\n",
"111/111 [==============================] - ETA: 0s - loss: 104.4015\n",
"Epoch 00011: val_loss did not improve from 99.70051\n",
"111/111 [==============================] - 54s 483ms/step - loss: 104.4015 - val_loss: 110.9032\n",
"Epoch 00011: early stopping\n",
"4/4 [==============================] - 1s 219ms/step - loss: 108.3460\n",
"Val Score: 108.34602355957031\n",
"====================================================================================\n",
"\n",
"\n"
]
},
}
],
"source": [
"from processing.models import fit_and_evaluate\n",
"n_folds=2\n",
"epochs=30\n",
"batch_size=8\n",
"\n",
"\n",
"#save the model history in a list after fitting so that we can plot later\n",
"model_history = [] \n",
"\n",
"for i in range(n_folds):\n",
" print(\"Training on Fold: \",i+1)\n",
" model = None\n",
" model = create_hybrid(trainAttrX.shape[1], shape = (240,240,1))\n",
" model.compile(loss=\"mean_absolute_percentage_error\", optimizer=opt)\n",
" t_x, val_x, t_y, val_y = custom_shuffle_split(trainAttrX,train_dataset,trainY,test_size = 0.1) \n",
" model_history.append(fit_and_evaluate(t_x, val_x, t_y, val_y, epochs, batch_size,model,es,cp))\n",
" print(\"=======\"*12, end=\"\\n\\n\\n\")"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<timed exec>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py\u001b[0m in \u001b[0;36m_method_wrapper\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_method_wrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 65\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_in_multi_worker_mode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# pylint: disable=protected-access\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 66\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 67\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0;31m# Running inside `run_distribute_coordinator` already.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)\u001b[0m\n\u001b[1;32m 846\u001b[0m batch_size=batch_size):\n\u001b[1;32m 847\u001b[0m \u001b[0mcallbacks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_train_batch_begin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 848\u001b[0;31m \u001b[0mtmp_logs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0miterator\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 849\u001b[0m \u001b[0;31m# Catch OutOfRangeError for Datasets of unknown size.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 850\u001b[0m \u001b[0;31m# This blocks until the batch has finished executing.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args, **kwds)\u001b[0m\n\u001b[1;32m 578\u001b[0m \u001b[0mxla_context\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mExit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 579\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 580\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 581\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 582\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtracing_count\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_tracing_count\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py\u001b[0m in \u001b[0;36m_call\u001b[0;34m(self, *args, **kwds)\u001b[0m\n\u001b[1;32m 609\u001b[0m \u001b[0;31m# In this case we have created variables on the first call, so we run the\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 610\u001b[0m \u001b[0;31m# defunned version which is guaranteed to never create variables.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 611\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_stateless_fn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# pylint: disable=not-callable\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 612\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_stateful_fn\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 613\u001b[0m \u001b[0;31m# Release the lock early so that multiple threads can perform the call\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/function.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 2418\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_lock\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2419\u001b[0m \u001b[0mgraph_function\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_maybe_define_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2420\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mgraph_function\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_filtered_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# pylint: disable=protected-access\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2421\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2422\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mproperty\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/function.py\u001b[0m in \u001b[0;36m_filtered_call\u001b[0;34m(self, args, kwargs)\u001b[0m\n\u001b[1;32m 1659\u001b[0m \u001b[0;31m`\u001b[0m\u001b[0margs\u001b[0m\u001b[0;31m`\u001b[0m \u001b[0;32mand\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1660\u001b[0m \"\"\"\n\u001b[0;32m-> 1661\u001b[0;31m return self._call_flat(\n\u001b[0m\u001b[1;32m 1662\u001b[0m (t for t in nest.flatten((args, kwargs), expand_composites=True)\n\u001b[1;32m 1663\u001b[0m if isinstance(t, (ops.Tensor,\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/function.py\u001b[0m in \u001b[0;36m_call_flat\u001b[0;34m(self, args, captured_inputs, cancellation_manager)\u001b[0m\n\u001b[1;32m 1743\u001b[0m and executing_eagerly):\n\u001b[1;32m 1744\u001b[0m \u001b[0;31m# No tape is watching; skip to running the function.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1745\u001b[0;31m return self._build_call_outputs(self._inference_function.call(\n\u001b[0m\u001b[1;32m 1746\u001b[0m ctx, args, cancellation_manager=cancellation_manager))\n\u001b[1;32m 1747\u001b[0m forward_backward = self._select_forward_and_backward_functions(\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/function.py\u001b[0m in \u001b[0;36mcall\u001b[0;34m(self, ctx, args, cancellation_manager)\u001b[0m\n\u001b[1;32m 591\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0m_InterpolateFunctionError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 592\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcancellation_manager\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 593\u001b[0;31m outputs = execute.execute(\n\u001b[0m\u001b[1;32m 594\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msignature\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 595\u001b[0m \u001b[0mnum_outputs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_num_outputs\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/execute.py\u001b[0m in \u001b[0;36mquick_execute\u001b[0;34m(op_name, num_outputs, inputs, attrs, ctx, name)\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 58\u001b[0m \u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mensure_initialized\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 59\u001b[0;31m tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,\n\u001b[0m\u001b[1;32m 60\u001b[0m inputs, attrs, num_outputs)\n\u001b[1;32m 61\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mcore\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_NotOkStatusException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
]
"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": [
"%%time\n",
"hist = model.fit(\n",
" x=[trainAttrX, train_dataset], y=trainY,\n",
" validation_data=([testAttrX, test_dataset], testY),\n",
" epochs=50, batch_size=8)"
"import matplotlib.pyplot as plt \n",
"\n",
"plt.title('Loss vs Epochs')\n",
"plt.plot(model_history[0].history['loss'], label='Training Fold 1')\n",
"plt.plot(model_history[1].history['loss'], label='Training Fold 2')\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 21,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'hist' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-16-17f56577a9c3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mpostprocessing\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot_history\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mplot_history\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mplot_history\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhist\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'hist' is not defined"
]
"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",
"plt.title('Validation loss vs Epochs')\n",
"plt.plot(model_history[0].history['val_loss'], label='Training Fold 1')\n",
"plt.plot(model_history[1].history['val_loss'], label='Training Fold 2')\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"from keras.models import load_model\n",
"\n",
"plot_history(hist)"
"model = load_model('superposition_injection.h5')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
......@@ -637,24 +829,59 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 25,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO:predicting ...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"avg. FVC: 2690.479018721756, std FVC 832.7709592986739\n",
"mean difference : 27.58%, std: 29.55%\n",
"competition score : -4.610789567859322\n"
]
}
],
"source": [
"from postprocessing.evaluate import evaluate_hybrid, compute_score\n",
"\n",
"preds = evaluate_hybrid(model, df, trainAttrX, trainImagesX, trainY, sc)\n",
"preds = evaluate_hybrid(model, df, trainAttrX, train_dataset, trainY, sc)\n",
"conf, score = compute_score(trainY,preds.flatten())\n",
"print('competition score :', score)"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 26,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"35/35 [==============================] - 11s 314ms/step - loss: 101.1096\n"
]
},
{
"data": {
"text/plain": [
"101.10960388183594"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.evaluate([trainAttrX, trainImagesX], trainY)"
"model.evaluate([trainAttrX, train_dataset], trainY)"
]
},
{
......@@ -666,22 +893,57 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 27,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO:predicting ...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"avg. FVC: 2690.479018721756, std FVC 832.7709592986739\n",
"mean difference : 34.22%, std: 31.98%\n",
"competition score : -4.61193964179478\n"
]
}
],
"source": [
"preds = evaluate_hybrid(model, df, testAttrX, testImagesX, testY, sc)\n",
"preds = evaluate_hybrid(model, df, testAttrX, test_dataset, testY, sc)\n",
"conf, score = compute_score(testY,preds.flatten())\n",
"print('competition score :', score)"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 28,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"9/9 [==============================] - 3s 279ms/step - loss: 100.0515\n"
]
},
{
"data": {
"text/plain": [
"100.05147552490234"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.evaluate([testAttrX, testImagesX], testY)"
"model.evaluate([testAttrX, test_dataset], testY)"
]
},
{
......
%% Cell type:markdown id: tags:
# CNN collage + MLP
%% Cell type:markdown id: tags:
https://www.pyimagesearch.com/2019/02/04/keras-multiple-inputs-and-mixed-data/
https://www.kaggle.com/franklemuchahary/basic-cnn-keras-with-cross-validation
%% Cell type:code id: tags:
``` python
import numpy as np
import pandas as pd
import os
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
```
%% Cell type:markdown id: tags:
## A - Preprocessing : Reading Data
%% Cell type:code id: tags:
``` python
os.chdir('../')
```
%% Cell type:code id: tags:
``` python
from preprocessing.read_load_data import read_data
input_directory='../osic-pulmonary-fibrosis-progression'
train_df, test_df, sample_df = read_data(input_directory)
train_df.head()
```
%%%% Output: execute_result
Patient Weeks FVC Percent Age Sex SmokingStatus
0 ID00007637202177411956430 -4 2315 58.253649 79 Male Ex-smoker
1 ID00007637202177411956430 5 2214 55.712129 79 Male Ex-smoker
2 ID00007637202177411956430 7 2061 51.862104 79 Male Ex-smoker
3 ID00007637202177411956430 9 2144 53.950679 79 Male Ex-smoker
4 ID00007637202177411956430 11 2069 52.063412 79 Male Ex-smoker
%% Cell type:markdown id: tags:
## B - Preprocessing : Loading Data
%% Cell type:code id: tags:
``` python
patients_train_ids= train_df.Patient.unique()
patient_test_list= test_df.Patient.unique()
patients_train_ids = [pat for pat in patients_train_ids]
```
%% Cell type:code id: tags:
``` python
from preprocessing.read_load_data import load_images
logging.info("loading attributes...")
df = pd.read_csv(f'{input_directory}/train.csv')
patients_train_ids= df.Patient.unique().tolist()
logging.info("loading images...")
images = load_images(input_directory,
'train',
patients_train_ids,
option='collage',
outputH = 240,
outputW = 240)