{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import Image","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Laboratorio 3: Reconocimiento de imágenes\n# Aplicación en detección de Retinopatía Diabética\n## Introducción\nLa retinopatía diabética es una enfermedad ocular que puede producirse en pacientes con diabetes. Se da debido a los altos niveles de azúcar en la sangre que causan daño a los vasos sanguíneos en la retina. Es general que no se presenten síntomas en las etapas tempranas. Los síntomas de la retinopatía diabética suelen afectar a ambos ojos. A medida que empeora la enfermedad, se presentan los siguientes síntomas:\n\n* Un mayor número de moscas volantes\n* Visión borrosa\n* Visión que cambia de borrosa a clara\n* Ver áreas en blanco u oscuras en el campo de visión\n* Visión nocturna deficiente\n* Notar que los colores se ven atenuados o apagados\n* Pérdida la visión\n\n#### Etapas y detección\nLa retinopatía se puede detectar de múltiples maneras, sin embargo existe un método a través del cual este padecimiento es detectado por inspección visual de los ojos del paciente. Los ojos, específicamente “un diferencial del ojo” se pueden observar nubosidades, que son hemorragias de los vasos sanguíneos.\n","execution_count":null},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"Image(\"../input/assets/assets/RetinopatiaDiabetica.jpg\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"##### Tipos de retinopatía diabética\n* Retinopatía diabética proliferativa: Esta es la etapa más avanzada de la enfermedad. Se produce cuando la retina comienza a desarrollar nuevos vasos sanguíneos. Esto se denomina neovascularización. Estos vasos nuevos frágiles a menudo sangran hacia el vítreo. La retinopatía diabética proliferativa es muy grave y puede hacerle perder tanto la visión central como la periférica.\n\n* Retinopatía diabética no proliferativa: Esta es la etapa temprana de la enfermedad ocular diabética. La mayoría de las personas diabéticas padecen de este tipo de retinopatía. En esta etapa de la enfermedad, muchos vasos sanguíneos pequeños sufren pérdidas y hacen que la retina se hinche. Si  se tiene retinopatía diabética no proliferativa, la visión del paciente será borrosa\n\n##### Problemas de detección\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"Image('../input/assets/assets/tensorflow.PNG')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"La gráfica anterior muestra que incluso oftalmólogos pueden presentar inconsistencias a la hora de diagnosticar a un paciente como con, o sin, retinopatía diabética y el grado de la misma.\n\n## Análisis del dataset\n\nLas imágenes son de varias dimensiones, habiendo de 1050 x 1050 px, 3216 x 2136 px, entre otros, a color por lo que se recomienda modificar las imágenes a escala de grises, o bien una transformación que permita reducir la complejidad de la red neuronal, logrando reducir el uso de recursos computacionales. \n\nEl dataset provisto contiene 3,662 observaciones para entrenar y 1,928 para testear. Las columnas que contiene el dataset es de código - de la cual no se presentará un análisis pues no brinda información esencial - y diagnosis, esta variable se distribuye de la siguiente manera:\n\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"Image('../input/assets/assets/diagnosisHist.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Image('../input/assets/assets/props.PNG')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"El código para realizar las visualizaciones anteriores puede encontrarse en el archivo DataExploration.R\n\nSe puede observar que la mayoría de imágenes, siendo casi un 50%, en el dataset de entrenamiento son diagnosticadas como “sin retinopatía diabética”, mientras que menos de un 5.3% y 8.1% son clasificadas como “severa” y “proliferativa”, respectivamente; esto puede repercutir en las respuestas que se obtengan con la red neuronal al introducir el test set, ya que podría sesgar la información y clasificar como “sin diagnosis”.\n\nAlgunas de las imágenes para cada diagnóstico son las siguientes:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\nimport os # Para importar las imagenes\nfrom PIL import Image # Para visualizar las imagenes\nimport numpy as np","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['path'] = train_df['id_code'].map(lambda x: os.path.join('../input/aptos2019-blindness-detection/train_images/','{}.png'.format(x)))\ntrain_df['path_gray'] = train_df['id_code'].map(lambda x: os.path.join('../input/transfrom-images/transform_images/','{}.png'.format(x)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### 0 - No DR","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"no_dr = Image.open(train_df[train_df.diagnosis==0].iloc[0].path)\nplt.imshow(np.asarray(no_dr))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### 1 - Mild","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"mild = Image.open(train_df[train_df.diagnosis==1].iloc[0].path)\nplt.imshow(np.asarray(mild))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### 2 - Moderate","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"moderate = Image.open(train_df[train_df.diagnosis==2].iloc[0].path)\nplt.imshow(np.asarray(moderate))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### 3 - Severe","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sev = Image.open(train_df[train_df.diagnosis==3].iloc[0].path)\nplt.imshow(np.asarray(sev))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### 4 - Proliferative","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"prol = Image.open(train_df[train_df.diagnosis==4].iloc[0].path)\nplt.imshow(np.asarray(prol))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Metodología\nSe usarán solo las primeras 611 fotos, por cuestiones de tiempo, como acordado en clase (aunque en clase se comentó que 300 era suficiente)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = train_df[:610]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"diagnosis_labs = pd.read_csv('../input/diagnosis/diagnosis.csv')\ntrain_df_labs = pd.merge(train_df, diagnosis_labs)\ntrain_df_labs[\"diagnosis_n\"].value_counts().plot(kind='bar')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Se puede observar que, ya que los diagnósticos estan distribuidos aleatoriamente en el csv original, escoger los primeros 611 no parece afectar a la distribución.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"### Modificación de las imágenes","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Ver dimensiones de imagen\nim = Image.open(train_df['path'][1])\nwidth, height = im.size\nprint(width,height) \nplt.imshow(np.asarray(im))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Se puede observar que las imagenes son bastante grandes, por lo cual será necesario para empezar, cambiar su tamaño.\n\nPara empezar, creemos nuestros train y test set a partir de train_df. Escogeremos 65% y 35% al azar, respectivamente.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train, test = np.split(train_df.sample(frac=1), [int(.65*len(train_df))])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Ahora, se debe procurar compensar la sobre-representación de los casos sin retinopatía diabética en el dataset de train, ya que esto podría ser un bias que afectaría el cross validation y el test.\n\nPara esto, se hará un oversampling.\nPara referencia, esta es la distribución de nuestro nuevo train set, al escoger una muestra del 65% al azar:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_labs = pd.merge(train, diagnosis_labs)\ntrain_labs[\"diagnosis_n\"].value_counts().plot(kind='bar')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Se puede observar que la distribución de los diagnósticos se sigue manteniendo.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"max_size = train_labs['diagnosis_n'].value_counts().max()\nmin_size = train_labs['diagnosis_n'].value_counts().min()\n\nlst = [train_labs]\nfor class_index, group in train_labs.groupby('diagnosis'):\n   lst.append(group.sample(max_size-len(group), replace=True))\noversampled_train = pd.concat(lst)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"oversampled_train[\"diagnosis_n\"].value_counts().plot(kind='bar')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"no_dr = np.random.choice(train_labs[train_labs.diagnosis==0].index, min_size, replace=False)\nmild = np.random.choice(train_labs[train_labs.diagnosis==1].index, min_size, replace=False)\nmoderate = np.random.choice(train_labs[train_labs.diagnosis==2].index, min_size, replace=False)\nsevere = np.random.choice(train_labs[train_labs.diagnosis==3].index, min_size, replace=False)\nproliferative = np.random.choice(train_labs[train_labs.diagnosis==4].index, min_size, replace=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"undersample_indexes = np.concatenate([no_dr,mild,moderate,severe,proliferative])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"undersampled_train = train_labs.loc[undersample_indexes]\nundersampled_train[\"diagnosis_n\"].value_counts().plot(kind='bar')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Transformaciones y Redes Neuronales\nSe realizarán 2 modelos, uno con el dataset undersampled y el otro oversampled. Para empezar, cargaremos las librerías a utilizar y los datos del test.","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import keras\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten\nfrom keras.layers import Conv2D, MaxPooling2D\nfrom keras.utils import to_categorical\nfrom keras.preprocessing import image\nfrom sklearn.model_selection import train_test_split\nfrom keras.utils import to_categorical\nfrom tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"test_images = []\nfor i in tqdm(range(test.shape[0])):\n    img = image.load_img(test['path_gray'].iloc[i], target_size=(256,256, 1), color_mode=\"grayscale\")\n    img = image.img_to_array(img)\n    img = img/255\n    test_images.append(img)\nX_test = np.array(test_images)\n\ny_test = test['diagnosis'].values\ny_test = to_categorical(y_test)","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}