{"cells":[{"metadata":{"_uuid":"e12dd6bcd4684b1d3968448f813317a8c0ee5442"},"cell_type":"markdown","source":"##  We will follow the general workflow:\n* Visualize data/perform some exploratory data analysis\n* Set up data pipeline and preprocessing\n* Build model\n* Train model\n* Evaluate model\n* Repeat"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"scrolled":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os, sys # modulos do sistema\n\nfrom time import time\n# import lbrary for image manipulation\nimport matplotlib.pyplot as plt   # biblioteca gráfica para gráficos\nimport matplotlib.image as mpimg  # biblioteca gráfica para gráficos\nimport cv2                        # library for image manipulation\n\n# bibliotecas de IA\nfrom skimage.transform import resize\nfrom skimage.io import imsave\nfrom keras.models import Model\nfrom keras.layers import Input, concatenate, Conv2D, MaxPooling2D, Conv2DTranspose\nfrom keras.optimizers import Adam\nfrom keras.callbacks import ModelCheckpoint\nfrom keras import backend as K\nK.set_image_data_format('channels_last')  # TF dimension ordering in this code\n\nprint(os.listdir(\"../input/weights/\"))\nprint(os.listdir('../input/airbus-ship-detection/'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4835c49a3af6b23fd77e8a442d3fe69c736dfc71"},"cell_type":"code","source":"# lendo o arquivo que contem todas as imagens de treinamento e as informações das máscara\ntss = pd.read_csv('../input/airbus-ship-detection/train_ship_segmentations_v2.csv')\ntss.keys()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0641dbc257a795552fac9d3b05f7abbdcd5fd74e"},"cell_type":"code","source":"tss.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a050f93f06eca0b670be8d479ffa8353e91356db"},"cell_type":"markdown","source":"## Get all the files"},{"metadata":{"_uuid":"5f5b9f44c90306a00d287fd9bb810a827aa112a7"},"cell_type":"markdown","source":"## Manipulação dos Dados de Treinamento\n  * 1  train :  1-10000\n  * 2 train :  10000 - 50000"},{"metadata":{"trusted":true,"_uuid":"a4009003dbd6590b64884795227a9c3e284d5e9a"},"cell_type":"code","source":"# PARAMETROS\n\n# teste\n# comeco = 0\n# fim = 10\n\n# ignorado\n# comeco = 230000\n# fim = 270000\n\n# 11 treinanemtno com 10000\ncomeco = 40000\nfim = 80000\n\nEPS = 10\nBS = 32\n\npesos = 'train-12.h5'\n\ntotal = fim-comeco #65515(50%) # 31030(23%) # len(tss['ImageId']) # 131030\n\nimage_rows = 768\nimage_cols = 768\n\nimg_rows = 192\nimg_cols = 192\nsmooth = 1.\n\ndim = 589824 # dimensão maxima da máscara 1d\nprint('total de imagens', total)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3ea17b3c4898940adfac90fcdeb02e81204458c2","_kg_hide-output":true,"_kg_hide-input":false,"scrolled":true},"cell_type":"code","source":"# ------------------------------------------------ #\n# -------- CRIANDO DADOS DE TREINAMENTO ---------- #\n# ------------------------------------------------ #\n\n# selecionar o nome da imagem e ler ela com o cv2, \n# após obter a marcação e gerar a mascara \n# adicionar a imagem e mascara no vertor de array para treinamento\n\n# criando todas as mascaras das imagens\ndef create_train_data():\n    \n    print(''*30)\n    print('criando dados de treinamento')\n    print('-'*30)\n    \n    imgs = np.ndarray((total, img_rows, img_cols), dtype=np.uint8)\n    imgs_mask = np.ndarray((total, img_rows, img_cols), dtype=np.uint8)\n    \n    a = 0 # indice\n    \n    # controlar qais valores do dataframe eu vou ler\n    for i in range(comeco, fim):\n\n        img = cv2.imread('../input/airbus-ship-detection/train_v2/'+tss.iloc[i]['ImageId'], 0) # lendo a imagem em tons de cinza \n        \n        str_mask = tss.iloc[i]['EncodedPixels'] # quando a imagem não possuir embarcação, a mesma passa pra outra \n\n        img_1d = np.zeros((dim),dtype=np.uint8) # cria um vetor 1D \n        \n        if isinstance(str_mask, str): # se for string ela seta a mascara como branca\n\n            str_mask = str_mask.split(' ') # obtem os pares de informações, posição e quantidade de pixels brancos\n            \n            for i in range(1,len(str_mask),2): # setar os valores da máscara\n                for j in range(int(str_mask[i])+1): \n                    position = int(str_mask[i-1])\n                    if position+j < dim: # assim não acessa posições fora do tamanho do array\n                        img_1d[position+j] = 255\n\n        img_2d = np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8) # cria a imagem 2D de fato\n\n        \n        indice = 0\n        for j in range(img.shape[1]): # seta na imagem 2D os valores da imagem 1D\n            for i in range(img.shape[0]):\n                img_2d[i][j] = img_1d[indice]\n                indice += 1\n        \n        # mas antes as imagens são convetidas em arrays        \n        img = np.array([resize(img, (img_cols, img_rows), preserve_range=True)])\n        img_mask = np.array([resize(img_2d, (img_cols, img_rows), preserve_range=True)])\n\n        # as imagens são setadas nos vetores de imagens\n        imgs[a] = img\n        imgs_mask[a] = img_mask\n        \n        if a % 100 == 0:\n            logg = 'Done: {0}/{1} images'.format(a, total) \n            sys.stdout.write('\\r'+logg)\n            #print('Done: {0}/{1} images'.format(a, total))\n            \n        a += 1\n    return imgs, imgs_mask","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3abe5f2c1723544c1f7c4fb114b23e7343e128e8"},"cell_type":"code","source":"def preprocess(imgs):\n    imgs_p = np.ndarray((imgs.shape[0], img_rows, img_cols), dtype=np.uint8)\n    for i in range(imgs.shape[0]):\n        imgs_p[i] = imgs[i]\n        \n    imgs_p = imgs_p[..., np.newaxis]\n    return imgs_p","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8f95ca04453799f7515ae32b64751cee41b69274"},"cell_type":"code","source":"inicio = time()\n# criar os dados de treinamento\nx_train, y_train = create_train_data()\n\nprint(x_train.shape, ' y ', x_train.shape)\n\nprint('pre-processing')\nx_train = preprocess(x_train)\ny_train = preprocess(y_train)\nprint('.')\n\nprint('convert tensor to float32')\nx_train = x_train.astype('float32')\ny_train = y_train.astype('float32')\nprint('.')\n\nprint('normalizando as imagens')\nx_train = x_train / 255.\ny_train = y_train / 255.\nprint('.')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"64d78ae21fb7ef05104c0b89e46322e0739c087c"},"cell_type":"markdown","source":"## Visualize"},{"metadata":{"trusted":true,"_uuid":"62dc1f9a518ab40f14bc00f244063d90d12eea54"},"cell_type":"code","source":"\nfor i in range(5):\n    \n    fig, axs = plt.subplots(1, 2, figsize=(9, 3), sharey=True)\n    \n    axs[0].imshow(x_train[i,:,:,0], cmap='gray')\n    \n    axs[1].imshow(y_train[i,:,:,0], cmap='gray')\n    \nplt.suptitle(\"Examples of Images and their Masks\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8d4b9b574443b5af0640cb5e305778f28fe07c75"},"cell_type":"markdown","source":""},{"metadata":{"trusted":true,"_uuid":"d8e72fede28df8309c56562732917b4859e952be"},"cell_type":"code","source":"# ------------------------------------------------ #\n# ------------ ARQUITETURA DA REDE --------------- #\n# ------------------------------------------------ #\n\ndef get_unet(entrada, weights_path=None):\n    \n    print('entrada da rede = ', entrada)\n    \n    inputs = Input(entrada) # camada de entrada, resolução de imagens em um canal\n    \n    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)\n    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv1)\n    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n\n    conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(pool1)\n    conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv2)\n    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n\n    conv3 = Conv2D(128, (3, 3), activation='relu', padding='same')(pool2)\n    conv3 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv3)\n    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n\n    conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')(pool3)\n    conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv4)\n    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n\n    conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool4)\n    conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv5)\n\n    up6 = concatenate([Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(conv5), conv4], axis=3)\n    conv6 = Conv2D(256, (3, 3), activation='relu', padding='same')(up6)\n    conv6 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv6)\n\n    up7 = concatenate([Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(conv6), conv3], axis=3)\n    conv7 = Conv2D(128, (3, 3), activation='relu', padding='same')(up7)\n    conv7 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv7)\n\n    up8 = concatenate([Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(conv7), conv2], axis=3)\n    conv8 = Conv2D(64, (3, 3), activation='relu', padding='same')(up8)\n    conv8 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv8)\n\n    up9 = concatenate([Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same')(conv8), conv1], axis=3)\n    conv9 = Conv2D(32, (3, 3), activation='relu', padding='same')(up9)\n    conv9 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv9)\n\n    conv10 = Conv2D(1, (1, 1), activation='sigmoid')(conv9)\n\n    model = Model(inputs=[inputs], outputs=[conv10])\n    \n    if weights_path:\n        model.load_weights(weights_path)\n\n    model.compile(optimizer=Adam(lr=1e-5), loss=dice_coef_loss, metrics=[dice_coef])\n\n    return model\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"65c15527d41e5ba88c30466f0ecd261f0453a1b3"},"cell_type":"code","source":"# metricas para avaliar a perda da segmetnação durate o treinamento\nsmooth = 1.\n\ndef dice_coef(y_true, y_pred): \n    y_true_f = K.flatten(y_true)\n    y_pred_f = K.flatten(y_pred)\n    intersection = K.sum(y_true_f * y_pred_f)\n    return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n\n\ndef dice_coef_loss(y_true, y_pred):\n    return -dice_coef(y_true, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"331c26d3e92160c9d684c0e24c17188ec6750265"},"cell_type":"code","source":"model = get_unet(x_train[0].shape,'../input/weights/'+pesos) # carrega os pesos aqui do treinamento anterior, se tiver e ou for melhor\nmodel.summary()\nmodel_checkpoint = ModelCheckpoint('weights.h5', monitor='val_loss', save_best_only=True)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9f5076aa9acdc571f72fca6ced847b08faf6dc04"},"cell_type":"code","source":"print('-'*30)\nprint('Fitting model...')\nprint('-'*30)\nlog = model.fit(x_train, y_train, batch_size=BS, epochs=EPS, verbose=1, shuffle=True,\n              validation_split=0.2,\n              callbacks=[model_checkpoint])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b5866ba2ab8b3cc0761b57daea2b2e21a629d081"},"cell_type":"code","source":"log.history.keys()\nprint('val_loss ........: ', log.history['val_loss'][len(log.history['val_loss'])-1])\nprint('loss ............: ', log.history['loss'][len(log.history['loss'])-1])\nprint('val_dice_coef....: ', log.history['val_dice_coef'][len(log.history['val_dice_coef'])-1])\nprint('dice_coef .......: ', log.history['dice_coef'][len(log.history['dice_coef'])-1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3e9862abe8d29d380da964349ad1ee2dc202c5c4","scrolled":true},"cell_type":"code","source":"fim = time()\n\n# tempo em segundos\ngasto = fim - inicio\n\n# tempo em minutos\ngasto /= 60\n\n# tempo em horas\nhoras = gasto / 60\n\ntitulo = \" Model Loss - Treinamento \"+str(pesos)+\"  \\n \"+str(total)+\" imagens . \"+str(EPS)+\" epocas . \"+str(BS)+\" batch szie \\n Tempo Gasto : %.2f minutos ou %.2f horas \" %(gasto, horas)+\" \\n \"+label_val_loss+\" and \"+label_loss\nlabel_val_loss = 'val_loss %.2f '  %(log.history['val_loss'][len(log.history['val_loss'])-1])\nlabel_loss = 'loss %.2f ' %(log.history['loss'][len(log.history['loss'])-1])\n\nnome_fig = str(pesos)+'_.png'\n\n# ---\n\nplt.plot(log.history['val_loss'], '--go', label='val_loss')\nplt.plot(log.history['loss'], '--ro', label='loss')\n\n# plt.plot(log.history['val_dice_coef'], '--bo', label='val_dice_coef')\n# plt.plot(log.history['dice_coef'], '--yo', label='dice_coef')\n\n\n\nplt.title(titulo)\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(loc='upper center', shadow=True, fontsize='x-large',  bbox_to_anchor=(1.25, 0.7), ncol=1)\nplt.savefig(nome_fig)\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ba162ad0406e5744d8ec34806f1d2073a080411d"},"cell_type":"markdown","source":"# References\n * [Image Segmentation](https://github.com/tensorflow/models/blob/master/samples/outreach/blogs/segmentation_blogpost/image_segmentation.ipynb)\n * [Ultra Nerve Segmentation](https://www.kaggle.com/c/ultrasound-nerve-segmentation/kernels)\n * [jocicmarko](https://github.com/jocicmarko/ultrasound-nerve-segmentation/blob/master/data.py)"},{"metadata":{"trusted":true,"_uuid":"cbde7864eb2975d91d93412a2f16af2fe7208d2f"},"cell_type":"code","source":"","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}