18 Incorporaciones
- 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
- 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("---")
No hay comentarios:
Publicar un comentario