Uso de un modelo CNN preentrenado en Keras

Objetivos:

  • Cargar un modelo ResNet50 preentrenado desde Keras Zoo
  • Construir un modelo sin la última capa y calcular representaciones de imágenes
  • Explorar la calidad de las representaciones con t-SNE
  • Reentrenar la última capa en un conjunto de datos de gatos vs. perros

Descargas

images_pascalVOC.zip

img_emb.h5

%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt
import os
from zipfile import ZipFile

if not os.path.exists("images_resize"):
    print('Extracting image files...')
    zf = ZipFile('images_pascalVOC.zip')
    zf.extractall('.')
from keras.applications.resnet50 import ResNet50
from keras.models import Model
from keras.preprocessing import image

model = ResNet50(include_top=True, weights='imagenet')
print(model.summary())
Model: "resnet50"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)         Output Shape          Param #  Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer         │ (None, 224, 224,  │          0 │ -                 │
│ (InputLayer)        │ 3)                │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv1_pad           │ (None, 230, 230,  │          0 │ input_layer[0][0] │
│ (ZeroPadding2D)     │ 3)                │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv1_conv (Conv2D) │ (None, 112, 112,  │      9,472 │ conv1_pad[0][0]   │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv1_bn            │ (None, 112, 112,  │        256 │ conv1_conv[0][0]  │
│ (BatchNormalizatio…64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv1_relu          │ (None, 112, 112,  │          0 │ conv1_bn[0][0]    │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool1_pad           │ (None, 114, 114,  │          0 │ conv1_relu[0][0]  │
│ (ZeroPadding2D)     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ pool1_pool          │ (None, 56, 56,    │          0 │ pool1_pad[0][0]   │
│ (MaxPooling2D)      │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_1_conv │ (None, 56, 56,    │      4,160 │ pool1_pool[0][0]  │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_1_bn   │ (None, 56, 56,    │        256 │ conv2_block1_1_c… │
│ (BatchNormalizatio…64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_1_relu │ (None, 56, 56,    │          0 │ conv2_block1_1_b… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_2_conv │ (None, 56, 56,    │     36,928 │ conv2_block1_1_r… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_2_bn   │ (None, 56, 56,    │        256 │ conv2_block1_2_c… │
│ (BatchNormalizatio…64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_2_relu │ (None, 56, 56,    │          0 │ conv2_block1_2_b… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_0_conv │ (None, 56, 56,    │     16,640 │ pool1_pool[0][0]  │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_3_conv │ (None, 56, 56,    │     16,640 │ conv2_block1_2_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_0_bn   │ (None, 56, 56,    │      1,024 │ conv2_block1_0_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_3_bn   │ (None, 56, 56,    │      1,024 │ conv2_block1_3_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_add    │ (None, 56, 56,    │          0 │ conv2_block1_0_b… │
│ (Add)               │ 256)              │            │ conv2_block1_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block1_out    │ (None, 56, 56,    │          0 │ conv2_block1_add… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_1_conv │ (None, 56, 56,    │     16,448 │ conv2_block1_out… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_1_bn   │ (None, 56, 56,    │        256 │ conv2_block2_1_c… │
│ (BatchNormalizatio…64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_1_relu │ (None, 56, 56,    │          0 │ conv2_block2_1_b… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_2_conv │ (None, 56, 56,    │     36,928 │ conv2_block2_1_r… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_2_bn   │ (None, 56, 56,    │        256 │ conv2_block2_2_c… │
│ (BatchNormalizatio…64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_2_relu │ (None, 56, 56,    │          0 │ conv2_block2_2_b… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_3_conv │ (None, 56, 56,    │     16,640 │ conv2_block2_2_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_3_bn   │ (None, 56, 56,    │      1,024 │ conv2_block2_3_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_add    │ (None, 56, 56,    │          0 │ conv2_block1_out… │
│ (Add)               │ 256)              │            │ conv2_block2_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block2_out    │ (None, 56, 56,    │          0 │ conv2_block2_add… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_1_conv │ (None, 56, 56,    │     16,448 │ conv2_block2_out… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_1_bn   │ (None, 56, 56,    │        256 │ conv2_block3_1_c… │
│ (BatchNormalizatio…64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_1_relu │ (None, 56, 56,    │          0 │ conv2_block3_1_b… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_2_conv │ (None, 56, 56,    │     36,928 │ conv2_block3_1_r… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_2_bn   │ (None, 56, 56,    │        256 │ conv2_block3_2_c… │
│ (BatchNormalizatio…64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_2_relu │ (None, 56, 56,    │          0 │ conv2_block3_2_b… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_3_conv │ (None, 56, 56,    │     16,640 │ conv2_block3_2_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_3_bn   │ (None, 56, 56,    │      1,024 │ conv2_block3_3_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_add    │ (None, 56, 56,    │          0 │ conv2_block2_out… │
│ (Add)               │ 256)              │            │ conv2_block3_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2_block3_out    │ (None, 56, 56,    │          0 │ conv2_block3_add… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_1_conv │ (None, 28, 28,    │     32,896 │ conv2_block3_out… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_1_bn   │ (None, 28, 28,    │        512 │ conv3_block1_1_c… │
│ (BatchNormalizatio…128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_1_relu │ (None, 28, 28,    │          0 │ conv3_block1_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_2_conv │ (None, 28, 28,    │    147,584 │ conv3_block1_1_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_2_bn   │ (None, 28, 28,    │        512 │ conv3_block1_2_c… │
│ (BatchNormalizatio…128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_2_relu │ (None, 28, 28,    │          0 │ conv3_block1_2_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_0_conv │ (None, 28, 28,    │    131,584 │ conv2_block3_out… │
│ (Conv2D)            │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_3_conv │ (None, 28, 28,    │     66,048 │ conv3_block1_2_r… │
│ (Conv2D)            │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_0_bn   │ (None, 28, 28,    │      2,048 │ conv3_block1_0_c… │
│ (BatchNormalizatio…512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_3_bn   │ (None, 28, 28,    │      2,048 │ conv3_block1_3_c… │
│ (BatchNormalizatio…512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_add    │ (None, 28, 28,    │          0 │ conv3_block1_0_b… │
│ (Add)               │ 512)              │            │ conv3_block1_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block1_out    │ (None, 28, 28,    │          0 │ conv3_block1_add… │
│ (Activation)        │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_1_conv │ (None, 28, 28,    │     65,664 │ conv3_block1_out… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_1_bn   │ (None, 28, 28,    │        512 │ conv3_block2_1_c… │
│ (BatchNormalizatio…128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_1_relu │ (None, 28, 28,    │          0 │ conv3_block2_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_2_conv │ (None, 28, 28,    │    147,584 │ conv3_block2_1_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_2_bn   │ (None, 28, 28,    │        512 │ conv3_block2_2_c… │
│ (BatchNormalizatio…128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_2_relu │ (None, 28, 28,    │          0 │ conv3_block2_2_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_3_conv │ (None, 28, 28,    │     66,048 │ conv3_block2_2_r… │
│ (Conv2D)            │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_3_bn   │ (None, 28, 28,    │      2,048 │ conv3_block2_3_c… │
│ (BatchNormalizatio…512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_add    │ (None, 28, 28,    │          0 │ conv3_block1_out… │
│ (Add)               │ 512)              │            │ conv3_block2_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block2_out    │ (None, 28, 28,    │          0 │ conv3_block2_add… │
│ (Activation)        │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_1_conv │ (None, 28, 28,    │     65,664 │ conv3_block2_out… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_1_bn   │ (None, 28, 28,    │        512 │ conv3_block3_1_c… │
│ (BatchNormalizatio…128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_1_relu │ (None, 28, 28,    │          0 │ conv3_block3_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_2_conv │ (None, 28, 28,    │    147,584 │ conv3_block3_1_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_2_bn   │ (None, 28, 28,    │        512 │ conv3_block3_2_c… │
│ (BatchNormalizatio…128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_2_relu │ (None, 28, 28,    │          0 │ conv3_block3_2_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_3_conv │ (None, 28, 28,    │     66,048 │ conv3_block3_2_r… │
│ (Conv2D)            │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_3_bn   │ (None, 28, 28,    │      2,048 │ conv3_block3_3_c… │
│ (BatchNormalizatio…512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_add    │ (None, 28, 28,    │          0 │ conv3_block2_out… │
│ (Add)               │ 512)              │            │ conv3_block3_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block3_out    │ (None, 28, 28,    │          0 │ conv3_block3_add… │
│ (Activation)        │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_1_conv │ (None, 28, 28,    │     65,664 │ conv3_block3_out… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_1_bn   │ (None, 28, 28,    │        512 │ conv3_block4_1_c… │
│ (BatchNormalizatio…128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_1_relu │ (None, 28, 28,    │          0 │ conv3_block4_1_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_2_conv │ (None, 28, 28,    │    147,584 │ conv3_block4_1_r… │
│ (Conv2D)            │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_2_bn   │ (None, 28, 28,    │        512 │ conv3_block4_2_c… │
│ (BatchNormalizatio…128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_2_relu │ (None, 28, 28,    │          0 │ conv3_block4_2_b… │
│ (Activation)        │ 128)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_3_conv │ (None, 28, 28,    │     66,048 │ conv3_block4_2_r… │
│ (Conv2D)            │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_3_bn   │ (None, 28, 28,    │      2,048 │ conv3_block4_3_c… │
│ (BatchNormalizatio…512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_add    │ (None, 28, 28,    │          0 │ conv3_block3_out… │
│ (Add)               │ 512)              │            │ conv3_block4_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv3_block4_out    │ (None, 28, 28,    │          0 │ conv3_block4_add… │
│ (Activation)        │ 512)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_1_conv │ (None, 14, 14,    │    131,328 │ conv3_block4_out… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_1_bn   │ (None, 14, 14,    │      1,024 │ conv4_block1_1_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_1_relu │ (None, 14, 14,    │          0 │ conv4_block1_1_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_2_conv │ (None, 14, 14,    │    590,080 │ conv4_block1_1_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_2_bn   │ (None, 14, 14,    │      1,024 │ conv4_block1_2_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_2_relu │ (None, 14, 14,    │          0 │ conv4_block1_2_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_0_conv │ (None, 14, 14,    │    525,312 │ conv3_block4_out… │
│ (Conv2D)            │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_3_conv │ (None, 14, 14,    │    263,168 │ conv4_block1_2_r… │
│ (Conv2D)            │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_0_bn   │ (None, 14, 14,    │      4,096 │ conv4_block1_0_c… │
│ (BatchNormalizatio…1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_3_bn   │ (None, 14, 14,    │      4,096 │ conv4_block1_3_c… │
│ (BatchNormalizatio…1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_add    │ (None, 14, 14,    │          0 │ conv4_block1_0_b… │
│ (Add)               │ 1024)             │            │ conv4_block1_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block1_out    │ (None, 14, 14,    │          0 │ conv4_block1_add… │
│ (Activation)        │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_1_conv │ (None, 14, 14,    │    262,400 │ conv4_block1_out… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_1_bn   │ (None, 14, 14,    │      1,024 │ conv4_block2_1_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_1_relu │ (None, 14, 14,    │          0 │ conv4_block2_1_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_2_conv │ (None, 14, 14,    │    590,080 │ conv4_block2_1_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_2_bn   │ (None, 14, 14,    │      1,024 │ conv4_block2_2_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_2_relu │ (None, 14, 14,    │          0 │ conv4_block2_2_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_3_conv │ (None, 14, 14,    │    263,168 │ conv4_block2_2_r… │
│ (Conv2D)            │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_3_bn   │ (None, 14, 14,    │      4,096 │ conv4_block2_3_c… │
│ (BatchNormalizatio…1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_add    │ (None, 14, 14,    │          0 │ conv4_block1_out… │
│ (Add)               │ 1024)             │            │ conv4_block2_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block2_out    │ (None, 14, 14,    │          0 │ conv4_block2_add… │
│ (Activation)        │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_1_conv │ (None, 14, 14,    │    262,400 │ conv4_block2_out… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_1_bn   │ (None, 14, 14,    │      1,024 │ conv4_block3_1_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_1_relu │ (None, 14, 14,    │          0 │ conv4_block3_1_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_2_conv │ (None, 14, 14,    │    590,080 │ conv4_block3_1_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_2_bn   │ (None, 14, 14,    │      1,024 │ conv4_block3_2_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_2_relu │ (None, 14, 14,    │          0 │ conv4_block3_2_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_3_conv │ (None, 14, 14,    │    263,168 │ conv4_block3_2_r… │
│ (Conv2D)            │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_3_bn   │ (None, 14, 14,    │      4,096 │ conv4_block3_3_c… │
│ (BatchNormalizatio…1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_add    │ (None, 14, 14,    │          0 │ conv4_block2_out… │
│ (Add)               │ 1024)             │            │ conv4_block3_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block3_out    │ (None, 14, 14,    │          0 │ conv4_block3_add… │
│ (Activation)        │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_1_conv │ (None, 14, 14,    │    262,400 │ conv4_block3_out… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_1_bn   │ (None, 14, 14,    │      1,024 │ conv4_block4_1_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_1_relu │ (None, 14, 14,    │          0 │ conv4_block4_1_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_2_conv │ (None, 14, 14,    │    590,080 │ conv4_block4_1_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_2_bn   │ (None, 14, 14,    │      1,024 │ conv4_block4_2_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_2_relu │ (None, 14, 14,    │          0 │ conv4_block4_2_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_3_conv │ (None, 14, 14,    │    263,168 │ conv4_block4_2_r… │
│ (Conv2D)            │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_3_bn   │ (None, 14, 14,    │      4,096 │ conv4_block4_3_c… │
│ (BatchNormalizatio…1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_add    │ (None, 14, 14,    │          0 │ conv4_block3_out… │
│ (Add)               │ 1024)             │            │ conv4_block4_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block4_out    │ (None, 14, 14,    │          0 │ conv4_block4_add… │
│ (Activation)        │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_1_conv │ (None, 14, 14,    │    262,400 │ conv4_block4_out… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_1_bn   │ (None, 14, 14,    │      1,024 │ conv4_block5_1_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_1_relu │ (None, 14, 14,    │          0 │ conv4_block5_1_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_2_conv │ (None, 14, 14,    │    590,080 │ conv4_block5_1_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_2_bn   │ (None, 14, 14,    │      1,024 │ conv4_block5_2_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_2_relu │ (None, 14, 14,    │          0 │ conv4_block5_2_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_3_conv │ (None, 14, 14,    │    263,168 │ conv4_block5_2_r… │
│ (Conv2D)            │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_3_bn   │ (None, 14, 14,    │      4,096 │ conv4_block5_3_c… │
│ (BatchNormalizatio…1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_add    │ (None, 14, 14,    │          0 │ conv4_block4_out… │
│ (Add)               │ 1024)             │            │ conv4_block5_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block5_out    │ (None, 14, 14,    │          0 │ conv4_block5_add… │
│ (Activation)        │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_1_conv │ (None, 14, 14,    │    262,400 │ conv4_block5_out… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_1_bn   │ (None, 14, 14,    │      1,024 │ conv4_block6_1_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_1_relu │ (None, 14, 14,    │          0 │ conv4_block6_1_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_2_conv │ (None, 14, 14,    │    590,080 │ conv4_block6_1_r… │
│ (Conv2D)            │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_2_bn   │ (None, 14, 14,    │      1,024 │ conv4_block6_2_c… │
│ (BatchNormalizatio…256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_2_relu │ (None, 14, 14,    │          0 │ conv4_block6_2_b… │
│ (Activation)        │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_3_conv │ (None, 14, 14,    │    263,168 │ conv4_block6_2_r… │
│ (Conv2D)            │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_3_bn   │ (None, 14, 14,    │      4,096 │ conv4_block6_3_c… │
│ (BatchNormalizatio…1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_add    │ (None, 14, 14,    │          0 │ conv4_block5_out… │
│ (Add)               │ 1024)             │            │ conv4_block6_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv4_block6_out    │ (None, 14, 14,    │          0 │ conv4_block6_add… │
│ (Activation)        │ 1024)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_1_conv │ (None, 7, 7, 512) │    524,800 │ conv4_block6_out… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_1_bn   │ (None, 7, 7, 512) │      2,048 │ conv5_block1_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_1_relu │ (None, 7, 7, 512) │          0 │ conv5_block1_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_2_conv │ (None, 7, 7, 512) │  2,359,808 │ conv5_block1_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_2_bn   │ (None, 7, 7, 512) │      2,048 │ conv5_block1_2_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_2_relu │ (None, 7, 7, 512) │          0 │ conv5_block1_2_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_0_conv │ (None, 7, 7,      │  2,099,200 │ conv4_block6_out… │
│ (Conv2D)            │ 2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_3_conv │ (None, 7, 7,      │  1,050,624 │ conv5_block1_2_r… │
│ (Conv2D)            │ 2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_0_bn   │ (None, 7, 7,      │      8,192 │ conv5_block1_0_c… │
│ (BatchNormalizatio…2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_3_bn   │ (None, 7, 7,      │      8,192 │ conv5_block1_3_c… │
│ (BatchNormalizatio…2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_add    │ (None, 7, 7,      │          0 │ conv5_block1_0_b… │
│ (Add)               │ 2048)             │            │ conv5_block1_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block1_out    │ (None, 7, 7,      │          0 │ conv5_block1_add… │
│ (Activation)        │ 2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_1_conv │ (None, 7, 7, 512) │  1,049,088 │ conv5_block1_out… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_1_bn   │ (None, 7, 7, 512) │      2,048 │ conv5_block2_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_1_relu │ (None, 7, 7, 512) │          0 │ conv5_block2_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_2_conv │ (None, 7, 7, 512) │  2,359,808 │ conv5_block2_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_2_bn   │ (None, 7, 7, 512) │      2,048 │ conv5_block2_2_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_2_relu │ (None, 7, 7, 512) │          0 │ conv5_block2_2_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_3_conv │ (None, 7, 7,      │  1,050,624 │ conv5_block2_2_r… │
│ (Conv2D)            │ 2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_3_bn   │ (None, 7, 7,      │      8,192 │ conv5_block2_3_c… │
│ (BatchNormalizatio…2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_add    │ (None, 7, 7,      │          0 │ conv5_block1_out… │
│ (Add)               │ 2048)             │            │ conv5_block2_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block2_out    │ (None, 7, 7,      │          0 │ conv5_block2_add… │
│ (Activation)        │ 2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_1_conv │ (None, 7, 7, 512) │  1,049,088 │ conv5_block2_out… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_1_bn   │ (None, 7, 7, 512) │      2,048 │ conv5_block3_1_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_1_relu │ (None, 7, 7, 512) │          0 │ conv5_block3_1_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_2_conv │ (None, 7, 7, 512) │  2,359,808 │ conv5_block3_1_r… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_2_bn   │ (None, 7, 7, 512) │      2,048 │ conv5_block3_2_c… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_2_relu │ (None, 7, 7, 512) │          0 │ conv5_block3_2_b… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_3_conv │ (None, 7, 7,      │  1,050,624 │ conv5_block3_2_r… │
│ (Conv2D)            │ 2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_3_bn   │ (None, 7, 7,      │      8,192 │ conv5_block3_3_c… │
│ (BatchNormalizatio…2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_add    │ (None, 7, 7,      │          0 │ conv5_block2_out… │
│ (Add)               │ 2048)             │            │ conv5_block3_3_b… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv5_block3_out    │ (None, 7, 7,      │          0 │ conv5_block3_add… │
│ (Activation)        │ 2048)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ avg_pool            │ (None, 2048)      │          0 │ conv5_block3_out… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ predictions (Dense) │ (None, 1000)      │  2,049,000 │ avg_pool[0][0]    │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 25,636,712 (97.80 MB)
 Trainable params: 25,583,592 (97.59 MB)
 Non-trainable params: 53,120 (207.50 KB)
None

Clasificación de una imagen

  • Abrir una imagen, preprocesarla y construir un batch de 1 imagen
  • Usar el modelo para clasificar esa imagen
  • Decodificar las predicciones usando decode_predictions de Keras

Notas:

  • Se puede utilizar preprocess_input para el preprocesamiento de la imagen
  • Probar el código con "images_resize/000007.jpg"
import numpy as np
import matplotlib.pyplot as plt
from keras.applications.imagenet_utils import preprocess_input, decode_predictions
from PIL import Image
from imageio.v2 import imread

path = "images_resize/000007.jpg"

# Read image using imageio
img = imread(path)
plt.imshow(img)

# Resize image using PIL
img_pil = Image.fromarray(img)
img_resized = img_pil.resize((224, 224))
img = np.array(img_resized).astype("float32")

# Add a batch dimension
img_batch = preprocess_input(img[np.newaxis])

predictions = model.predict(img_batch)
decoded_predictions = decode_predictions(predictions)

for s, name, score in decoded_predictions[0]:
    print(name, score)
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 713ms/step

convertible 0.9606545

beach_wagon 0.014514458

sports_car 0.011048748

grille 0.0050838953

car_wheel 0.0031563553

Cálculo de la representación de una imagen

from keras.applications.resnet50 import ResNet50
from keras.models import Model
from keras.preprocessing import image

model = ResNet50(include_top=False, weights='imagenet')
input = model.input
output = model.output
base_model = Model(input, output)
representation = base_model.predict(img_batch)
print("shape of representation:", representation.shape)
print("proportion of zero valued axis: %0.3f" % np.mean(representation[0]==0))
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 663ms/step

shape of representation: (1, 7, 7, 2048)

proportion of zero valued axis: 0.852

Calcular las representaciones de todas las imágenes puede ser un proceso costoso. Normalmente, esto se realiza utilizando grandes batches en una GPU.

Para la siguiente parte, utilizaremos representaciones precalculadas guardadas en formato h5. Esto se realiza utilizando el script process_images.py.

import os
paths = ["images_resize/" + path for path in sorted(os.listdir("images_resize/"))]
import h5py

# Load pre-calculated representations
h5f = h5py.File('img_emb.h5','r')
out_tensors = h5f['img_emb'][:]
h5f.close()

Las representaciones son densas.

# Proportion of zeros in the vector of the first image:
print("proportion of zeros (first image):", np.mean(out_tensors[0] == 0.0))

# Proportion of negative values in the full representation tensor
print("proportion of strictly negative values:", np.mean(out_tensors < 0.0))

# For all representations:
plt.hist(np.mean(out_tensors == 0.0, axis=1))
plt.title("Fraction of zero values per image vector");

# These 0 values come from the different ReLU units.
# They propagate through the layers, and there can be many.
# If a network has too many of them, a lot of computation
# / memory is wasted.
proportion of zeros (first image): 0.15380859375
proportion of strictly negative values: 0.0

from sklearn.manifold import TSNE

img_emb_tsne = TSNE(perplexity=30).fit_transform(out_tensors)
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 10))
plt.scatter(img_emb_tsne[:, 0], img_emb_tsne[:, 1]);
plt.xticks(()); plt.yticks(());
plt.show()

Otra visualización de los embeddings en el espacio generado con TSNE.

import matplotlib
import matplotlib.pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
from PIL import Image
from imageio.v2 import imread


def imscatter(x, y, paths, ax=None, zoom=1, linewidth=0):
    if ax is None:
        ax = plt.gca()
    x, y = np.atleast_1d(x, y)
    artists = []
    for x0, y0, p in zip(x, y, paths):
        try:
            im = imread(p)
        except:
            print(p)
            continue
        # Resize image using PIL
        img_pil = Image.fromarray(im)
        img_resized = img_pil.resize((224, 224))
        im = np.array(img_resized)

        im = OffsetImage(im, zoom=zoom)
        ab = AnnotationBbox(im, (x0, y0), xycoords='data',
                            frameon=True, pad=0.1, 
                            bboxprops=dict(edgecolor='red',
                                           linewidth=linewidth))
        artists.append(ax.add_artist(ab))
    ax.update_datalim(np.column_stack([x, y]))
    ax.autoscale()
    return artists
fig, ax = plt.subplots(figsize=(50, 50))
imscatter(img_emb_tsne[:, 0], img_emb_tsne[:, 1], paths, zoom=0.5, ax=ax)
plt.savefig('tsne.png')

Búsqueda de imágenes similares

def display(img):
    plt.figure()
    img = imread(img)
    plt.imshow(img)
idx = 57

def most_similar(idx, top_n=5):
    dists = np.linalg.norm(out_tensors - out_tensors[idx], axis = 1)
    sorted_dists = np.argsort(dists)
    return sorted_dists[:top_n]

sim = most_similar(idx)
[display(paths[s]) for s in sim];

Clasificación mediante Vecinos Más Cercanos

Usando estas representaciones, es posible construir un clasificador de vecinos más cercanos. Sin embargo, las representaciones fueron aprendidas en ImageNet, que contiene imágenes centradas. Cuando introducimos imágenes de PascalVOC, se asemejan más a entradas plausibles de un sistema del mundo real.

La siguiente sección explora esta posibilidad calculando el histograma de similitudes entre una imagen y las demás.

out_norms = np.linalg.norm(out_tensors, axis=1, keepdims=True)
normed_out_tensors = out_tensors / out_norms
item_idx = 208
dists_to_item = np.linalg.norm(out_tensors - out_tensors[item_idx], axis=1)
cos_to_item = np.dot(normed_out_tensors, normed_out_tensors[item_idx]) 
plt.hist(cos_to_item, bins=200)
display(paths[item_idx])

Al ver el histograma de similitudes anterior, se aprecia que no existe una separación clara de los límites entre clases.

Con un conjunto de datos etiquetado, incluso con muy pocas etiquetas por clase, sería posible:
- construir un modelo de k-Vecinos Más Cercanos,
- construir un modelo de clasificación como una SVM u otro.

items = np.where(cos_to_item > 0.44)
print(items)
[display(paths[s]) for s, _ in zip(items[0], range(10))];
(array([  4,   9,  12,  60,  82, 151, 170, 186, 187, 205, 208, 225, 252,
       265, 274, 280, 310, 330, 331, 355, 385, 391, 397, 400, 420, 435,
       474, 486, 490]),)