{"cells":[{"metadata":{"_uuid":"34b6997bb115a11f47a7f54ce9d9052791b2e707","_cell_guid":"c67e806c-e0e6-415b-8cf0-ed92eba5ed37"},"cell_type":"markdown","source":"# Overview\nThe goal is to make a nice retinopathy model by using a pretrained inception v3 as a base and retraining some modified final layers with attention\n\nThis can be massively improved with \n* high-resolution images\n* better data sampling\n* ensuring there is no leaking between training and validation sets, ```sample(replace = True)``` is real dangerous\n* better target variable (age) normalization\n* pretrained models\n* attention/related techniques to focus on areas"},{"metadata":{"_uuid":"ef93395c5e376a163afd509453235ce6951f6b72"},"cell_type":"markdown","source":"## Load Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom keras.applications import inception_v3 as inc_net\n# Display\nfrom IPython.display import Image\nimport matplotlib.pyplot as plt\nimport sklearn\nfrom skimage.segmentation import mark_boundaries\nimport lime\nfrom lime import lime_image\nfrom keras.preprocessing import image\nimport os\nimport shap\nimport keras.backend as K\nfrom keras.applications.vgg16 import preprocess_input","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c163e45042a69905855f7c04a65676e5aca4837b","_cell_guid":"e94de3e7-de1f-4c18-ad1f-c8b686127340","trusted":true},"cell_type":"code","source":"import keras\nfrom keras.models import load_model\nfrom keras.metrics import top_k_categorical_accuracy\ndef top_2_accuracy(in_gt, in_pred):\n    return top_k_categorical_accuracy(in_gt, in_pred, k=2)\nmodel = load_model('../input/model-full/full_retina_model.h5',custom_objects={'top_2_accuracy': top_2_accuracy})\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b736e41fac4caf7ff6a8d177bcf0cd26a457746b"},"cell_type":"code","source":"model.load_weights('../input/weights/retina_weights.best.hdf5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"17eea0257de97a643f64858638ed9a2664f3c266"},"cell_type":"code","source":"base_image_dir = os.path.join('..', 'input', 'diabetic-retinopathy-detection')\nretina_df = pd.read_csv(os.path.join(base_image_dir, 'trainLabels.csv'))\nretina_df['PatientId'] = retina_df['image'].map(lambda x: x.split('_')[0])\nretina_df['path'] = retina_df['image'].map(lambda x: os.path.join(base_image_dir,\n                                                         '{}.jpeg'.format(x)))\nretina_df['exists'] = retina_df['path'].map(os.path.exists)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def transform_img_fn(path_list):\n    '''Transform image so it can be processed by inception.'''\n    out = []\n    for img_path in path_list:\n        img = image.load_img(img_path, target_size=(512, 512))\n        x = image.img_to_array(img)\n        x = np.expand_dims(x, axis=0)\n        x = inc_net.preprocess_input(x)\n        out.append(x)\n    return np.vstack(out)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def retorna_data(classe):\n    dataframe = retina_df[retina_df['level'] == classe]\n    dataframe = dataframe[dataframe['exists'] == True]\n    dataframe['new_index'] = range(len(dataframe))\n    dataframe = dataframe.set_index('new_index')\n    colunas = ['NO-DR','NPDR-LIGHT','NPDR-MODERATE','NPDR-SEVERE','PDR']\n    y = list()\n    for i in range(len(dataframe)):\n        expl = transform_img_fn([dataframe['path'][i]])\n        result = model.predict(expl,batch_size = 32, verbose = True)\n        x = [result[0][0],result[0][1],result[0][2],result[0][3],result[0][4]]\n        y.append(x)\n    return pd.DataFrame(y, columns= colunas)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Case example data NO-DR"},{"metadata":{"trusted":true},"cell_type":"code","source":"retorna_data(0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Case NPDR-LIGHT"},{"metadata":{"trusted":true},"cell_type":"code","source":"retorna_data(1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Case NPDR-MODERATE"},{"metadata":{"trusted":true},"cell_type":"code","source":"retorna_data(2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Case NPDR-SEVERE\t"},{"metadata":{"trusted":true},"cell_type":"code","source":"retorna_data(3)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Case PDR"},{"metadata":{"trusted":true},"cell_type":"code","source":"retorna_data(4)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Testes explicação"},{"metadata":{"trusted":true,"_uuid":"5644f70eceda7d272b96eb2c509494ad597901e3"},"cell_type":"code","source":"amostra = np.ndarray(shape=(50, 512, 512,3),\n                     dtype=np.float32)\ncount = 0\nfor i in range(50):\n    to_explain = retina_df['path'][1]\n    to_explain = transform_img_fn([to_explain])\n    a = model.predict(to_explain,batch_size = 32)\n    for j in range(4):\n        if((a[0][j] * 100) > 85):\n            print(a[0][j])\n            amostra[count] = to_explain\n            count += 1\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5f53210bcc546bbcba7f40024e3108206981f338"},"cell_type":"code","source":"def transform_img_fn2(path_list):\n    '''Transform image so it can be processed by inception.'''\n    out = []\n    for img_path in path_list:\n        img = image.load_img(img_path, target_size=(224, 224))\n        x = image.img_to_array(img)\n        x = np.expand_dims(x, axis=0)\n        x = inc_net.preprocess_input(x)\n        out.append(x)\n    return np.vstack(out)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b4112c67b670f3260be89ec1d322f3f93a14c82b"},"cell_type":"markdown","source":"## DataSet"},{"metadata":{"trusted":true,"_uuid":"b8b922674ef0abd97d59381dc58726cf8d474f31"},"cell_type":"code","source":"to_explain = retina_df['path'][1]\nto_explain = transform_img_fn([to_explain])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"to_explain2 = retina_df['path'][2]\nto_explain2 = transform_img_fn([to_explain2])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3365cdf2cad1127e2c84038ba35e5f3e487e18f3"},"cell_type":"code","source":"test = np.ndarray(shape=(2, 512, 512,3),\n                     dtype=np.float32)\ntest[0] = to_explain\ntest[1] = to_explain2\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a121dc90a8c05e699bf025c4f07c5283999e531e"},"cell_type":"code","source":"amostra = np.ndarray(shape=(5, 512, 512,3),\n                     dtype=np.float32)\nz = 0\nfor i in range(5):\n    x = retina_df['path'][i]\n    x = transform_img_fn([x])\n    amostra[z] = x\n    z += 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8504d4840aca780606a2430429ce5eec36d73c28"},"cell_type":"code","source":"test.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e5683e4b5c8ebbc66ac36d43306d6cd5457e5820"},"cell_type":"code","source":"to_explain.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ee4367ca4bcb47d8970a884251f23520a91c0a04"},"cell_type":"code","source":"def map2layer(x, layer):\n    print(x.shape)\n    feed_dict = dict(zip([model.layers[0].input], [preprocess_input(x.copy())]))\n    #print(feed_dict)\n    return K.get_session().run(model.layers[layer].input, feed_dict)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e7911222c9e70907aa92a8971027e1f289ebce47"},"cell_type":"code","source":"e = shap.DeepExplainer(model,amostra)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eea93cd68d8d1f039bf7adc84ed545775b05db3c","_kg_hide-input":false},"cell_type":"code","source":"e = shap.GradientExplainer(\n    (model.layers[7].input, model.layers[-1].output),\n    map2layer(amostra, 7),\n    local_smoothing=0 # std dev of smoothing noise\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"z = map2layer(amostra, 7)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"z.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = map2layer(test, 7)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"K.clear_session()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1888e4b2c25812831f93834f48499a6ee41e51ac"},"cell_type":"code","source":"shap_values,indexes = e.shap_values(map2layer(test, 7), ranked_outputs=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"28cbb3fc8807014a467e431ee985d30f5cd1b27b"},"cell_type":"code","source":"test = np.ndarray(shape=(2, 512, 512,3),\n                     dtype=np.float32)\ntest[0] = to_explain\ntest[1] = to_explain2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f86830932f22473d0cd7c553fd9d0b727ce71695"},"cell_type":"code","source":"shap_values = e.shap_values(to_explain)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"01cc8e9f872e6c9b649effa13c513c9fa96fc845"},"cell_type":"code","source":"shap.image_plot(shap_values, -to_explain)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f3772b49dd586dd0511d3c52187347126eeceaa5"},"cell_type":"code","source":"index_names = [0,1,2,3,4]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"828915f7091801704e552efd51367a15a4cf4b09"},"cell_type":"code","source":"shap.image_plot(shap_values, to_explain, index_names)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e06738937658c6f168a59d387f050707ce892ad6"},"cell_type":"code","source":"from keras.preprocessing import image\nimg_orig = transform_img_fn([x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fdd2a9ff45495c61e6bc1c0f17d3239628b488aa"},"cell_type":"code","source":"test = list()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e9bdbe10d304341e44185053ece20c015090a5cd"},"cell_type":"code","source":"y = retina_df['path'][7]\ny = transform_img_fn([y])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c0eeba72210cd2bb8fb1117f388415067d422256"},"cell_type":"code","source":"test.append(y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f2681eae9b48c7d0db9ab1cfa13ef5d2e717e947"},"cell_type":"code","source":"c = next(iter(test))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e88287ae1aff7bcb4bae457011143f4749b16607"},"cell_type":"markdown","source":"## Exemplo SHAP"},{"metadata":{"trusted":true,"_uuid":"5d6ef4ef03eec3083617f892cc8652a976bd1aaa"},"cell_type":"code","source":"e = shap.DeepExplainer (model, img_orig)\nshap_values = e.shap_values(c [1 : 4])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a0b4e32d0b54f11acabf6180f3f605e98096b29a"},"cell_type":"code","source":"shap.image_plot (shap_values, - c [1 : 4])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"91902b232a6b467db62b40dcdcdd0f014e5769d9"},"cell_type":"markdown","source":"## Exemplo LIME"},{"metadata":{"trusted":true,"_uuid":"e10b06501704944548bd47b14154a3a24cfee727"},"cell_type":"code","source":"model.predict(img_orig)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b3de8a8ff59c3faabd81d004ee6d5744fb5fc5de"},"cell_type":"code","source":"explainer = lime_image.LimeImageExplainer(verbose=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0dc7ce1b74001fdbee978afad299259667ded64a"},"cell_type":"code","source":"explanation = explainer.explain_instance(img_orig[0], model.predict, top_labels=5, hide_color=0, num_samples=1000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3cc5ad97b0c96ac2b30afedef0a0ba04fbeb56aa"},"cell_type":"code","source":"explanation.top_labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"996060493f1b39f5450c2cf230098199cd542a37"},"cell_type":"code","source":"temp, mask = explanation.get_image_and_mask(0, positive_only=True, num_features=15, hide_rest=False)\nplt.imshow(mark_boundaries(temp / 2 + 0.5, mask))","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}