wp-plugin-bluehost
domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init
action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home1/spotsail/public_html/martra/wp-includes/functions.php on line 6114En el primer post de preparar la certificaci\u00f3n de TensorFlow Developer<\/a>, vimos el notebook preparado para solucionar un problema de clasificaci\u00f3n de im\u00e1genes multiples usando el dataset Fashion MNIST que viene con Tensorflow. <\/p>\n\n\n\n En el notebook actual voy a usar un Dataset muy conocido, el de gatos y perros de Microsoft, opara solucionar un problema de clasificaci\u00f3n binaria. El Dataset muy diferente al usado en el notebook anterior. No tan solo por el tama\u00f1o de las im\u00e1genes. Este debe descargarse un fichero .zip, descomprirlo en el disco y cargar las imagines usando un ImageDataGenerator. Una t\u00e9cnica que no se vio en el ejemplo anterior. <\/p>\n\n\n\n (2) Building and training neural network models using TensorFlow 2.x<\/strong> (3) Image classification He intentado cubrir todas las marcadas en amarillo en el Notebook IMAGERecog.ipynb<\/a> disponible en el repositorio de GitHub<\/a> donde est\u00e1n todos los notebooks preparados para el examen de TensorFlow Developer. <\/p>\n\n\n\n El notebook esta dividido en diferentes secciones. Primero se cargan las librer\u00edas necesarias y los datos. Se crea la estructura. Despu\u00e9s se definen funciones gen\u00e9ricas, los modelos. A partir de aqu\u00ed se hace el aprendizaje de los diferentes modelos, con y sin data augmentation. En el ultimo apartado se usan dos procesos diferentes de Transfer Learning, usando los modelos prentrenados InceptionV3 y VGG16. <\/p>\n\n\n\n Se importan las t\u00edpicas librer\u00edas, se define una semilla para que los datos se repartan siempre igual en todas las ejecuciones. Importo dos optimizadores, por que he realizado pruebas con ambos, aunque me gusta m\u00e1s c\u00f3mo funciona Adam. <\/p>\n\n\n\n Se importa ImageDataGenerator que se utiliza para trabajar con el Dataset. <\/p>\n\n\n\n Obtenemos el fichero .zip. Hay que recalcar que el c\u00f3digo funciona tanto en Google Colab como en un notebook Jupyter en el disco local. Nos deja el fichero .zip en el directorio \/tmp\/<\/p>\n\n\n\n Para descomprimirlo importamos zipfile, y no hay ning\u00fan secreto. el zip viene con las imagenes en dos directorios: <\/p>\n\n\n\n Tendremos que pasarlo de estos dos directorios a otros para tener datos de entreno y datos de validaci\u00f3n. <\/p>\n\n\n\n La estructura de directorios se debe crear en el disco, ya sea en el que nos monta de forma temporal Colab, como en el nuestro. <\/p>\n\n\n\n La funci\u00f3n mkdir devuelve una excepci\u00f3n en caso de que el directorio ya est\u00e9 creado, por eso lo he puesto dentro de un bloque try y he ignorado la excepci\u00f3n. <\/p>\n\n\n\n Con los directorios ya creados podemos copiar las im\u00e1genes, para ello tengo una funci\u00f3n que recibe los directorios origen, los destino y el n\u00famero de im\u00e1genes que quiero usar como validadoras. <\/p>\n\n\n\n La llamada a la funci\u00f3n es muy sencilla: <\/p>\n\n\n\n La llamada a la funci\u00f3n nos devuelve los datos divididos en dos arrays, uno para cada categor\u00eda, pero no es lo importante. Lo que realmente ha hecho es dividir las im\u00e1genes en los cuatro directorios para poder crear datos de entreno y datos de validaci\u00f3n partiendo del directorio en el que se han situado. <\/p>\n\n\n\n Son las funciones gen\u00e9ricas, usadas para imprimir gr\u00e1ficos, o tratar los datos. Muchas de ellas compartidas entre diferentes notebooks. <\/p>\n\n\n\n Aqu\u00ed se preparan los juegos de datos, el de training y el de validation. Usando ImageDataGenerator<\/em><\/strong> se normalizan las im\u00e1genes. Acto seguido con flow_from_directory<\/em><\/strong> se cargan las im\u00e1genes. Le podemos indicar el target size, pera que todas tengan el mismo, debe coincidir con el shape de entrada de nuestro modelo. <\/p>\n\n\n\n La funci\u00f3n devuelvo los dos juegos de datos. <\/p>\n\n\n\n Esta funci\u00f3n nos crea un gr\u00e1fico comparando el loss y el accuracy del history de la ejecuci\u00f3n del modelo que le pasemos. <\/p>\n\n\n\n Los modelos los he puesto todos dentro de una funci\u00f3n en lugar de irlos creando por el notebook. Me facilita la vida para compararlos, buscarlos o editarlos. como pode\u00eds ver hay dos modelos y son todos muy sencillos. <\/p>\n\n\n\n Tenemos un modelo con una sola capa convolucional y despu\u00e9s otro con tres capas convolucionales. Cada capa convolutional se acompa\u00f1a de una capa MaxPooling2D. <\/p>\n\n\n\n Los dos siguientes modelos son exactamente los mismos pero incorporando capas de Dropout detr\u00e1s de la capa MaxPooling2D. <\/p>\n\n\n\n Es un modelo muy simple, tan solo una capa convolucional, una de MaxPooling2D y la capa densa con 128 neurones. <\/p>\n\n\n\n Resultados: <\/p>\n\n\n\n 6s 180ms\/step – loss: 0.1124 – accuracy: 0.9857 – val_loss: 1.4532 – val_accuracy: 0.8167<\/p>\n\n\n\n 84s 418ms\/step – loss: 0.3824 – accuracy: 0.8318 – val_loss: 0.3082 – val_accuracy: 0.8762Con Data Augmentation<\/sup><\/p>\n\n\n\n Como es normal, el modelo tiene un gran problema de overfitting, que se ve solucionado parcialmente al usar Image Augmentation. <\/p>\n\n\n\nPuntos cubiertos del examen TensorFlow Developer en el notebook. <\/h3>\n\n\n\n
\u274f Build, compile and train machine learning (ML) models using TensorFlow.
\u274f Preprocess data to get it ready for use in a model.<\/mark>
\u274f Use models to predict results.
\u274f Build sequential models with multiple layers.<\/mark>
\u274f Build and train models for binary classification.<\/mark>
\u274f Build and train models for multi-class categorization.
\u274f Plot loss and accuracy of a trained model.<\/mark>
\u274f Identify strategies to prevent overfitting, including augmentation and dropout.
\u274f Use pretrained models (transfer learning).<\/mark>
\u274f Extract features from pre-trained models.
\u274f Ensure that inputs to a model are in the correct shape.
\u274f Ensure that you can match test data to the input shape of a neural network.
\u274f Ensure you can match output data of a neural network to specified input shape for test data.
\u274f Understand batch loading of data.<\/mark>
\u274f Use callbacks to trigger the end of training cycles.
\u274f Use datasets from different sources.
\u274f Use datasets in different formats, including json and csv.
\u274f Use datasets from tf.data.datasets.<\/p>\n\n\n\n
<\/strong>\u274f Define Convolutional neural networks with Conv2D and pooling layers.
\u274f Build and train models to process real-world image datasets.
\u274f Understand how to use convolutions to improve your neural network.
\u274f Use real-world images in different shapes and sizes..
\u274f Use image augmentation to prevent overfitting.
\u274f Use ImageDataGenerator.
\u274f Understand how ImageDataGenerator labels images based on the directory structure.<\/mark><\/p>\n\n\n\nContenido y estructura del notebook. <\/h3>\n\n\n\n
Importar librer\u00edas y datos. <\/h4>\n\n\n\n
#First steep is import the libraries. \nimport tensorflow as tf\ntf.random.set_seed(42)\n#Numpy is a lybrary that allow us to work with arrays. \nimport numpy as np\n#keras is an open source neural networks lybrary writted in python that run's in varios frameworks, TensorFlow included. \nfrom tensorflow import keras\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nfrom tensorflow.keras.optimizers import RMSprop\nfrom tensorflow.keras.optimizers import Adam\n\nprint (tf.__version__)\n \ngEpochs=30 <\/pre>\n\n\n\n
#obtain the data from microsoft.com\n#the same dataset is available in kaggle but with a different organization\n#https:\/\/www.kaggle.com\/competitions\/dogs-vs-cats\/data\n\n#If it dosn't run be sure to have wget installed in your local machine. It works fine in Colab. \n\n!wget --no-check-certificate \\\nhttps:\/\/download.microsoft.com\/download\/3\/E\/1\/3E1C3F21-ECDB-4869-8368-6DEBA77B919F\/kagglecatsanddogs_5340.zip \\-O \/tmp\/catsvsdogs.zip<\/pre>\n\n\n\n
#unzip the data\nimport zipfile\ncvr_zip_file = '\/tmp\/catsvsdogs.zip'\nzipmem = zipfile.ZipFile(cvr_zip_file)\nzipmem.extractall('\/tmp\/catsvsdogs')\nzipmem.close()<\/pre>\n\n\n\n
dira=<\/strong>\"\/tmp\/catsvsdogs\/PetImages\/Cat\/\" \ndirb=<\/strong>\"\/tmp\/catsvsdogs\/PetImages\/Dog\/\" <\/pre>\n\n\n\n
destDirTraina=<\/strong>'\/tmp\/datacvd\/train\/cats\/' \ndestDirTrainb=<\/strong>'\/tmp\/datacvd\/train\/dogs\/'\ndestDirVala=<\/strong>'\/tmp\/datacvd\/validation\/cats\/' \ndestDirValb=<\/strong>'\/tmp\/datacvd\/validation\/dogs\/'\ndirTrain=<\/strong>'\/tmp\/datacvd\/train\/'\ndirVal=<\/strong>'\/tmp\/datacvd\/validation\/'<\/pre>\n\n\n\n
#create the directory structure\nimport os\n\n#we need a try block, because it fails when the directories already exist. \ntry:\n os.mkdir('\/tmp\/datacvd')\n os.mkdir('\/tmp\/datacvd\/train')\n os.mkdir('\/tmp\/datacvd\/validation')\n os.mkdir('\/tmp\/datacvd\/train\/cats')\n os.mkdir('\/tmp\/datacvd\/train\/dogs')\n os.mkdir('\/tmp\/datacvd\/validation\/cats')\n os.mkdir('\/tmp\/datacvd\/validation\/dogs')\nexcept:\n pass<\/pre>\n\n\n\n
#we need 4 datasets, two for training the model and two for validate or test the model. \n#to classify the images in this dataset we can move it from their original directories to \n#a new ones with the correct structure. \n\ndef getimagesfromdir(dira=\"\", dirb=\"\", destDirTraina=\"\", destDirTrainb=\"\", destDirVala=\"\", destDirValb=\"\", NumVal=100):\n from shutil import copyfile\n\n #this array contents all the images to move\/copy\n imagesA=[]\n imagesB=[]\n\n for imagename in os.listdir(dira):\n imageCat = dira + imagename\n if (os.path.getsize(imageCat)) > 0:\n imagesA.append(imagename)\n\n for imagename in os.listdir(dirb):\n imageDog = dirb + imagename\n if (os.path.getsize(imageDog)) > 0:\n imagesB.append(imagename)\n\n\n counterImage = 0\n for imagename in imagesA:\n if counterImage < 2000:\n copyfile(dira + imagename, destDirVala+imagename)\n else:\n copyfile(dira + imagename, destDirTraina+imagename)\n counterImage +=1\n\n counterImage = 0\n for imagename in imagesB:\n if counterImage < 2000:\n copyfile(dirb + imagename, destDirValb+imagename)\n else:\n copyfile(dirb + imagename, destDirTrainb+imagename)\n counterImage +=1\n\n print(len(os.listdir(destDirValb)))\n print(len(os.listdir(destDirTrainb)))\n print(len(os.listdir(destDirVala)))\n print(len(os.listdir(destDirTraina)))\n return imagesA, imagesB<\/pre>\n\n\n\n
imagesCats, imagesDogs = getimagesfromdir(dira=dira, \n dirb=dirb, \n destDirTraina=destDirTraina, \n destDirTrainb=destDirTrainb,\n destDirVala=destDirVala, \n destDirValb=destDirValb,\n NumVal=2000)<\/pre>\n\n\n\n
Funciones del Notebook. <\/h4>\n\n\n\n
def SimpleDataGenerator():\n #TRAIN Dataset\n #Normalize the images\n train_idg = ImageDataGenerator(rescale=1\/255)\n train_data = train_idg.flow_from_directory(\n '\/tmp\/datacvd\/train', \n target_size = (150, 150), \n batch_size = 105, \n class_mode='binary'\n )\n #VALIDATION Dataset\n val_idg = ImageDataGenerator(rescale=1\/255)\n val_data = val_idg.flow_from_directory(\n '\/tmp\/datacvd\/validation', \n target_size = (150, 150), \n batch_size = 100, \n class_mode='binary'\n )\n return train_data, val_data<\/pre>\n\n\n\n
#Print accuracy & val_accura vs loss & val_loss \n\ndef plot_loss_acc(history):\n '''Plots the training and validation loss and accuracy from a history object'''\n acc = history.history['accuracy']\n val_acc = history.history['val_accuracy']\n loss = history.history['loss']\n val_loss = history.history['val_loss']\n\n epochs = range(len(acc))\n\n plt.plot(epochs, acc, 'bo-', label='Training accuracy')\n plt.plot(epochs, val_acc, 'go-', label='Validation accuracy')\n plt.title('Training and validation accuracy')\n plt.legend()\n\n plt.figure()\n\n plt.plot(epochs, loss, 'bo-', label='Training Loss')\n plt.plot(epochs, val_loss, 'go-', label='Validation Loss')\n plt.title('Training and validation loss')\n plt.legend()\n\n plt.show()<\/pre>\n\n\n\n
Modelos. <\/h4>\n\n\n\n
def get_model(kindmodel):\n switcher = {\n\n #it's a minimal model for images, with just an Convolutionatl layer and a MaxPooling layer\n 0: tf.keras.models.Sequential([\n tf.keras.layers.Conv2D(16, (4,4), activation=\"relu\", input_shape=(150, 150, 3)),\n tf.keras.layers.MaxPooling2D(2,2), \n tf.keras.layers.Flatten(), \n tf.keras.layers.Dense(128, activation=\"relu\"), \n tf.keras.layers.Dense(1, activation=\"sigmoid\")]),\n #keeping it simple just add more convolutional anv maxpooling layers\n #es incluso menos pesado que el anterior, gracias a las capas de maxpooling\n 1: tf.keras.models.Sequential([\n tf.keras.layers.Conv2D(16, (4,4), activation=\"relu\", input_shape=(150, 150, 3)),\n tf.keras.layers.MaxPooling2D(2,2), \n tf.keras.layers.Conv2D(32, (4,4), activation=\"relu\"),\n tf.keras.layers.MaxPooling2D(2,2), \n tf.keras.layers.Conv2D(64, (4,4), activation=\"relu\"),\n tf.keras.layers.MaxPooling2D(2,2), \n tf.keras.layers.Flatten(), \n tf.keras.layers.Dense(512, activation=\"relu\"), \n tf.keras.layers.Dense(1, activation=\"sigmoid\")]),\n 3: tf.keras.models.Sequential([\n tf.keras.layers.Conv2D(16, (4,4), activation=\"relu\", input_shape=(150, 150, 3)),\n tf.keras.layers.MaxPooling2D(2,2), \n tf.keras.layers.Dropout(0.5), \n tf.keras.layers.Flatten(), \n tf.keras.layers.Dense(128, activation=\"relu\"), \n tf.keras.layers.Dense(1, activation=\"sigmoid\")]),\n 4: tf.keras.models.Sequential([\n tf.keras.layers.Conv2D(16, (4,4), activation=\"relu\", input_shape=(150, 150, 3)),\n tf.keras.layers.MaxPooling2D(2,2),\n tf.keras.layers.Dropout(0.2), \n tf.keras.layers.Conv2D(32, (4,4), activation=\"relu\"),\n tf.keras.layers.MaxPooling2D(2,2), \n tf.keras.layers.Dropout(0.2), \n tf.keras.layers.Conv2D(64, (4,4), activation=\"relu\"),\n tf.keras.layers.MaxPooling2D(2,2), \n tf.keras.layers.Dropout(0.5), \n tf.keras.layers.Flatten(), \n tf.keras.layers.Dense(512, activation=\"relu\"), \n tf.keras.layers.Dense(1, activation=\"sigmoid\")]),\n }\n return switcher.get(kindmodel, None)<\/pre>\n\n\n\n
Modelo con una sola capa convolucional. <\/h4>\n\n\n\n
tf.keras.models.Sequential([\n tf.keras.layers.Conv2D(16, (4,4), activation=\"relu\", input_shape=(150, 150, 3)),\n tf.keras.layers.MaxPooling2D(2,2), \n tf.keras.layers.Flatten(), \n tf.keras.layers.Dense(128, activation=\"relu\"), \n tf.keras.layers.Dense(1, activation=\"sigmoid\")])<\/pre>\n\n\n\n