Pop

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)

No hay comentarios:

Publicar un comentario

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...