{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!unzip '../input/carvana-image-masking-challenge/train.zip'\n!unzip '../input/carvana-image-masking-challenge/train_masks.zip'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow_datasets as tfds\nimport keras\nimport numpy as np\nimport pandas as pd \nfrom IPython.display import clear_output\nimport matplotlib.pyplot as plt\nimport glob\nfrom PIL import Image\nfrom keras.preprocessing import image\nimport cv2\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install git+https://github.com/tensorflow/examples.git\n!pip install -U tfds-nightly\nfrom tensorflow_examples.models.pix2pix import pix2pix","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def preprocess_image(img,mask,train=True):\n    input_img=cv2.resize(img,(128,128))/255.0\n    input_mask=cv2.resize(mask,(128,128))\n    return input_img,input_mask","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_imgs(name):\n    input_img=cv2.imread('./train/'+name+'.jpg')\n    input_mask=image.img_to_array(Image.open('./train_masks/'+name+'_mask.gif'))\n    input_img,input_mask=preprocess_image(input_img,input_mask)\n    return input_img,input_mask","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_data=[]\ny_data=[]\nimgs_path=glob.glob('./train/*')\nfor i in range(len(imgs_path)):\n    input_img,input_mask=load_imgs(imgs_path[i][8:-4])\n    x_data.append(input_img)\n    y_data.append(input_mask)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_d=np.array(x_data)\ny_d=np.array(y_data)\ntrain_data=int((x_d.shape[0]*0.80))\nx_train=x_d[:train_data]\ny_train=y_d[:train_data]\nx_test=x_d[train_data:]\ny_test=y_d[train_data:]\nprint(x_train.shape,y_train.shape,x_test.shape,y_test.shape)\n\ny_train=y_train[...,np.newaxis]\ny_test=y_test[...,np.newaxis]\nprint(x_train.shape,y_train.shape,x_test.shape,y_test.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Definir modelo"},{"metadata":{},"cell_type":"markdown","source":"Definimos dos salidas a diferenciar, el fondo y el carro, generando una mascara del carro."},{"metadata":{"trusted":true},"cell_type":"code","source":"\nOUTPUT_CHANNELS = 2","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Para definir la red hacemos uso de MobileNetV2, entendimos que este es un modelo que hace uso de la luz presente en imagen para obtener la mayor cantidad de información, la entrada corresponde a las imagenes redimensionandas y rgb."},{"metadata":{"trusted":true},"cell_type":"code","source":"base_model = tf.keras.applications.MobileNetV2(input_shape=[128, 128, 3], include_top=False)\n\n# Use the activations of these layers\nlayer_names = [\n    'block_1_expand_relu',   # 64x64\n    'block_3_expand_relu',   # 32x32\n    'block_6_expand_relu',   # 16x16\n    'block_13_expand_relu',  # 8x8\n    'block_16_project',      # 4x4\n]\nlayers = [base_model.get_layer(name).output for name in layer_names]\n\n# Create the feature extraction model\ndown_stack = tf.keras.Model(inputs=base_model.input, outputs=layers)\n\ndown_stack.trainable = False","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Por medio de upstack se van a concatenar capas a la red, que van a redimensionar la imagen que luego de ser reducidas para obtener la informacion relevante. Pix2Pix es capaz de reconstruir la estructura de la imagen a partir de una dimension menor. (Honestamente no entendimos bien como saber cuantos filtros aplicar y el size del kernel, es decir el 512 y el 3)"},{"metadata":{"trusted":true},"cell_type":"code","source":"up_stack = [\n    #pix2pix.upsample(1024, 3),\n    pix2pix.upsample(512, 3),  # 4x4 -> 8x8\n    pix2pix.upsample(256, 3),  # 8x8 -> 16x16\n    pix2pix.upsample(128, 3),  # 16x16 -> 32x32\n    pix2pix.upsample(64, 3),   # 32x32 -> 64x64\n]\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Al darle mayor número de filtros y tamaño de kernel, el tiempo de entrenamiento de la red, aumenta bastante."},{"metadata":{"trusted":true},"cell_type":"code","source":"def unet_model(output_channels):\n  inputs = tf.keras.layers.Input(shape=[128, 128, 3])\n  x = inputs\n\n  # Downsampling through the model\n  skips = down_stack(x)\n  x = skips[-1]\n  skips = reversed(skips[:-1])\n\n  # Upsampling and establishing the skip connections\n  for up, skip in zip(up_stack, skips):\n    x = up(x)\n    concat = tf.keras.layers.Concatenate()\n    x = concat([x, skip])\n\n  # This is the last layer of the model\n  last = tf.keras.layers.Conv2DTranspose(\n      output_channels, 4, strides=2,\n      padding='same')  #64x64 -> 128x128\n\n  x = last(x)\n\n  return tf.keras.Model(inputs=inputs, outputs=x)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"El modelo en general, extrae las características reduciendo las dimensiones, por lo que la construccion de la mascara se enfoca en volver a dimensionar la imagen?"},{"metadata":{},"cell_type":"markdown","source":"## Entrena el modelo"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = unet_model(OUTPUT_CHANNELS)\nmodel.compile(optimizer='adam',\n              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tf.keras.utils.plot_model(model, show_shapes=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_history = model.fit(x_train,y_train, epochs=1,validation_data=(x_test,y_test))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"El modelo entrenado resultaba obtener unas mascaras bastante similares a las de test, el numero de epocas de entrenamiento lo variamos pero el tiempo de proceso era bastante mayor y aunque la precision aumentaba, nos pareció que llegaba a un punto donde se sobreentrenaba la red. "},{"metadata":{"trusted":true},"cell_type":"code","source":"i=4\npred_mask = model.predict(x_test[i:i+1])\nprint(pred_mask.shape)\ny_pred=np.argmax(pred_mask[0],-1)\ny_pred=y_pred[...,np.newaxis]\nprint(y_pred.shape)\nfig=plt.figure(figsize=(15, 15))\nimg=x_test[i]\ntrue_mask=keras.preprocessing.image.array_to_img(y_test[i])\npred_mask=keras.preprocessing.image.array_to_img(y_pred)\nfiles=[img,true_mask,pred_mask]\nfor i in range(len(files)):\n    plt.subplot(1, len(files) , i+1)\n    plt.imshow((files[i]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}