10. Ejemplo entrenamiento y validación(2)
- Hola a todos.Vamos continuar con nuestro curso dedicado al aprendizaje automático.Para ello nos basaremos en un curso de google dedicado a este tema. En este enlace tenéis el curso al completo en castellano: https://developers.google.com/machine-learning/crash-course/ml-intro?hl=es
- En el vídeo anterior empezamos con un ejemplo de código donde veíamos las diferentes formas de entrenar un modelo.En esta entrada vamos a continuar con nuestro ejemplo. Acabaremos las dos tareas pendientes que nos quedaron en el capítulo anterior:
- Entrenar y evaluar un modelo
- Evaluar en los datos de prueba
- Os dejo el vídeo donde acabo nuestro ejemplo y os lo explico en profundidad:
- Como siempre os dejo el código visto en el vídeo:
#Vamos a trabajar con múltiples funciones, así que modularizaremos la lógica para #preprocesarlas funciones
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 que tendrá los datos de vivienda
Returns:
Un DataFrame que contiene las características que se utilizarán para el modelo.
"""
selected_features = california_housing_dataframe[
["latitude",
"longitude",
"housing_median_age",
"total_rooms",
"total_bedrooms",
"population",
"households",
"median_income"]]
processed_features = selected_features.copy()
# Crea una 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 (etiquetas) a partir del conjunto de datos de viviendas de California.
Args:
california_housing_dataframe: Contenedor que tendrá los datos de vivienda
Returns:
Un DataFrame que contiene la característica de destino.
"""
output_targets = pd.DataFrame()
# Ponemos el objetivo (target) en miles de dolares
output_targets["median_house_value"] = (
california_housing_dataframe["median_house_value"] / 1000.0)
return output_targets
#Para el conjunto de entrenamiento, elegiremos los primeros 12000 ejemplos, de un total de #17000.
training_examples = preprocess_features(california_housing_dataframe.head(12000))
training_examples.describe()
training_targets = preprocess_targets(california_housing_dataframe.head(12000))
training_targets.describe()
#Para el conjunto de validación, elegiremos los últimos 5000 ejemplos, de un total de 17000.
validation_examples = preprocess_features(california_housing_dataframe.tail(5000))
validation_examples.describe()
validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))
validation_targets.describe()
plt.figure(figsize=(13, 8))
ax = plt.subplot(1, 2, 1)
ax.set_title("Conjunto datos validación")
ax.set_autoscaley_on(False)
ax.set_ylim([32, 43])
ax.set_autoscalex_on(False)
ax.set_xlim([-126, -112])
plt.scatter(validation_examples["longitude"],
validation_examples["latitude"],
cmap="coolwarm",
c=validation_targets["median_house_value"] / validation_targets["median_house_value"].max())
ax = plt.subplot(1,2,2)
ax.set_title("Conjunto datos entrenamiento")
ax.set_autoscaley_on(False)
ax.set_ylim([32, 43])
ax.set_autoscalex_on(False)
ax.set_xlim([-126, -112])
plt.scatter(training_examples["longitude"],
training_examples["latitude"],
cmap="coolwarm",
c=training_targets["median_house_value"] / training_targets["median_house_value"].max())
_ = plt.plot()
#función que utilizaremos para tratar los datos de entrada
def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):
"""Entrena un modelo de regresión lineal de una característica.
Parametros de entrada:
features: DataFrame de características
targets: DataFrame de objetivos
batch_size: Tamaño de los lotes a pasar al modelo.
shuffle: Verdadero o falso mezclar los datos
num_epochs:Número de iteracciones. None = se repite infinitamanete
Returns:
Tupla de (características, etiquetas) para el siguiente lote de datos
"""
# Convertimos en un dict de arrays numpy.
features = {key:np.array(value) for key,value in dict(features).items()}
# Lo colocamos como un objeto Dataset de tensorflow,damos un tamaño a cada lote y #asignamos el numero de iteraciones
ds = Dataset.from_tensor_slices((features,targets))
ds = ds.batch(batch_size).repeat(num_epochs)
if shuffle:
ds = ds.shuffle(buffer_size=10000)
# Devolevemos el nuevo lote datos
features, labels = ds.make_one_shot_iterator().get_next()
return features, labels
def construct_feature_columns(input_features):
"""Construye 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 train_model(
learning_rate,
steps,
batch_size,
training_examples,
training_targets,
validation_examples,
validation_targets):
"""Entrena un modelo de regresión lineal de múltiples características.
Además del entrenamiento, esta función también imprime información sobre el progreso del entrenamiento,
así como una gráfica de la pérdida de entrenamiento y validación a lo largo del tiempo.
Args:
learning_rate: Float con la tasa de aprendizaje
steps:Un int distinto de cero.Es el número total de pasos de entrenamiento. Un paso de entrenamiento
consiste en un pase hacia adelante y hacia atrás usando un solo lote.
batch_size: Un int distinto de cero con el tamaño del lote
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 exactamente una columna de
`california_housing_dataframe` para usar como objetivo para la capacitación.
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 exactamente una columna de
`california_housing_dataframe` para usar como destino para la validación.
Returns:
Un objeto `LinearRegressor` entrenado en los datos de entrenamiento.
"""
periods = 10
steps_per_period = steps / periods
# Creamos objeto linear_regressor
my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)
linear_regressor = tf.estimator.LinearRegressor(
feature_columns=construct_feature_columns(training_examples),
optimizer=my_optimizer
)
# Creamos funcion de entrada
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)
# Entrenamos al modelo dentro de un bucle
print("Entranando al modelo...")
print("Error cuadrático medio en los datos de entrenammiento:")
training_rmse = []
validation_rmse = []
for period in range (0, periods):
# Entrena el modelo, partiendo del estado anterior.
linear_regressor.train(
input_fn=training_input_fn,
steps=steps_per_period,
)
#calculamos las predicciones.
training_predictions = linear_regressor.predict(input_fn=predict_training_input_fn)
training_predictions = np.array([item['predictions'][0] for item in training_predictions])
validation_predictions = linear_regressor.predict(input_fn=predict_validation_input_fn)
validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])
# Calcular la pérdida de entrenamiento y validación.
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))
# Mostramos perdida actual
print(" periodo %02d : %0.2f" % (period, training_root_mean_squared_error))
#Agrega las métricas de pérdida de este período a nuestra lista.
training_rmse.append(training_root_mean_squared_error)
validation_rmse.append(validation_root_mean_squared_error)
print("Entrenamiento del modelo finalizado.")
plt.ylabel("Error cuadrático medio")
plt.xlabel("Periodos")
plt.title("Error cuadrático medio vs. Periodos")
plt.tight_layout()
plt.plot(training_rmse, label="training")
plt.plot(validation_rmse, label="validation")
plt.legend()
return linear_regressor
linear_regressor = train_model(
learning_rate=0.00003,
steps=500,
batch_size=5,
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_test_input_fn = lambda: my_input_fn(
test_examples,
test_targets["median_house_value"],
num_epochs=1,
shuffle=False)
test_predictions = linear_regressor.predict(input_fn=predict_test_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("Error cuadrático medio final en los datos de test: %0.2f" % root_mean_squared_error)
No hay comentarios:
Publicar un comentario