{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":11848,"databundleVersionId":862157,"sourceType":"competition"}],"dockerImageVersionId":30558,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# CNN Cancer Detection","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport time\nimport matplotlib.pyplot as plt\nimport cv2\nimport tensorflow as tf\nimport seaborn as sns\nfrom PIL import Image\nfrom tensorflow import keras\nimport tensorflow_io as tfio\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D\nfrom tensorflow.keras.layers import Dense, Dropout, Flatten, Activation\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint\nfrom tensorflow.keras.optimizers import Adam\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score\nfrom tensorflow.keras.models import load_model\nfrom sklearn.utils import resample","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-11-17T19:17:08.361063Z","iopub.execute_input":"2023-11-17T19:17:08.361526Z","iopub.status.idle":"2023-11-17T19:17:19.509193Z","shell.execute_reply.started":"2023-11-17T19:17:08.361489Z","shell.execute_reply":"2023-11-17T19:17:19.507967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Description","metadata":{}},{"cell_type":"markdown","source":"Create an algorithm to identify metastatic cancer in small image patches taken from larger digital pathology scans using CNN model","metadata":{}},{"cell_type":"markdown","source":"## EDA","metadata":{}},{"cell_type":"markdown","source":"I created the train_data_path with \"/\" at the end to avoid being adding it everytime on the code","metadata":{}},{"cell_type":"code","source":"train_data_path = '../input/histopathologic-cancer-detection/train/'","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:19.511307Z","iopub.execute_input":"2023-11-17T19:17:19.511969Z","iopub.status.idle":"2023-11-17T19:17:19.517505Z","shell.execute_reply.started":"2023-11-17T19:17:19.511925Z","shell.execute_reply":"2023-11-17T19:17:19.516262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len_train = len(os.listdir(train_data_path))\nlen_train","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:19.518649Z","iopub.execute_input":"2023-11-17T19:17:19.519600Z","iopub.status.idle":"2023-11-17T19:17:22.355169Z","shell.execute_reply.started":"2023-11-17T19:17:19.519559Z","shell.execute_reply":"2023-11-17T19:17:22.354244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"But, I didn't put for the test data because it's not needed","metadata":{}},{"cell_type":"code","source":"test_data_path = '../input/histopathologic-cancer-detection/test'","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:22.358316Z","iopub.execute_input":"2023-11-17T19:17:22.358757Z","iopub.status.idle":"2023-11-17T19:17:22.363634Z","shell.execute_reply.started":"2023-11-17T19:17:22.358717Z","shell.execute_reply":"2023-11-17T19:17:22.362519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len_test = len(os.listdir(test_data_path))\nlen_test","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:22.365330Z","iopub.execute_input":"2023-11-17T19:17:22.366043Z","iopub.status.idle":"2023-11-17T19:17:27.997323Z","shell.execute_reply.started":"2023-11-17T19:17:22.366002Z","shell.execute_reply":"2023-11-17T19:17:27.996198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Checking both Train and Test Data we can see that all pictures are in .TIF which means they have a higher quality than .PNG or .JPEG. .TIF or .TIFF are used in professinal photografy world and for a investigation of cancer, those images have to have a high-end quality and that's the why those images are in .TIF","metadata":{}},{"cell_type":"markdown","source":"They all have the same size 27.94kb","metadata":{}},{"cell_type":"code","source":"label_data = pd.read_csv('../input/histopathologic-cancer-detection/train_labels.csv')","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:27.998572Z","iopub.execute_input":"2023-11-17T19:17:27.998923Z","iopub.status.idle":"2023-11-17T19:17:28.357315Z","shell.execute_reply.started":"2023-11-17T19:17:27.998871Z","shell.execute_reply":"2023-11-17T19:17:28.356299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_data","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.358554Z","iopub.execute_input":"2023-11-17T19:17:28.358855Z","iopub.status.idle":"2023-11-17T19:17:28.383032Z","shell.execute_reply.started":"2023-11-17T19:17:28.358830Z","shell.execute_reply":"2023-11-17T19:17:28.381779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_data.info()","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.384487Z","iopub.execute_input":"2023-11-17T19:17:28.384806Z","iopub.status.idle":"2023-11-17T19:17:28.426348Z","shell.execute_reply.started":"2023-11-17T19:17:28.384779Z","shell.execute_reply":"2023-11-17T19:17:28.425239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_data.describe()","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.427721Z","iopub.execute_input":"2023-11-17T19:17:28.428072Z","iopub.status.idle":"2023-11-17T19:17:28.453188Z","shell.execute_reply.started":"2023-11-17T19:17:28.428043Z","shell.execute_reply":"2023-11-17T19:17:28.451988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_count = label_data['label'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.456969Z","iopub.execute_input":"2023-11-17T19:17:28.457303Z","iopub.status.idle":"2023-11-17T19:17:28.465134Z","shell.execute_reply.started":"2023-11-17T19:17:28.457274Z","shell.execute_reply":"2023-11-17T19:17:28.464220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_count","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.466448Z","iopub.execute_input":"2023-11-17T19:17:28.467411Z","iopub.status.idle":"2023-11-17T19:17:28.481030Z","shell.execute_reply.started":"2023-11-17T19:17:28.467377Z","shell.execute_reply":"2023-11-17T19:17:28.479643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = label_data['label'].values","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.482705Z","iopub.execute_input":"2023-11-17T19:17:28.483292Z","iopub.status.idle":"2023-11-17T19:17:28.487449Z","shell.execute_reply.started":"2023-11-17T19:17:28.483260Z","shell.execute_reply":"2023-11-17T19:17:28.486472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.489209Z","iopub.execute_input":"2023-11-17T19:17:28.489845Z","iopub.status.idle":"2023-11-17T19:17:28.500534Z","shell.execute_reply.started":"2023-11-17T19:17:28.489806Z","shell.execute_reply":"2023-11-17T19:17:28.499387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"0 means the image has no tumor tissue  \n1 means the image has tumor tissue","metadata":{}},{"cell_type":"code","source":"plt.pie(label_count, labels = [0,1], startangle=90, autopct='%1.1f%%')\nplt.title('Tumor Tissue')\nplt.xlabel('0 = No Tumor, 1 = Tumor')\nplt.ylabel('Propotion')","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.502127Z","iopub.execute_input":"2023-11-17T19:17:28.502824Z","iopub.status.idle":"2023-11-17T19:17:28.684971Z","shell.execute_reply.started":"2023-11-17T19:17:28.502780Z","shell.execute_reply":"2023-11-17T19:17:28.683936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As the Training data has 40.5% of tumor tissue and 59.5% with no tumor issue, this data is not consided imbalanced.","metadata":{}},{"cell_type":"code","source":"label_data['id'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.686478Z","iopub.execute_input":"2023-11-17T19:17:28.686979Z","iopub.status.idle":"2023-11-17T19:17:28.947379Z","shell.execute_reply.started":"2023-11-17T19:17:28.686938Z","shell.execute_reply":"2023-11-17T19:17:28.946510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are no duplicates id in the label data","metadata":{}},{"cell_type":"code","source":"len_train/(len_test+len_train)","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.948554Z","iopub.execute_input":"2023-11-17T19:17:28.949049Z","iopub.status.idle":"2023-11-17T19:17:28.955206Z","shell.execute_reply.started":"2023-11-17T19:17:28.949021Z","shell.execute_reply":"2023-11-17T19:17:28.954091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len_test/(len_test+len_train)","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.956847Z","iopub.execute_input":"2023-11-17T19:17:28.957235Z","iopub.status.idle":"2023-11-17T19:17:28.967214Z","shell.execute_reply.started":"2023-11-17T19:17:28.957206Z","shell.execute_reply":"2023-11-17T19:17:28.965887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As the training data is 79.3% of the total data and test data is 20.7%, It is recommended to have the validation data as approximaly the same size as test data, so I will split the training data in 60% and 19.3%, to leave the training data with at least 60% of the total data.","metadata":{"execution":{"iopub.status.busy":"2023-11-05T14:58:24.706972Z","iopub.execute_input":"2023-11-05T14:58:24.707377Z","iopub.status.idle":"2023-11-05T14:58:24.712583Z","shell.execute_reply.started":"2023-11-05T14:58:24.707345Z","shell.execute_reply":"2023-11-05T14:58:24.711309Z"}}},{"cell_type":"code","source":"len_val = (len_test+len_train)*0.193\nlen_val","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.968737Z","iopub.execute_input":"2023-11-17T19:17:28.969217Z","iopub.status.idle":"2023-11-17T19:17:28.978254Z","shell.execute_reply.started":"2023-11-17T19:17:28.969159Z","shell.execute_reply":"2023-11-17T19:17:28.976976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"split_rate = len_val/len_train\nsplit_rate","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.981577Z","iopub.execute_input":"2023-11-17T19:17:28.981916Z","iopub.status.idle":"2023-11-17T19:17:28.988494Z","shell.execute_reply.started":"2023-11-17T19:17:28.981867Z","shell.execute_reply":"2023-11-17T19:17:28.987524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_data['id'][10]","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:28.989650Z","iopub.execute_input":"2023-11-17T19:17:28.990276Z","iopub.status.idle":"2023-11-17T19:17:28.999013Z","shell.execute_reply.started":"2023-11-17T19:17:28.990244Z","shell.execute_reply":"2023-11-17T19:17:28.998141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Showing few of the imaging and labels of the training data","metadata":{}},{"cell_type":"code","source":"for i in range(10):\n    label_data['id'][i]\n    im=cv2.imread(train_data_path + label_data['id'][i] +'.tif')\n    f, ax = plt.subplots()\n    plt.title(label_data['label'][i])\n    ax.imshow(im, resample=True, cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:29.000144Z","iopub.execute_input":"2023-11-17T19:17:29.001023Z","iopub.status.idle":"2023-11-17T19:17:31.486694Z","shell.execute_reply.started":"2023-11-17T19:17:29.000991Z","shell.execute_reply":"2023-11-17T19:17:31.481803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As I had explained above, as the data is not considered imbalanced, so I will use the how train data to divide in training and valid data","metadata":{}},{"cell_type":"markdown","source":"## DModel Architecture","metadata":{}},{"cell_type":"markdown","source":"I've used the CNN architecture presented by @fmarazzi in this kernel:\nhttps://www.kaggle.com/fmarazzi/baseline-keras-cnn-roc-fast-5min-0-8253-lb","metadata":{}},{"cell_type":"markdown","source":"The achitecture is simple: the model has relu as hidden activation fuctions and sigmoid for output because it is a single classification model","metadata":{}},{"cell_type":"code","source":"kernel_size = (3,3)\npool_size= (2,2)\nfirst_filters = 32\nsecond_filters = 64\nthird_filters = 128\n\ndropout_conv = 0.3\ndropout_dense = 0.3\n\n\nmodel = Sequential()\nmodel.add(Conv2D(first_filters, kernel_size, activation = 'relu', input_shape = (96, 96, 3)))\nmodel.add(Conv2D(first_filters, kernel_size, activation = 'relu'))\nmodel.add(Conv2D(first_filters, kernel_size, activation = 'relu'))\nmodel.add(MaxPooling2D(pool_size = pool_size)) \nmodel.add(Dropout(dropout_conv))\n\nmodel.add(Conv2D(second_filters, kernel_size, activation ='relu'))\nmodel.add(Conv2D(second_filters, kernel_size, activation ='relu'))\nmodel.add(Conv2D(second_filters, kernel_size, activation ='relu'))\nmodel.add(MaxPooling2D(pool_size = pool_size))\nmodel.add(Dropout(dropout_conv))\n\nmodel.add(Conv2D(third_filters, kernel_size, activation ='relu'))\nmodel.add(Conv2D(third_filters, kernel_size, activation ='relu'))\nmodel.add(Conv2D(third_filters, kernel_size, activation ='relu'))\nmodel.add(MaxPooling2D(pool_size = pool_size))\nmodel.add(Dropout(dropout_conv))\n\nmodel.add(Flatten())\nmodel.add(Dense(512, activation = \"relu\"))\nmodel.add(Dropout(dropout_dense))\nmodel.add(Dense(1, activation = \"sigmoid\"))\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:31.488086Z","iopub.execute_input":"2023-11-17T19:17:31.489455Z","iopub.status.idle":"2023-11-17T19:17:31.925047Z","shell.execute_reply.started":"2023-11-17T19:17:31.489405Z","shell.execute_reply":"2023-11-17T19:17:31.923954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\n\noptimizer = Adam(learning_rate=0.0001)\nmodel.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:31.926485Z","iopub.execute_input":"2023-11-17T19:17:31.926824Z","iopub.status.idle":"2023-11-17T19:17:31.949162Z","shell.execute_reply.started":"2023-11-17T19:17:31.926795Z","shell.execute_reply":"2023-11-17T19:17:31.948275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_data['label'] = label_data['label'].astype(str)  # Convert label column to string","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:31.950531Z","iopub.execute_input":"2023-11-17T19:17:31.951085Z","iopub.status.idle":"2023-11-17T19:17:32.050397Z","shell.execute_reply.started":"2023-11-17T19:17:31.951053Z","shell.execute_reply":"2023-11-17T19:17:32.049510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"My computer couldn't support to run the whole train data, not even a small part, so I used only he head 1000 to train my model,which is not ideal with batches size of 128. Number of epochs were 5 to speed the running process, by the epoch 2 my model is already tending to overfit because of the amount of data train I had to give","metadata":{}},{"cell_type":"code","source":"# Add the .tif extension to the 'id' column for correct file referencing\nlabel_data['id'] = label_data['id'].apply(lambda x: f\"{x}.tif\")\n\n# Preparing data generators\ntrain_datagen = ImageDataGenerator(rescale=1./255, validation_split=split_rate)  # Normalize images\n\nbatch_size = 128\ntrain_steps = 1000*(1-split_rate) // batch_size  \nval_steps = 1000*split_rate // batch_size    \n\ntrain_gen = train_datagen.flow_from_dataframe(\n    dataframe=label_data.head(1000),\n    directory=train_data_path,\n    x_col='id',\n    y_col='label',\n    target_size=(96, 96),\n    class_mode='binary',\n    batch_size=batch_size,\n    subset='training'\n)\n\nval_gen = train_datagen.flow_from_dataframe(\n    dataframe=label_data.head(1000),\n    directory=train_data_path,\n    x_col='id',\n    y_col='label',\n    target_size=(96, 96),\n    class_mode='binary',\n    batch_size=batch_size,\n    subset='validation'\n)\n\n# Training the model\nhistory = model.fit(\n    train_gen,\n    steps_per_epoch=train_steps,\n    validation_data=val_gen,\n    validation_steps=val_steps,\n    epochs=5\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:17:32.051793Z","iopub.execute_input":"2023-11-17T19:17:32.052386Z","iopub.status.idle":"2023-11-17T19:20:50.629034Z","shell.execute_reply.started":"2023-11-17T19:17:32.052353Z","shell.execute_reply":"2023-11-17T19:20:50.627873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ids = [filename[:-4] for filename in os.listdir(test_data_path)]\ntest_filenames = [os.path.join(test_data_path, filename) for filename in os.listdir(test_data_path)]\ntest_df = pd.DataFrame()\ntest_df[\"id\"] = test_ids\ntest_df[\"filename\"] = test_filenames","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:20:50.630797Z","iopub.execute_input":"2023-11-17T19:20:50.631619Z","iopub.status.idle":"2023-11-17T19:20:50.809860Z","shell.execute_reply.started":"2023-11-17T19:20:50.631568Z","shell.execute_reply":"2023-11-17T19:20:50.808658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_generator = train_datagen.flow_from_dataframe(\n    dataframe=test_df,\n    x_col=\"filename\",\n    y_col=None,\n    target_size=(96, 96),\n    color_mode=\"rgb\",\n    batch_size=batch_size,\n    shuffle=False,\n    class_mode=None,\n    validate_filenames=False\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:20:50.811826Z","iopub.execute_input":"2023-11-17T19:20:50.812444Z","iopub.status.idle":"2023-11-17T19:20:50.916037Z","shell.execute_reply.started":"2023-11-17T19:20:50.812395Z","shell.execute_reply":"2023-11-17T19:20:50.914914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_probs = model.predict(test_generator)\ntest_labels = np.round(test_probs).astype(int).flatten()\nout_df = pd.DataFrame()\nout_df[\"id\"] = test_ids\nout_df[\"label\"] = test_labels","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:20:50.920881Z","iopub.execute_input":"2023-11-17T19:20:50.921266Z","iopub.status.idle":"2023-11-17T19:31:45.090640Z","shell.execute_reply.started":"2023-11-17T19:20:50.921229Z","shell.execute_reply":"2023-11-17T19:31:45.089334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"out_df","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:31:45.092241Z","iopub.execute_input":"2023-11-17T19:31:45.092730Z","iopub.status.idle":"2023-11-17T19:31:45.106643Z","shell.execute_reply.started":"2023-11-17T19:31:45.092690Z","shell.execute_reply":"2023-11-17T19:31:45.105452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"out_df.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:31:45.108548Z","iopub.execute_input":"2023-11-17T19:31:45.108952Z","iopub.status.idle":"2023-11-17T19:31:45.237832Z","shell.execute_reply.started":"2023-11-17T19:31:45.108910Z","shell.execute_reply":"2023-11-17T19:31:45.236382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.read_csv('/kaggle/working/submission.csv')","metadata":{"execution":{"iopub.status.busy":"2023-11-17T19:31:45.239438Z","iopub.execute_input":"2023-11-17T19:31:45.240298Z","iopub.status.idle":"2023-11-17T19:31:45.305930Z","shell.execute_reply.started":"2023-11-17T19:31:45.240263Z","shell.execute_reply":"2023-11-17T19:31:45.304675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Conclusion","metadata":{}},{"cell_type":"markdown","source":"My model preditct 50% of the results, the low value is due to the points below:\n - My computer couldn't support to run a database with images like that, it was too big for my processing.\n - The CCN architeture I chose is slower than other ones I saw around\n - I used only 1000 pictures\n - I used only the head 1000","metadata":{}},{"cell_type":"markdown","source":"My model proposition was to split the train data in a way we had train with 60%, validation data with 20% and test data with 20%. Train data + test data = 100%, test data was already 20%, so I decided to split train data in train and validation data to make that happen.\nIf I had a better computer using SGUs to support runnning it, my model will be better trainined and my results would have been much better.","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}