<jupyter_start><jupyter_text>Clasificación de imágenes con pesos preentrenados y el modelo VGG19<NAME> @emiliothehuman    Procedamos a importar un modelo preentrenado y aplicarlo a una imagen descargada de internet<jupyter_code># Importar cosas necesarias...

import tensorflow as tf
import tensorflow.contrib.keras as keras
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import os
import numpy as np
from PIL import Image
L = keras.layers<jupyter_output><empty_output><jupyter_text>Importemos el modelo VGG19 con los pesos "imagenet" preentrenados. Atención al parámetro include_top = True, que tendremos que alterar en la siguiente práctica<jupyter_code>model = keras.applications.vgg19.VGG19(include_top = True, weights = "imagenet")<jupyter_output>Downloading data from https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels.h5
574717952/574710816 [==============================] - 146s 0us/step<jupyter_text>Echemos un vistazo al modelo:<jupyter_code>model.summary()<jupyter_output>_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 224, 224, 3)       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 112, 112, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 112, 112, 128)     147584    
_________________________________________________________________
block2_poo[...]<jupyter_text>Como vemos, la capa de entrada espera tensores de forma (224, 224, 3) -> (píxels hor, píxels ver, canales rgb)Descarguemos una imagen de internet. Cambia el enlace para descargar la imagen que más te guste. Echa antes un vistazo a la lista de categorías que reconoce este modelo (archivo imagenet1000_clsid_to_human.txt que puedes encontrar en el github del curso) para elegir una imagen con la que vaya a funcionar bien.<jupyter_code>!wget "https://www.theflavorbender.com/wp-content/uploads/2014/09/Simpsons-Doughnuts-4140-700x1057.jpg"
# Pongamos un nombre más amigable
os.rename("Simpsons-Doughnuts-4140-700x1057.jpg", "donut.jpg")<jupyter_output>--2019-04-18 14:54:29--  https://www.theflavorbender.com/wp-content/uploads/2014/09/Simpsons-Doughnuts-4140-700x1057.jpg
Resolving www.theflavorbender.com (www.theflavorbender.com)... 172.16.58.3, 172.16.17.32, fd00:a516:7c1b:17cd:6d81:2137:bd2a:2c5b:558b, ...
Connecting to www.theflavorbender.com (www.theflavorbender.com)|172.16.58.3|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 45719 (45K) [image/jpeg]
Saving to: ‘Simpsons-Doughnuts-4140-700x1057.jpg’

Simpsons-Doughnuts- 100%[===================>]  44.65K  --.-KB/s    in 0.01s   

2019-04-18 14:54:29 (3.67 MB/s) - ‘Simpsons-Doughnuts-4140-700x1057.jpg’ saved [45719/45719]<jupyter_text>Leemos la imagen con Image.open<jupyter_code>img = Image.open('donut.jpg')<jupyter_output><empty_output><jupyter_text>A ver, a ver...<jupyter_code>plt.imshow(img)
print(img.size)<jupyter_output>(700, 1057)<jupyter_text>¡Ups! La imagen no tiene las dimensiones adecuadas (224x224 px). Reescalémosla:<jupyter_code>scaledImg = img.resize((224,224))
plt.imshow(scaledImg)<jupyter_output><empty_output><jupyter_text>Mmmm.... la proporción de aspecto no es cuadrada, y la imagen aparece achatada. En este caso, la imagen no está tan distorsionada como para que la red la clasifique de manera incorrecta, pero por purismo, vamos a quedarnos con un crop central de la imagen:<jupyter_code>squareImg = img.crop((0,200,700,900)).resize((224,224))<jupyter_output><empty_output><jupyter_text>Ahora mucho mejor:<jupyter_code>plt.imshow(squareImg)<jupyter_output><empty_output><jupyter_text>Convirtamos la imagen a tensor (1, 224, 224, 3):<jupyter_code>imdata = np.array(squareImg).reshape(1, 224, 224, 3) # formato (Nº muestras, anchura, altura, canales)<jupyter_output><empty_output><jupyter_text>Apliquemos este tensor al modelo, a ver qué nos (pre)dice:<jupyter_code>np.argmax(model.predict(imdata))<jupyter_output><empty_output><jupyter_text>El modelo asocia la máxima probabilidad a la clase 415. Si consultamos imagenet1000_clsidx_to_labels.txt, veremos que corresponde con la categoría "bakery, bakeshot, bakehouse". Así que lo podemos dar por bueno.Para hacer nuestra vida más fácil, importemos el diccionario de datos (File -> open y súbelo a la carpeta del notebook) y definamos una función auxiliar para ayudarnos a clasificar imágenes:<jupyter_code>import json
categoryNames = eval(open('imagenet1000_clsidx_to_labels.txt', 'r').read())
def Classify(img):
    cat = np.argmax(model.predict(img))
    print(categoryNames[cat])<jupyter_output><empty_output><jupyter_text>Tan sólo tenemos que llamar a Classify dándole como datos de entrada el tensor:<jupyter_code>Classify(imdata)<jupyter_output>bakery, bakeshop, bakehouse
{'fraction_non_alphanumeric': 0.1141552511415525, 'fraction_numerical': 0.06812785388127854, 'mean_word_length': 5.958068614993647, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 52, 'https://': 3, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 3, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '325077', 'license': 'MIT', 'n_tokens_mistral': 2132, 'n_tokens_neox': 1855, 'n_words': 435, 'path': 'CNN/CNNPreentrenada.ipynb', 'repo_name': 'emiliopomares/AdvancedAnalyticsCourse', 'size': '5474'}