Pop

Patrones de diseño software 2.Factory

2.Patrón de creación Factory

  • Hola a todos.Seguimos con  nuestro  curso dedicado a los patrones de diseño software.Los patrones de diseño son unas técnicas para resolver problemas comunes en el desarrollo de software y otros ámbitos  referentes al diseño de interacción o interfaces.
  • En esta entrada veremos el patrón de diseño Factory, que consiste en utilizar una clase constructora abstracta con unos cuantos métodos definidos y otros abstractos. Es un patrón de diseño creacional y que sirve para construir una jerarquía de clases. En nuestro caso la jerarquía de clase que hemos creado tiene el aspecto que veis en la imagen:
  • En el siguiente vídeo vemos con un ejemplo como construir esta estructura de clases basándonos en el patrón de diseño factory. 


  • Os dejo el código de las diferentes clases vistas en el vídeo:
*Clase BaseDatosGenerica:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Factory
{
    public abstract  class BaseDatosGenerica
    {
        public abstract string dameCadenaConexion();

    }
}

*Clase Oracle:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Factory
{
    class Oracle:BaseDatosGenerica
    {
        public override string dameCadenaConexion()
        {
            return "CAdena conexión base de datos Oracle";
        }
    }
}

*Clase  SqlServer

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Factory
{
    class SqlServer:BaseDatosGenerica
    {
        public override string dameCadenaConexion()
        {
            return "Cadena conexión base de datos SQlServer";
        }
    }
}

*Clase MySql

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Factory
{
    class MySql:BaseDatosGenerica
    {
        public override string dameCadenaConexion()
        {
            return "Cadena conexión base de datos Mysql";
        }
    }
}

* Clase Configuracion:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Factory
{

    class Configuracion
    {
        public const int SqlServer = 1;
        public const int Oracle = 2;
        public const int MySql = 3;

        public BaseDatosGenerica CrearConexion(int BaseDatos)
        {
            BaseDatosGenerica baseDatos = null;

            if (BaseDatos == 1)
                baseDatos = new SqlServer();
            else if (BaseDatos == 2)
                baseDatos = new Oracle();
            else if (BaseDatos == 3)
                baseDatos = new MySql();
            else
                throw new Exception("Base de datos no soportada");

            return baseDatos;

        }
    }
}

*Clase Program: 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Factory
{
    class Program
    {
        static void Main(string[] args)
        {
            Configuracion conf = new Configuracion();
            BaseDatosGenerica bDatos = conf.CrearConexion(Configuracion.SqlServer);
            Console.WriteLine(bDatos.dameCadenaConexion());
            Console.ReadLine();
             bDatos = conf.CrearConexion(Configuracion.Oracle);
            Console.WriteLine(bDatos.dameCadenaConexion());
            Console.ReadLine();
            bDatos = conf.CrearConexion(Configuracion.MySql);
            Console.WriteLine(bDatos.dameCadenaConexion());
            Console.ReadLine();
        }
    }
}

Patrones de diseño software 1.Presentación

1.Presentación

  • Hola a todos.Hoy comenzamos un nuevo curso dedicado a los patrones de diseño software.Los patrones de diseño son unas técnicas para resolver problemas comunes en el desarrollo de software y otros ámbitos  referentes al diseño de interacción o interfaces.En definitiva un patrón de diseño es una forma reutilizable de resolver un problema común.
  • Algunos de lo motivos por lo que se usan son los siguientes: ahorran tiempo y nos ayudan a estar seguros de la validez de nuestros código.Además los patrones de diseño establecen un lenguaje común entre todos los miembros del equipo.
  • Quizás lo mas complicado es elegir que patrón de diseño se adapta mejor para resolver nuestro problema, para ello es necesario conocer qué tipo de problemas soluciona cada uno y descubrir cómo aplicarlo a casos concretos.
    • Patrones creación:  Son los que facilitan la tarea de creación de nuevos objetos, de tal forma que el proceso de creación pueda ser desacoplado de la implementación del resto del sistema.Los patrones creacionales están basados en la encapsulación, ya que nos facilitan la tarea de creación de nuevos objetos encapsulando el proceso.Los que veremos en este curso son: 
      • Factory 
      • Builder 
      • Singleton
      • Prototype superficial 
      • Prototype deep 
    • Patrones estrucuturales: Son patrones que nos facilitan la modelización de nuestros software especificando la forma en la que unas clases se relacionan con otras:
      • Adapter 
      •  Facade 
      •  Proxy  
      • Bridge 
    • Patrones comportamiento:
      • Memento
      • Strategy
      • Iterator 

  • En siguiente vídeo os cuento en consistirá el curso:

Curso Tensorflow con Anaconda -18 Incorporaciones

18 Incorporaciones

  • Una incorporación es un espacio de dimensiones relativamente bajas al que se pueden trasladar vectores de dimensiones altas. Las incorporaciones permiten llevar a cabo el aprendizaje automático con más facilidad en entradas de gran tamaño.
  • El filtrado colaborativo es la tarea de realizar predicciones acerca de los intereses de un usuario en función de los intereses de muchos otros usuarios.  Por ejemplo,observemos la tarea de recomendación de películas. Imagina que tenemos 1,000,000 usuarios y una lista de las películas que cada uno de ellos ha visto (de un catálogo de 500,000 películas). Nuestro objetivo es recomendar películas a los usuarios. Para resolver este problema, se necesita un método que determine qué películas son similares entre sí. En la imagen vemos como hemos agrupado las películas  similares cerca.


  • Si distribuimos las películas en una incorporación de dos dimensiones, definimos una distancia entre las películas de manera tal que las películas estén cerca entre sí  (y por lo tanto se infiere que son similares). En términos más generales, lo que hicimos es asignar estas películas a un espacio de incorporación, donde se describe cada palabra mediante un conjunto de coordenadas en dos dimensiones. Por ejemplo, en este espacio, "Shrek" se asigna a (-1.0, 0.95) y "Bleu" se asigna a (0.65, -0.2). 




  • En general, al aprender una incorporación de d dimensiones, cada película se representa con d números de valores reales y cada uno de ellos proporciona la coordenada en cada dimensión. Los datos categóricos hacen referencia a atributos de entrada que representan uno o más elementos discretos de un conjunto de opciones finito.Se representan de manera más eficaz a través de tensores dispersos, que son tensores con muy pocos elementos distintos de cero. Por ejemplo, si queremos crear un modelo de recomendaciones de películas, podemos asignar un ID único a cada película posible y, luego, representar al usuario como un tensor disperso de las películas que ha mirado, tal como se muestra en la Figura.


    • Cada fila de la matriz en la Figura 3 corresponde a un usuario y puede ser representado con un tensor disperso, ya que cada usuario solo mira una pequeña fracción de las películas posibles. La última fila corresponde al tensor disperso [1, 3, 999999]
    • Os dejo el vídeo con la explicación:
    • Os dejo el código visto en el vídeo:
    """Objetivos:
    - En este ejercicio, exploraremos datos dispersos y trabajaremos con incrustaciones utilizando datos de texto de reseñas 
    de películas (del conjunto de datos de la ACL 2011 IMDB). Estos datos ya han sido procesados en formato tf.Example.
    - Convertir datos de cadena de revisión de películas en un vector de características.
    - Implementar un modelo lineal de análisis.
    - Implementar un modelo neuronal utilizando una incorporación que proyecte datos en dos dimensiones.
    - Visualicar la inserción para ver lo que el modelo ha aprendido sobre las relaciones entre las palabras.
    """

    #Importemos nuestras dependencias y descarguemos los datos de entrenamiento y prueba

    from __future__ import print_function

    import collections
    import io
    import math

    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import tensorflow as tf
    from IPython import display
    from sklearn import metrics

    tf.logging.set_verbosity(tf.logging.ERROR)
    train_url = 'https://download.mlcc.google.com/mledu-datasets/sparse-data-embedding/train.tfrecord'
    train_path = tf.keras.utils.get_file(train_url.split('/')[-1], train_url)
    test_url = 'https://download.mlcc.google.com/mledu-datasets/sparse-data-embedding/test.tfrecord'
    test_path = tf.keras.utils.get_file(test_url.split('/')[-1], test_url)

    #Primero, configuremos el canal de entrada para importar nuestros datos en un modelo TensorFlow. 
    #Podemos usar la siguiente función para analizar los datos de entrenamiento y prueba (formato TFRecord) y devolver un dictado 
    #de las características y las etiquetas correspondientes.

    def _parse_function(record):
      """Extracts features and labels.
      
      Args:
        record: Ruta  a un archivo TFRecord   
      Returns:
        A `tuple` `(labels, features)`:
          features: Una de tensores que representan las características.
          labels: Un tensor con las etiquetas correspondientes.
      """
      features = {
        "terms": tf.VarLenFeature(dtype=tf.string), # terms are strings of varying lengths
        "labels": tf.FixedLenFeature(shape=[1], dtype=tf.float32) # labels are 0 or 1
      }
      
      parsed_features = tf.parse_single_example(record, features)
      
      terms = parsed_features['terms'].values
      labels = parsed_features['labels']

      return  {'terms':terms}, labels
      
    #Para confirmar que nuestra función está funcionando como se espera, construyamos un TFRecordDataset para los datos 
    #de entrenamiento, y asignemos los datos a características y etiquetas utilizando la función anterior.

    ds = tf.data.TFRecordDataset(train_path)
    # Map features and labels with the parse function.
    ds = ds.map(_parse_function)

    ds

    #Ejecute el siguiente código recuperamos el primer ejemplo del conjunto de datos de entrenamiento.

    n = ds.make_one_shot_iterator().get_next()
    sess = tf.Session()# Create an input_fn that parses the tf.Examples from the given files,
    # and split them into features and targets.
    def _input_fn(input_filenames, num_epochs=None, shuffle=True):
      
      # Same code as above; create a dataset and map features and labels.
      ds = tf.data.TFRecordDataset(input_filenames)
      ds = ds.map(_parse_function)

      if shuffle:
        ds = ds.shuffle(10000)

      # Our feature data is variable-length, so we pad and batch
      # each field of the dataset structure to whatever size is necessary.
      ds = ds.padded_batch(25, ds.output_shapes)
      
      ds = ds.repeat(num_epochs)

      
      # Return the next batch of data.
      features, labels = ds.make_one_shot_iterator().get_next()
      return features, labels
    sess.run(n)

    #Ahora, construyamos una función de entrada  que podamos pasar al método train () de un objeto TensorFlow Estimator.
    # Create an input_fn that parses the tf.Examples from the given files,
    # and split them into features and targets.
    def _input_fn(input_filenames, num_epochs=None, shuffle=True):
      
      # Same code as above; create a dataset and map features and labels.
      ds = tf.data.TFRecordDataset(input_filenames)
      ds = ds.map(_parse_function)

      if shuffle:
        ds = ds.shuffle(10000)

      # Our feature data is variable-length, so we pad and batch
      # each field of the dataset structure to whatever size is necessary.
      ds = ds.padded_batch(25, ds.output_shapes)
      
      ds = ds.repeat(num_epochs)

      
      # Return the next batch of data.
      features, labels = ds.make_one_shot_iterator().get_next()
      return features, labels

    #Tarea 1: usar un modelo lineal con entradas dispersas y un vocabulario explícito

    #Para nuestro primer modelo, construiremos un modelo LinearClassifier usando 50 términos informativos

    # 50 informative terms that compose our model vocabulary 
    informative_terms = ("bad", "great", "best", "worst", "fun", "beautiful",
                         "excellent", "poor", "boring", "awful", "terrible",
                         "definitely", "perfect", "liked", "worse", "waste",
                         "entertaining", "loved", "unfortunately", "amazing",
                         "enjoyed", "favorite", "horrible", "brilliant", "highly",
                         "simple", "annoying", "today", "hilarious", "enjoyable",
                         "dull", "fantastic", "poorly", "fails", "disappointing",
                         "disappointment", "not", "him", "her", "good", "time",
                         "?", ".", "!", "movie", "film", "action", "comedy",
                         "drama", "family")

    terms_feature_column = tf.feature_column.categorical_column_with_vocabulary_list(key="terms", vocabulary_list=informative_terms)

    #A continuación, construiremos el LinearClassifier, lo entrenaremos en el conjunto de entrenamiento y lo evaluaremos en el 
    #conjunto de evaluación. 

    my_optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)
    my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)

    feature_columns = [ terms_feature_column ]


    classifier = tf.estimator.LinearClassifier(
      feature_columns=feature_columns,
      optimizer=my_optimizer,
    )

    classifier.train(
      input_fn=lambda: _input_fn([train_path]),
      steps=1000)

    evaluation_metrics = classifier.evaluate(
      input_fn=lambda: _input_fn([train_path]),
      steps=1000)
    print("Valores conjunto entrenamiento:")
    for m in evaluation_metrics:
      print(m, evaluation_metrics[m])
    print("---")

    evaluation_metrics = classifier.evaluate(
      input_fn=lambda: _input_fn([test_path]),
      steps=1000)

    print("Valores conjunto validación:")
    for m in evaluation_metrics:
      print(m, evaluation_metrics[m])
    print("---")


    #Tarea 2: usar un modelo de red neuronal profunda (DNN)

    ##################### Here's what we changed ##################################
    classifier = tf.estimator.DNNClassifier(                                      #
      feature_columns=[tf.feature_column.indicator_column(terms_feature_column)], #
      hidden_units=[20,20],                                                       #
      optimizer=my_optimizer,                                                     #
    )                                                                             #
    ###############################################################################

    try:
      classifier.train(
        input_fn=lambda: _input_fn([train_path]),
        steps=1000)

      evaluation_metrics = classifier.evaluate(
        input_fn=lambda: _input_fn([train_path]),
        steps=1)
      print("Valores conjunto entrenamiento:")
      for m in evaluation_metrics:
        print(m, evaluation_metrics[m])
      print("---")

      evaluation_metrics = classifier.evaluate(
        input_fn=lambda: _input_fn([test_path]),
        steps=1)

      print("Valores conjunto validación:")
      for m in evaluation_metrics:
        print(m, evaluation_metrics[m])
      print("---")
    except ValueError as err:
      print(err)
      

    #Tarea 3: usar una incrustación con un modelo DNN
    #Una columna incrustada toma datos escasos como entrada y devuelve un vector denso de dimensión inferior como salida.
    #En el siguiente código, haga lo siguiente:
        #Defina las columnas de características para el modelo utilizando una columna de incrustación que proyecta los datos en 
        #2 dimensiones.
        #Defina un DNNClassifier con las siguientes especificaciones:
            #Dos capas ocultas de 20 unidades cada una.
            #Optimización de Adagrad con una tasa de aprendizaje de 0,1.
            #Un gradient_clip_norm de 5.0
            
    ########################## SOLUTION CODE ########################################
    terms_embedding_column = tf.feature_column.embedding_column(terms_feature_column, dimension=2)
    feature_columns = [ terms_embedding_column ]

    my_optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)
    my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)

    classifier = tf.estimator.DNNClassifier(
      feature_columns=feature_columns,
      hidden_units=[20,20],
      optimizer=my_optimizer
    )
    #################################################################################

    classifier.train(
      input_fn=lambda: _input_fn([train_path]),
      steps=1000)

    evaluation_metrics = classifier.evaluate(
      input_fn=lambda: _input_fn([train_path]),
      steps=1000)
    print("Valores conjunto entrenamiento:")
    for m in evaluation_metrics:
      print(m, evaluation_metrics[m])
    print("---")

    evaluation_metrics = classifier.evaluate(
      input_fn=lambda: _input_fn([test_path]),
      steps=1000)

    print("Valores conjunto validación:")
    for m in evaluation_metrics:
      print(m, evaluation_metrics[m])
    print("---")

    #Tarea 5: Examinar la incrustación
    # 1 Ejecute el siguiente código para ver la inserción que entrenamos en la Tarea 3. 
    # 2 Vuelva a entrenar el modelo volviendo a ejecutar el código en la Tarea 3, y luego vuelva a ejecutar 
    # 3 Finalmente, vuelva a entrenar el modelo nuevamente usando solo 10 pasos 

    import numpy as np
    import matplotlib.pyplot as plt

    embedding_matrix = classifier.get_variable_value('dnn/input_from_feature_columns/input_layer/terms_embedding/embedding_weights')

    for term_index in range(len(informative_terms)):
      # Create a one-hot encoding for our term. It has 0s everywhere, except for
      # a single 1 in the coordinate that corresponds to that term.
      term_vector = np.zeros(len(informative_terms))
      term_vector[term_index] = 1
      # We'll now project that one-hot vector into the embedding space.
      embedding_xy = np.matmul(term_vector, embedding_matrix)
      plt.text(embedding_xy[0],
               embedding_xy[1],
               informative_terms[term_index])

    # Do a little setup to make sure the plot displays nicely.
    plt.rcParams["figure.figsize"] = (15, 15)
    plt.xlim(1.2 * embedding_matrix.min(), 1.2 * embedding_matrix.max())
    plt.ylim(1.2 * embedding_matrix.min(), 1.2 * embedding_matrix.max())
    plt.show() 

    #Tarea 6: tratar de mejorar el rendimiento del modelo
    # Download the vocabulary file.
    terms_url = 'https://download.mlcc.google.com/mledu-datasets/sparse-data-embedding/terms.txt'
    terms_path = tf.keras.utils.get_file(terms_url.split('/')[-1], terms_url)

    # Create a feature column from "terms", using a full vocabulary file.
    informative_terms = None
    with io.open(terms_path, 'r', encoding='utf8') as f:
      # Convert it to a set first to remove duplicates.
      informative_terms = list(set(f.read().split()))
      
    terms_feature_column = tf.feature_column.categorical_column_with_vocabulary_list(key="terms", 
                                                                                     vocabulary_list=informative_terms)

    terms_embedding_column = tf.feature_column.embedding_column(terms_feature_column, dimension=2)
    feature_columns = [ terms_embedding_column ]

    my_optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)
    my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)

    classifier = tf.estimator.DNNClassifier(
      feature_columns=feature_columns,
      hidden_units=[10,10],
      optimizer=my_optimizer
    )

    classifier.train(
      input_fn=lambda: _input_fn([train_path]),
      steps=1000)

    evaluation_metrics = classifier.evaluate(
      input_fn=lambda: _input_fn([train_path]),
      steps=1000)
    print("Training set metrics:")
    for m in evaluation_metrics:
      print(m, evaluation_metrics[m])
    print("---")

    evaluation_metrics = classifier.evaluate(
      input_fn=lambda: _input_fn([test_path]),
      steps=1000)

    print("Test set metrics:")
    for m in evaluation_metrics:
      print(m, evaluation_metrics[m])
    print("---")

    Curso Tensorflow con Anaconda -17 Redes neuronales de clases múltiples

    17 Redes neuronales de clases múltiples

    • En vídeos anteriores, presentamos modelos de clasificación binaria que podían elegir una de dos opciones posibles, como el caso en el que distinguimos si un correo electrónico dado "es spam" o "no es spam". En este vídeo, investigaremos la clasificación de clases múltiples, que puedes elegir entre posibilidades múltiples. Por ejemplo:
      • ¿Este perro es un beagle, un basset hound o un sabueso?
      • ¿Esta flor es una iris sibirica, hollandica, versicolor o setosa?
      • Algunos problemas de clases múltiples del mundo real implican elegir entre millones de clases individuales.Por ejemplo, supongamos un modelo de clasificación de clases múltiples que pueda identificar la imagen de lo que fuera.
    • En la imagen vemos un ejemplo de "uno frente a todos", que es un enfoque que nos proporciona una mane
    • ra de aprovechar la clasificación binaria. En un problema de clasificación dado con N soluciones posibles, una solución de uno frente a todos consiste en N clasificadores binarios independientes.


    • Otro posible enfoque es utilizar Softmax. La regresión logística genera un decimal entre 0 y 1.0. Por ejemplo, si un clasificador de correo electrónico tiene un resultado de  regresión logística de 0.8, hay un 80% de posibilidad de que un correo electrónico sea spam y un 20% de que no lo sea. La suma de las probabilidades de que un correo electrónico sea spam o no es 1.0.
    • Softmax lleva esta idea al plano de las clases múltiples. Es decir, softmax asigna probabilidades decimales a cada clase en un caso de clases múltiples. Esas probabilidades decimales deben sumar 1.0. Esta restricción adicional permite que el entrenamiento converja más rápido.
    • Os dejo un vídeo donde os cuento todo esto:



    • Os dejo el código visto en el vídeo:
    #Capacitar a un modelo lineal y una red neuronal para clasificar los dígitos escritos a mano.
    """
    Primero, descargamos el conjunto de datos, importemos TensorFlow y otras utilidades, y carguemos los datos en un dataframe. """

    from __future__ import print_function

    import glob
    import math
    import os

    from IPython import display
    from matplotlib import cm
    from matplotlib import gridspec
    from matplotlib import pyplot as plt
    import numpy as np
    import pandas as pd
    import seaborn as sns
    from sklearn import metrics
    import tensorflow as tf
    from tensorflow.python.data import Dataset

    tf.logging.set_verbosity(tf.logging.ERROR)
    pd.options.display.max_rows = 10
    pd.options.display.float_format = '{:.1f}'.format

    mnist_dataframe = pd.read_csv(
      "https://download.mlcc.google.com/mledu-datasets/mnist_train_small.csv",
      sep=",",
      header=None)

    # Usamos los primeros 10,000 registros de entrenamiento y validación.
    mnist_dataframe = mnist_dataframe.head(10000)

    mnist_dataframe = mnist_dataframe.reindex(np.random.permutation(mnist_dataframe.index))
    mnist_dataframe.head()

    """Las columnas 1 a 784 contienen los valores de características, uno por píxel para los valores de 28 × 28 = 784 píxeles.
    Los valores de los píxeles están en una escala de grises en la que 0 representa blanco, 255 representa negro y 
    los valores entre 0 y 255 representan tonos de gris. 
    La mayoría de los valores de píxeles son 0 pero no todos son cero"""
    mnist_dataframe.loc[:, 120:130]

    # Ahora, analicemos las etiquetas y características y veamos algunos ejemplos
    def parse_labels_and_features(dataset):
      """Extraemos de etiquetas y características.
      Función para escalar o transformar las funciones si es necesario.
      
      Args:
        dataset: `Dataframe`, que contiene la etiqueta en la primera columna y
           valores de píxeles monocromos en las columnas restantes, en orden mayor de fila.
      Returns:
        Una `tupla` `(labels, features)`:
          labels: Devuelve una serie panda
          características: Devuelve un dataframe
      """
      labels = dataset[0]
      features = dataset.loc[:,1:784]
      # Escalamos para que los valores esten entre 0 y 1
      features = features / 255

      return labels, features

    training_targets, training_examples = parse_labels_and_features(mnist_dataframe[:7500])
    training_examples.describe()
    validation_targets, validation_examples = parse_labels_and_features(mnist_dataframe[7500:10000])
    validation_examples.describe()

    #Ejemplo aleatorio y su etiqueta correspondiente.
    rand_example = np.random.choice(training_examples.index)
    _, ax = plt.subplots()
    ax.matshow(training_examples.loc[rand_example].values.reshape(28, 28))
    ax.set_title("Label: %i" % training_targets.loc[rand_example])
    ax.grid(False)

    """Tarea 1: construir un modelo lineal para MNIST
    Primero, vamos a crear un modelo de línea base para comparar.
    El LinearClassifier proporciona un conjunto de k clasificadores de uno contra todos, uno para cada una de las k clases.
    Mostramos una matriz de confusión. La matriz de confusión muestra qué clases se clasificaron erróneamente. 
    También tenga en cuenta que rastreamos el error del modelo usando la función log_loss.
    Esto no debe confundirse con la función de pérdida interna de LinearClassifier que se utiliza para el entrenamiento."""

    def construct_feature_columns():
      """Construye las columnas de la característica TensorFlow.

      Returns:
       Una columna de características de 784 pixeles
      """ 
      
      return set([tf.feature_column.numeric_column('pixels', shape=784)])


    #Creamos funciones de entrada separadas para entrenamiento y para predicción: create_training_input_fn () y 
    #create_predict_input_fn ().Podemos invocar estas funciones para devolver las _input_fns correspondientes para 
    #que pasen a nuestras llamadas .train () y .predict ().

    def create_training_input_fn(features, labels, batch_size, num_epochs=None, shuffle=True):
      """Un input_fn personalizado para enviar datos.
      Args:
        features: Características de entrenamiento.
        labels: Etiquetas de entrenamiento.
        batch_size: Tamaño de lote para usar durante el entrenamiento.

      Returns:
       Una función que devuelve lotes de características de entrenamiento y etiquetas durante el entrenamiento
      """
      def _input_fn(num_epochs=None, shuffle=True):
        # Las entradas son reseteadas en cada llamada a to .train(). Para asegurar el modelo
        # obtiene una buena muestra de datos, incluso cuando el número de pasos es pequeño,
        # mezcla todos los datos antes de crear el objeto Dataset
        idx = np.random.permutation(features.index)
        raw_features = {"pixels":features.reindex(idx)}
        raw_targets = np.array(labels[idx])
       
        ds = Dataset.from_tensor_slices((raw_features,raw_targets)) # warning: 2GB limit
        ds = ds.batch(batch_size).repeat(num_epochs)
        
        if shuffle:
          ds = ds.shuffle(10000)
        
        # Devuelve el siguiente lote de datos.
        feature_batch, label_batch = ds.make_one_shot_iterator().get_next()
        return feature_batch, label_batch

      return _input_fn

    def create_predict_input_fn(features, labels, batch_size):
      """Un input_fn personalizado para enviar datos mnist al estimador para predicciones.

      Args:
        features: Características para predicciones
        labels: Las etiquetas de los ejemplos de predicción.

      Returns:
        Una función que devuelve características y etiquetas para predicciones.
      """
      def _input_fn():
        raw_features = {"pixels": features.values}
        raw_targets = np.array(labels)
        
        ds = Dataset.from_tensor_slices((raw_features, raw_targets)) # warning: 2GB limit
        ds = ds.batch(batch_size)
        
            
        # Devolvemos el siguiente lote de datos
        feature_batch, label_batch = ds.make_one_shot_iterator().get_next()
        return feature_batch, label_batch

      return _input_fn

    def train_linear_classification_model(
        learning_rate,
        steps,
        batch_size,
        training_examples,
        training_targets,
        validation_examples,
        validation_targets):
      """Entrena un modelo de clasificación lineal para el conjunto de datos de dígitos MNIST.
      
        Además del enrenamiento, esta función también imprime información sobre el progreso de dicho entrenamiento,
       Un gráfico de la pérdida de entrenamiento y validación en el tiempo, y una matriz de confuciónn.
      
      Args:
        learning_rate: A `float`, the learning rate to use.
        steps: A non-zero `int`, the total number of training steps. A training step
          consists of a forward and backward pass using a single batch.
        batch_size: A non-zero `int`, the batch size.
        training_examples: A `DataFrame` containing the training features.
        training_targets: A `DataFrame` containing the training labels.
        validation_examples: A `DataFrame` containing the validation features.
        validation_targets: A `DataFrame` containing the validation labels.
          
      Returns:
        El objeto `LinearClassifier` entrenado.
      """

      periods = 10

      steps_per_period = steps / periods  
      # Creamos las funciones de entrada
      predict_training_input_fn = create_predict_input_fn(
        training_examples, training_targets, batch_size)
      predict_validation_input_fn = create_predict_input_fn(
        validation_examples, validation_targets, batch_size)
      training_input_fn = create_training_input_fn(
        training_examples, training_targets, batch_size)
      
      # Creamos el objeto LinearClassifier.
      my_optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate)
      my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)
      classifier = tf.estimator.LinearClassifier(
          feature_columns=construct_feature_columns(),
          n_classes=10,
          optimizer=my_optimizer,
          config=tf.estimator.RunConfig(keep_checkpoint_max=1)
      )

      # Entrene al modelo, pero hágalo dentro de un bucle para que podamos evaluar periódicamente
      print("Entrenando el modelo...")
      print("LogLoss error en datos de valdación:")
      training_errors = []
      validation_errors = []
      for period in range (0, periods):
        # Entrenamos al modelo desde el estado anterior
        classifier.train(
            input_fn=training_input_fn,
            steps=steps_per_period
        )
      
        #Calculamos probabilidades
        training_predictions = list(classifier.predict(input_fn=predict_training_input_fn))
        training_probabilities = np.array([item['probabilities'] for item in training_predictions])
        training_pred_class_id = np.array([item['class_ids'][0] for item in training_predictions])
        training_pred_one_hot = tf.keras.utils.to_categorical(training_pred_class_id,10)
            
        validation_predictions = list(classifier.predict(input_fn=predict_validation_input_fn))
        validation_probabilities = np.array([item['probabilities'] for item in validation_predictions])    
        validation_pred_class_id = np.array([item['class_ids'][0] for item in validation_predictions])
        validation_pred_one_hot = tf.keras.utils.to_categorical(validation_pred_class_id,10)    
        
        # Calcular los errores de entrenamiento y validación.
        training_log_loss = metrics.log_loss(training_targets, training_pred_one_hot)
        validation_log_loss = metrics.log_loss(validation_targets, validation_pred_one_hot)
        # De vez en cuando imprimir la pérdida actual.
        print("  period %02d : %0.2f" % (period, validation_log_loss))
        # Agrega las métricas de pérdida de este período a nuestra lista.
        training_errors.append(training_log_loss)
        validation_errors.append(validation_log_loss)
      print("Entrenamiento del modelo finalizazo.")
      # Eliminar archivos de eventos para ahorrar espacio en disco.
      _ = map(os.remove, glob.glob(os.path.join(classifier.model_dir, 'events.out.tfevents*')))
      
      # Calcule las predicciones finales
      final_predictions = classifier.predict(input_fn=predict_validation_input_fn)
      final_predictions = np.array([item['class_ids'][0] for item in final_predictions])
      
      
      accuracy = metrics.accuracy_score(validation_targets, final_predictions)
      print("Exactitud final (on validation data): %0.2f" % accuracy)

      # Genera una gráfica de métricas de pérdida en periodos.
      plt.ylabel("LogLoss")
      plt.xlabel("Periodos")
      plt.title("LogLoss vs. Periodos")
      plt.plot(training_errors, label="training")
      plt.plot(validation_errors, label="validation")
      plt.legend()
      plt.show()
      
      # Pintamos la matriz de confusión
      cm = metrics.confusion_matrix(validation_targets, final_predictions)
      # Normalizamos la matriz de confusión por fila.
      cm_normalized = cm.astype("float") / cm.sum(axis=1)[:, np.newaxis]
      ax = sns.heatmap(cm_normalized, cmap="bone_r")
      ax.set_aspect(1)
      plt.title("Confusion matriz")
      plt.ylabel("Etiqueta verdadera")
      plt.xlabel("Etiqueta predicción")
      plt.show()

      return classifier

    _ = train_linear_classification_model(
        learning_rate=0.03,
        steps=1000,
        batch_size=30,
        training_examples=training_examples,
        training_targets=training_targets,
        validation_examples=validation_examples,
        validation_targets=validation_targets)

    """Tarea 2: reemplazar el clasificador lineal con una red neuronal
    Reemplace el LinearClassifier de arriba con un DNNClassifier y encuentre una combinación de parámetros que 
    dé una precisión de 0.95 o más."""

    def train_nn_classification_model(
        learning_rate,
        steps,
        batch_size,
        hidden_units,
        training_examples,
        training_targets,
        validation_examples,
        validation_targets):
      """Entrena un modelo de clasificación de red neuronal para el conjunto de datos de dígitos MNIST.
      
        Además del enrenamiento, esta función también imprime información sobre el progreso 
        de dicho entrenamiento,
       Un gráfico de la pérdida de entrenamiento y validación en el tiempo, y una matriz de confusiónn.
      
      Args:
        learning_rate: A `float`, the learning rate to use.
        steps: A non-zero `int`, the total number of training steps. A training step
          consists of a forward and backward pass using a single batch.
        batch_size: A non-zero `int`, the batch size.
        hidden_units: A `list` of int values, specifying the number of neurons in each layer.
        training_examples: A `DataFrame` containing the training features.
        training_targets: A `DataFrame` containing the training labels.
        validation_examples: A `DataFrame` containing the validation features.
        validation_targets: A `DataFrame` containing the validation labels.
          
      Returns:
        El objeto  `DNNClassifier` .
      """

      periods = 10
      # Precaución: las entradasse restablecen con cada llamada.
      # Si el número de pasos es pequeño, es posible que su modelo nunca vea la mayoría de los datos. 
      # Así que con múltiples llamadas `.train`  es posible que desee controlar la longitud

      steps_per_period = steps / periods  
      
        # Creamos las funciones de entrada
      predict_training_input_fn = create_predict_input_fn(
        training_examples, training_targets, batch_size)
      predict_validation_input_fn = create_predict_input_fn(
        validation_examples, validation_targets, batch_size)
      training_input_fn = create_training_input_fn(
        training_examples, training_targets, batch_size)
      
      # Creamos las funciones de entrada
      predict_training_input_fn = create_predict_input_fn(
        training_examples, training_targets, batch_size)
      predict_validation_input_fn = create_predict_input_fn(
        validation_examples, validation_targets, batch_size)
      training_input_fn = create_training_input_fn(
        training_examples, training_targets, batch_size)
      
      # Creamos las columnas
      feature_columns = [tf.feature_column.numeric_column('pixels', shape=784)]

      #objeto DNNClassifier.
      my_optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate)
      my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)
      classifier = tf.estimator.DNNClassifier(
          feature_columns=feature_columns,
          n_classes=10,
          hidden_units=hidden_units,
          optimizer=my_optimizer,
          config=tf.contrib.learn.RunConfig(keep_checkpoint_max=1)
      )

      # Entrene al modelo, pero hágalo dentro de un bucle para que podamos evaluar periódicamente
      print("Training model...")
      print("LogLoss error (on validation data):")
      training_errors = []
      validation_errors = []
      for period in range (0, periods):
        #Entrena el modelo, partiendo del estado anterior.
        classifier.train(
            input_fn=training_input_fn,
            steps=steps_per_period
        )
      
          #Calculamos probabilidades
        training_predictions = list(classifier.predict(input_fn=predict_training_input_fn))
        training_probabilities = np.array([item['probabilities'] for item in training_predictions])
        training_pred_class_id = np.array([item['class_ids'][0] for item in training_predictions])
        training_pred_one_hot = tf.keras.utils.to_categorical(training_pred_class_id,10)
            
        validation_predictions = list(classifier.predict(input_fn=predict_validation_input_fn))
        validation_probabilities = np.array([item['probabilities'] for item in validation_predictions])    
        validation_pred_class_id = np.array([item['class_ids'][0] for item in validation_predictions])
        validation_pred_one_hot = tf.keras.utils.to_categorical(validation_pred_class_id,10)    
        
         # Calcular los errores de entrenamiento y validación.
        training_log_loss = metrics.log_loss(training_targets, training_pred_one_hot)
        validation_log_loss = metrics.log_loss(validation_targets, validation_pred_one_hot)
         # De vez en cuando imprimir la pérdida actual.
        print("  period %02d : %0.2f" % (period, validation_log_loss))
         # Agrega las métricas de pérdida de este período a nuestra lista.
        training_errors.append(training_log_loss)
        validation_errors.append(validation_log_loss)
      print("Entrenamiento del modelo finalizado.")
     # Eliminar archivos de eventos para ahorrar espacio en disco.
      _ = map(os.remove, glob.glob(os.path.join(classifier.model_dir, 'events.out.tfevents*')))
      
      # Calculamos las predicciones finales
      final_predictions = classifier.predict(input_fn=predict_validation_input_fn)
      final_predictions = np.array([item['class_ids'][0] for item in final_predictions])
      
      
      accuracy = metrics.accuracy_score(validation_targets, final_predictions)
      print("Exactitud final (on validation data): %0.2f" % accuracy)

      # Genera una gráfica de métricas de pérdida en periodos.
      plt.ylabel("LogLoss")
      plt.xlabel("Periodos")
      plt.title("LogLoss vs. Periodos")
      plt.plot(training_errors, label="training")
      plt.plot(validation_errors, label="validation")
      plt.legend()
      plt.show()
      
       # Pintamos la matriz de confusión# Pintamos la matriz de confusión
      cm = metrics.confusion_matrix(validation_targets, final_predictions)

        #Normalizamos
      cm_normalized = cm.astype("float") / cm.sum(axis=1)[:, np.newaxis]
      ax = sns.heatmap(cm_normalized, cmap="bone_r")
      ax.set_aspect(1)
      plt.title("Confusion matriz")
      plt.ylabel("Etiqueta verdadera")
      plt.xlabel("Etiqueta predicción")
      plt.show()

      return classifier
    classifier = train_nn_classification_model(
        learning_rate=0.05,
        steps=1000,
        batch_size=30,
        hidden_units=[100, 100],
        training_examples=training_examples,
        training_targets=training_targets,
        validation_examples=validation_examples,
        validation_targets=validation_targets)

    predict_test_input_fn = create_predict_input_fn(
        test_examples, test_targets, batch_size=100)

    test_predictions = classifier.predict(input_fn=predict_test_input_fn)
    test_predictions = np.array([item['class_ids'][0] for item in test_predictions])
      
    accuracy = metrics.accuracy_score(test_targets, test_predictions)
    print("Accuracy on test data: %0.2f" % accuracy)

    """Tarea 3: Visualizar los pesos de la primera capa oculta.
    Tomemos unos minutos para profundizar en nuestra red neuronal
    y ver lo que ha aprendido al acceder al atributo de peso_ de
    nuestro modelo.
    La capa de entrada de nuestro modelo tiene 784 pesos correspondientes a las imágenes de entrada de 28 × 28 píxeles. 
    La primera capa oculta tendrá 784 × N pesos, donde N es el número de nodos en esa capa. 
    Podemos volver a convertir esos pesos en imágenes 28 × 28 cambiando cada una de las matrices N 1 × 784 de pesos 
    en matrices N de tamaño 28 × 28."""

    print(classifier.get_variable_names())

    weights0 = classifier.get_variable_value("dnn/hiddenlayer_0/kernel")

    print("weights0 shape:", weights0.shape)

    num_nodes = weights0.shape[1]
    num_rows = int(math.ceil(num_nodes / 10.0))
    fig, axes = plt.subplots(num_rows, 10, figsize=(20, 2 * num_rows))
    for coef, ax in zip(weights0.T, axes.ravel()):
        # Weights in coef is reshaped from 1x784 to 28x28.
        ax.matshow(coef.reshape(28, 28), cmap=plt.cm.pink)
        ax.set_xticks(())
        ax.set_yticks(())

    plt.show()

    Curso Tensorflow con Anaconda -16 Entrenamiento de las redes neuronales

    16 Entrenamiento de las redes neuronales

    • En este capítulo veremos como entrenar una red neuronal.Cabe destacar que la propagación inversa es el algoritmo de entrenamiento más común en las redes neuronales. Permite que el descenso de gradientes sea factible para las redes neuronales de varias capas.En nuestro caso  TensorFlow realiza la propagación inversa automáticamente,  de manera que no necesitamos conocimientos específicos del algoritmo.
    • En el siguiente vídeo vemos un ejemplo en el que tratamos de mejorar el rendimiento de la red neuronal que entrenamos en el vídeo anterior:
    • Os dejo el código visto en el vídeo:
    #Objetivo: mejorar el rendimiento de una red neuronal mediante la normalización de las #funciones y la aplicación de varios algoritmos de optimización

    #Primero cargamos los datoscon los que vamos a trabajar.Visto en videos anteriores

    from __future__ import print_function

    import math

    from IPython import display
    from matplotlib import cm
    from matplotlib import gridspec
    from matplotlib import pyplot as plt
    import numpy as np
    import pandas as pd
    from sklearn import metrics
    import tensorflow as tf
    from tensorflow.python.data import Dataset

    tf.logging.set_verbosity(tf.logging.ERROR)
    pd.options.display.max_rows = 10
    pd.options.display.float_format = '{:.1f}'.format

    california_housing_dataframe = pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv", sep=",")

    california_housing_dataframe = california_housing_dataframe.reindex(
        np.random.permutation(california_housing_dataframe.index))

    def preprocess_features(california_housing_dataframe):
      """Prepara las características de entrada del conjunto de datos de vivienda de California.

      Args:
        california_housing_dataframe: contenedor datos
           del conjunto de datos de vivienda de California.
      Returns:
      Un DataFrame que contiene las características que se utilizarán para el modelo, incluyendo atributos sintéticos.
      """
      selected_features = california_housing_dataframe[
        ["latitude",
         "longitude",
         "housing_median_age",
         "total_rooms",
         "total_bedrooms",
         "population",
         "households",
         "median_income"]]
      processed_features = selected_features.copy()
      # Creamos característica sintética
      processed_features["rooms_per_person"] = (
        california_housing_dataframe["total_rooms"] /
        california_housing_dataframe["population"])
      return processed_features

    def preprocess_targets(california_housing_dataframe):
      """Prepara características de destino (es decir, etiquetas) a partir del conjunto de datos de vivienda de California.
      Args:
        california_housing_dataframe: contenedor de datosdel conjunto de datos de vivienda de California.
      Returns:
       Un DataFrame que contiene la característica de destino.
      """
      output_targets = pd.DataFrame()
      # ponemos el objetivo en unidades de miles de dolares
      output_targets["median_house_value"] = (
        california_housing_dataframe["median_house_value"] / 1000.0)
      return output_targets

    # Elija los primeros 12000 (de 17000) ejemplos de entrenamiento.
    training_examples = preprocess_features(california_housing_dataframe.head(12000))
    training_targets = preprocess_targets(california_housing_dataframe.head(12000))

    # Elija los últimos 5000 (de 17000) ejemplos para validación.
    validation_examples = preprocess_features(california_housing_dataframe.tail(5000))
    validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))

    print("Training examples summary:")
    display.display(training_examples.describe())
    print("Validation examples summary:")
    display.display(validation_examples.describe())

    print("Training targets summary:")
    display.display(training_targets.describe())
    print("Validation targets summary:")
    display.display(validation_targets.describe())

    #Ahora entrenamos la red neuronal

    def construct_feature_columns(input_features):
      """Construimos las columnas de la característica TensorFlow

      Args:
        input_features: Los nombres de las características de entrada numérica a utilizar.
      Returns:
        Un conjunto de columnas de características
      """ 
      return set([tf.feature_column.numeric_column(my_feature)
                  for my_feature in input_features])

    def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):
        """Entrenamos una red neuronal
      
        Args:
          features: Dataframe de características
          targets: Dataframe de objetivos
          batch_size: Tamaño de los lotes
          shuffle: Según sea verdadero o falso mezclamos los datos.
          num_epochs: Número de repeticiones
        Returns:
          Tuple of (features, labels) for next data batch
        """
     
        
        features = {key:np.array(value) for key,value in dict(features).items()}                                             

        ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit
        ds = ds.batch(batch_size).repeat(num_epochs)
        
        if shuffle:
          ds = ds.shuffle(10000)
        

        features, labels = ds.make_one_shot_iterator().get_next()
        return features, labels

    def train_nn_regression_model(
        my_optimizer,
        steps,
        batch_size,
        hidden_units,
        training_examples,
        training_targets,
        validation_examples,
        validation_targets):
      """Entrenamos una red neuronal
      
      Además del entrenamiento, esta función también imprime información sobre el progreso de la capacitación,
      así como una gráfica de la pérdida de entrenamiento y validación a lo largo del tiempo.
      
      Args:
        learning_rate: Un `float`,la tasa de aprendizaje
        steps: Un entero >0 `int`, el número de pasos de entrenamiento
        batch_size: Tamaño del lote
        hidden_units:Lista de valores que nos dice el número de neuronas de cada capa.
        training_examples: Un `DataFrame` que contiene una o más columnas de
          `california_housing_dataframe` para usar como funciones de entrada para el entrenamiento
        training_targets: Un `DataFrame` que contiene una columna 
          `california_housing_dataframe` Lo utilizamos como objetivo de entrenamiento
        validation_examples: Un `DataFrame` que contiene una o más columnas de
          `california_housing_dataframe`  para usar como funciones de entrada para la validación
        validation_targets:Un `DataFrame` que contiene una columna  de
          `california_housing_dataframe` para usar como objetivo de validación
          
      Returns:
        A `DNNRegressor` Objeto entrenado en los datos de entrenamiento.
      """

      periods = 10
      steps_per_period = steps / periods
      
      # Create a DNNRegressor object.
      my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)
      dnn_regressor = tf.estimator.DNNRegressor(
          feature_columns=construct_feature_columns(training_examples),
          hidden_units=hidden_units,
          optimizer=my_optimizer
      )
      
      # Create input functions.
      training_input_fn = lambda: my_input_fn(training_examples, 
                                              training_targets["median_house_value"], 
                                              batch_size=batch_size)
      predict_training_input_fn = lambda: my_input_fn(training_examples, 
                                                      training_targets["median_house_value"], 
                                                      num_epochs=1, 
                                                      shuffle=False)
      predict_validation_input_fn = lambda: my_input_fn(validation_examples, 
                                                        validation_targets["median_house_value"], 
                                                        num_epochs=1, 
                                                        shuffle=False)

      # Train the model, but do so inside a loop so that we can periodically assess
      # loss metrics.
      print("Training model...")
      print("RMSE (on training data):")
      training_rmse = []
      validation_rmse = []
      for period in range (0, periods):
        # Train the model, starting from the prior state.
        dnn_regressor.train(
            input_fn=training_input_fn,
            steps=steps_per_period
        )
        # Take a break and compute predictions.
        training_predictions = dnn_regressor.predict(input_fn=predict_training_input_fn)
        training_predictions = np.array([item['predictions'][0] for item in training_predictions])
        
        validation_predictions = dnn_regressor.predict(input_fn=predict_validation_input_fn)
        validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])
        
        # Compute training and validation loss.
        training_root_mean_squared_error = math.sqrt(
            metrics.mean_squared_error(training_predictions, training_targets))
        validation_root_mean_squared_error = math.sqrt(
            metrics.mean_squared_error(validation_predictions, validation_targets))
        # Occasionally print the current loss.
        print("  period %02d : %0.2f" % (period, training_root_mean_squared_error))
        # Add the loss metrics from this period to our list.
        training_rmse.append(training_root_mean_squared_error)
        validation_rmse.append(validation_root_mean_squared_error)
      print("Model training finished.")

      # Output a graph of loss metrics over periods.
      plt.ylabel("RMSE")
      plt.xlabel("Periods")
      plt.title("Root Mean Squared Error vs. Periods")
      plt.tight_layout()
      plt.plot(training_rmse, label="training")
      plt.plot(validation_rmse, label="validation")
      plt.legend()

      print("Final RMSE (on training data):   %0.2f" % training_root_mean_squared_error)
      print("Final RMSE (on validation data): %0.2f" % validation_root_mean_squared_error)

      return dnn_regressor, training_rmse, validation_rmse

    _ = train_nn_regression_model(
        my_optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.0007),
        steps=5000,
        batch_size=70,
        hidden_units=[10, 10],
        training_examples=training_examples,
        training_targets=training_targets,
        validation_examples=validation_examples,
        validation_targets=validation_targets)

    #Escalado lineal.Puede ser una buena práctica normal normalizar las entradas para que se #encuentren #dentro del rango -1, 1. 
    #Esto ayuda a que el SGD no se atasque al tomar pasos que son demasiado grandes en una #dimensión #o demasiado pequeños en otra. 

    def linear_scale(series):
      min_val = series.min()
      max_val = series.max()
      scale = (max_val - min_val) / 2.0
      return series.apply(lambda x:((x - min_val) / scale) - 1.0)

    #Tarea 1: Normalizar las características mediante el escalado lineal Normaliza las entradas a la #-1, 1.

    def normalize_linear_scale(examples_dataframe):
      """Devuelve una versión de la entrada `DataFrame` que tiene todas sus características normalizadas linealmente."""
      
      processed_features = pd.DataFrame()
      processed_features["latitude"] = linear_scale(examples_dataframe["latitude"])
      processed_features["longitude"] = linear_scale(examples_dataframe["longitude"])
      processed_features["housing_median_age"] = linear_scale(examples_dataframe["housing_median_age"])
      processed_features["total_rooms"] = linear_scale(examples_dataframe["total_rooms"])
      processed_features["total_bedrooms"] = linear_scale(examples_dataframe["total_bedrooms"])
      processed_features["population"] = linear_scale(examples_dataframe["population"])
      processed_features["households"] = linear_scale(examples_dataframe["households"])
      processed_features["median_income"] = linear_scale(examples_dataframe["median_income"])
      processed_features["rooms_per_person"] = linear_scale(examples_dataframe["rooms_per_person"])
      return processed_features

    normalized_dataframe = normalize_linear_scale(preprocess_features(california_housing_dataframe))
    normalized_training_examples = normalized_dataframe.head(12000)
    normalized_validation_examples = normalized_dataframe.tail(5000)

    _ = train_nn_regression_model(
        my_optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.005),
        steps=2000,
        batch_size=50,
        hidden_units=[10, 10],
        training_examples=normalized_training_examples,
        training_targets=training_targets,
        validation_examples=normalized_validation_examples,
        validation_targets=validation_targets)

    #Tarea 2: Probar un optimizador diferente
    """Utilice los optimizadores de Adagrad y Adam y compare el rendimiento.
    El optimizador de Adagrad funciona muy bien para problemas convexos, pero no siempre es ideal para el entrenamiento no neuronal
    con problemas no convexos.
    Para problemas de optimización no convexos, Adam es a veces más eficiente que Adagrad. 
    Para usar a Adam, invoca el método tf.train.AdamOptimizer."""

    #Adagrad
    _, adagrad_training_losses, adagrad_validation_losses = train_nn_regression_model(
        my_optimizer=tf.train.AdagradOptimizer(learning_rate=0.5),
        steps=500,
        batch_size=100,
        hidden_units=[10, 10],
        training_examples=normalized_training_examples,
        training_targets=training_targets,
        validation_examples=normalized_validation_examples,
        validation_targets=validation_targets)
    #Adam
    _, adam_training_losses, adam_validation_losses = train_nn_regression_model(
        my_optimizer=tf.train.AdamOptimizer(learning_rate=0.009),
        steps=500,
        batch_size=100,
        hidden_units=[10, 10],
        training_examples=normalized_training_examples,
        training_targets=training_targets,
        validation_examples=normalized_validation_examples,
        validation_targets=validation_targets)


    plt.ylabel("RMSE")
    plt.xlabel("Periods")
    plt.title("Root Mean Squared Error vs. Periods")
    plt.plot(adagrad_training_losses, label='Adagrad training')
    plt.plot(adagrad_validation_losses, label='Adagrad validation')
    plt.plot(adam_training_losses, label='Adam training')
    plt.plot(adam_validation_losses, label='Adam validation')
    _ = plt.legend()

    #Tarea 3: Explorar métodos alternativos de normalización
    #Pruebe las normalizaciones alternativas para varias características para mejorar aún más el #rendimiento.
    #Si observa detenidamente las estadísticas de resumen de sus datos transformados, puede #observar que la escala lineal 
    #de algunas características las deja agrupadas cerca de -1.
    #Podríamos hacerlo mejor al elegir formas adicionales de transformar estas características.

    def log_normalize(series):
      return series.apply(lambda x:math.log(x+1.0))

    def clip(series, clip_to_min, clip_to_max):
      return series.apply(lambda x:(
        min(max(x, clip_to_min), clip_to_max)))

    def z_score_normalize(series):
      mean = series.mean()
      std_dv = series.std()
      return series.apply(lambda x:(x - mean) / std_dv)

    def binary_threshold(series, threshold):
      return series.apply(lambda x:(1 if x > threshold else 0))


    """
    Estas son solo algunas de las maneras en que podríamos pensar en los datos. 
    Los hogares, median_income y total_bedrooms aparecen distribuidos normalmente en un espacio de registro.

    La latitud, la longitud y la vivienda_median_age probablemente son mejores simplemente escaladas linealmente, como antes.
    La población, las habitaciones totales y las habitaciones_per_personas tienen algunos valores muy altos . 
    Parecen demasiado extremos para que la normalización de registros ayude. Los acortamos."""
    def normalize(examples_dataframe):
      """Returns a version of the input `DataFrame` that has all its features normalized."""
      processed_features = pd.DataFrame()

      processed_features["households"] = log_normalize(examples_dataframe["households"])
      processed_features["median_income"] = log_normalize(examples_dataframe["median_income"])
      processed_features["total_bedrooms"] = log_normalize(examples_dataframe["total_bedrooms"])
      
      processed_features["latitude"] = linear_scale(examples_dataframe["latitude"])
      processed_features["longitude"] = linear_scale(examples_dataframe["longitude"])
      processed_features["housing_median_age"] = linear_scale(examples_dataframe["housing_median_age"])

      processed_features["population"] = linear_scale(clip(examples_dataframe["population"], 0, 5000))
      processed_features["rooms_per_person"] = linear_scale(clip(examples_dataframe["rooms_per_person"], 0, 5))
      processed_features["total_rooms"] = linear_scale(clip(examples_dataframe["total_rooms"], 0, 10000))

      return processed_features

    normalized_dataframe = normalize(preprocess_features(california_housing_dataframe))
    normalized_training_examples = normalized_dataframe.head(12000)
    normalized_validation_examples = normalized_dataframe.tail(5000)

    _ = train_nn_regression_model(
        my_optimizer=tf.train.AdagradOptimizer(learning_rate=0.15),
        steps=1000,
        batch_size=50,
        hidden_units=[10, 10],
        training_examples=normalized_training_examples,
        training_targets=training_targets,
        validation_examples=normalized_validation_examples,
        validation_targets=validation_targets)

    Curso Tensorflow con Anaconda -15 Introducción a las redes neuronales

    15 Introducción a las redes neuronales

    • En este capítulo veremos una introducción a las redes neuronales. Las redes neuronales son una versión mucho más sofisticada de las combinaciones de atributos. Básicamente, las redes neuronales aprenden las combinaciones de atributos correspondientes que necesitas.
    • Supongamos que nos encontramos con un problema de clasificación no lineal, es decir no se puede predecir con exactitud una etiqueta con un modelo de forma b+w1x1+w2x2. Es decir, la "superficie de decisión" no es una línea. 
    • En el siguiente vídeo os cuento todo esto y además veremos un ejemplo de código:

    • Os dejo el código visto en el vídeo:
    from __future__ import print_function

    import math

    from IPython import display
    from matplotlib import cm
    from matplotlib import gridspec
    from matplotlib import pyplot as plt
    import numpy as np
    import pandas as pd
    from sklearn import metrics
    import tensorflow as tf
    from tensorflow.python.data import Dataset

    tf.logging.set_verbosity(tf.logging.ERROR)
    pd.options.display.max_rows = 10
    pd.options.display.float_format = '{:.1f}'.format

    california_housing_dataframe=pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv", sep=",")

    california_housing_dataframe = california_housing_dataframe.reindex(
        np.random.permutation(california_housing_dataframe.index))
    def preprocess_features(california_housing_dataframe):
      """Prepares input features from California housing data set.

      Args:
        california_housing_dataframe: A Pandas DataFrame expected to contain data
          from the California housing data set.
      Returns:
        A DataFrame that contains the features to be used for the model, including
        synthetic features.
      """
      selected_features = california_housing_dataframe[
        ["latitude",
         "longitude",
         "housing_median_age",
         "total_rooms",
         "total_bedrooms",
         "population",
         "households",
         "median_income"]]
      processed_features = selected_features.copy()
      # Create a synthetic feature.
      processed_features["rooms_per_person"] = (
        california_housing_dataframe["total_rooms"] /
        california_housing_dataframe["population"])
      return processed_features

    def preprocess_targets(california_housing_dataframe):
      """Prepares target features (i.e., labels) from California housing data set.

      Args:
        california_housing_dataframe: A Pandas DataFrame expected to contain data
          from the California housing data set.
      Returns:
        A DataFrame that contains the target feature.
      """
      output_targets = pd.DataFrame()
      # Scale the target to be in units of thousands of dollars.
      output_targets["median_house_value"] = (
        california_housing_dataframe["median_house_value"] / 1000.0)
      return output_targets
      
    # Choose the first 12000 (out of 17000) examples for training.
    training_examples = preprocess_features(california_housing_dataframe.head(12000))
    training_targets = preprocess_targets(california_housing_dataframe.head(12000))

    # Choose the last 5000 (out of 17000) examples for validation.
    validation_examples = preprocess_features(california_housing_dataframe.tail(5000))
    validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))

    # Double-check that we've done the right thing.
    print("Training examples summary:")
    display.display(training_examples.describe())
    print("Validation examples summary:")
    display.display(validation_examples.describe())

    print("Training targets summary:")
    display.display(training_targets.describe())
    print("Validation targets summary:")
    display.display(validation_targets.describe())

    def construct_feature_columns(input_features):
      """Construct the TensorFlow Feature Columns.

      Args:
        input_features: The names of the numerical input features to use.
      Returns:
        A set of feature columns
      """ 
      return set([tf.feature_column.numeric_column(my_feature)
                  for my_feature in input_features])

    def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):
        """Trains a neural net regression model.
      
        Args:
          features: pandas DataFrame of features
          targets: pandas DataFrame of targets
          batch_size: Size of batches to be passed to the model
          shuffle: True or False. Whether to shuffle the data.
          num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely
        Returns:
          Tuple of (features, labels) for next data batch
        """
        
        # Convert pandas data into a dict of np arrays.
        features = {key:np.array(value) for key,value in dict(features).items()}                                             
        # Construct a dataset, and configure batching/repeating.
        ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit
        ds = ds.batch(batch_size).repeat(num_epochs)
        

        if shuffle:
          ds = ds.shuffle(10000)
        
        # Return the next batch of data.
        features, labels = ds.make_one_shot_iterator().get_next()
        return features, labels
     def train_nn_regression_model(
        learning_rate,
        steps,
        batch_size,
        hidden_units,
        training_examples,
        training_targets,
        validation_examples,
        validation_targets):
      """Trains a neural network regression model.
      
      In addition to training, this function also prints training progress information,
      as well as a plot of the training and validation loss over time.
      
      Args:
        learning_rate: A `float`, the learning rate.
        steps: A non-zero `int`, the total number of training steps. A training step
          consists of a forward and backward pass using a single batch.
        batch_size: A non-zero `int`, the batch size.
        hidden_units: A `list` of int values, specifying the number of neurons in each layer.
        training_examples: A `DataFrame` containing one or more columns from
          `california_housing_dataframe` to use as input features for training.
        training_targets: A `DataFrame` containing exactly one column from
          `california_housing_dataframe` to use as target for training.
        validation_examples: A `DataFrame` containing one or more columns from
          `california_housing_dataframe` to use as input features for validation.
        validation_targets: A `DataFrame` containing exactly one column from
          `california_housing_dataframe` to use as target for validation.
          
      Returns:
        A `DNNRegressor` object trained on the training data.
      """

      periods = 10
      steps_per_period = steps / periods
      
      # Create a DNNRegressor object.
      my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
      my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)
      dnn_regressor = tf.estimator.DNNRegressor(
          feature_columns=construct_feature_columns(training_examples),
          hidden_units=hidden_units,
          optimizer=my_optimizer,
      )
      
      # Create input functions.
      training_input_fn = lambda: my_input_fn(training_examples, 
                                              training_targets["median_house_value"], 
                                              batch_size=batch_size)
      predict_training_input_fn = lambda: my_input_fn(training_examples, 
                                                      training_targets["median_house_value"], 
                                                      num_epochs=1, 
                                                      shuffle=False)
      predict_validation_input_fn = lambda: my_input_fn(validation_examples, 
                                                        validation_targets["median_house_value"], 
                                                        num_epochs=1, 
                                                        shuffle=False)

      # Train the model, but do so inside a loop so that we can periodically assess
      # loss metrics.
      print("Training model...")
      print("RMSE (on training data):")
      training_rmse = []
      validation_rmse = []
      for period in range (0, periods):
        # Train the model, starting from the prior state.
        dnn_regressor.train(
            input_fn=training_input_fn,
            steps=steps_per_period
        )
        # Take a break and compute predictions.
        training_predictions = dnn_regressor.predict(input_fn=predict_training_input_fn)
        training_predictions = np.array([item['predictions'][0] for item in training_predictions])
        
        validation_predictions = dnn_regressor.predict(input_fn=predict_validation_input_fn)
        validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])
        
        # Compute training and validation loss.
        training_root_mean_squared_error = math.sqrt(
            metrics.mean_squared_error(training_predictions, training_targets))
        validation_root_mean_squared_error = math.sqrt(
            metrics.mean_squared_error(validation_predictions, validation_targets))
        # Occasionally print the current loss.
        print("  period %02d : %0.2f" % (period, training_root_mean_squared_error))
        # Add the loss metrics from this period to our list.
        training_rmse.append(training_root_mean_squared_error)
        validation_rmse.append(validation_root_mean_squared_error)
      print("Model training finished.")

      # Output a graph of loss metrics over periods.
      plt.ylabel("RMSE")
      plt.xlabel("Periods")
      plt.title("Root Mean Squared Error vs. Periods")
      plt.tight_layout()
      plt.plot(training_rmse, label="training")
      plt.plot(validation_rmse, label="validation")
      plt.legend()

      print("Final RMSE (on training data):   %0.2f" % training_root_mean_squared_error)
      print("Final RMSE (on validation data): %0.2f" % validation_root_mean_squared_error)

      return dnn_regressor
      
     dnn_regressor = train_nn_regression_model(
        learning_rate=0.001,
        steps=2000,
        batch_size=100,
        hidden_units=[3, 10],
        training_examples=training_examples,
        training_targets=training_targets,
        validation_examples=validation_examples,
        validation_targets=validation_targets)
    california_housing_test_data = pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_test.csv", sep=",")

    test_examples = preprocess_features(california_housing_test_data)
    test_targets = preprocess_targets(california_housing_test_data)

    predict_testing_input_fn = lambda: my_input_fn(test_examples, 
                                                   test_targets["median_house_value"], 
                                                   num_epochs=1, 
                                                   shuffle=False)

    test_predictions = dnn_regressor.predict(input_fn=predict_testing_input_fn)
    test_predictions = np.array([item['predictions'][0] for item in test_predictions])

    root_mean_squared_error = math.sqrt(
        metrics.mean_squared_error(test_predictions, test_targets))

    print("Final RMSE (on test data): %0.2f" % root_mean_squared_error)

    Curso .NET Core en C# - 34.Creamos nuestro propio log

    34.Creamos nuestro propio log Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de  ASP.NET...