<jupyter_start><jupyter_text>Introduccion a TensorFlowComo cuando uno esta aprendiendo algo, lo que siempre ansiamos es poder hacer algo practico, asi que como introduccion vamos a resolver un ejercisio basico, con algo simple solamente para poder dimensionar como son las implementaciones de machine learning de una forma muy basica, para luego poder profundisar mas.Aca les dejo un enlace a algo de teoria, para que puedan leerlo, esta sacada de el curso de google de tensoflow, pero lo quiero ir perfeccionando un poco mas:[Indice Documentacion](Teoric/000_Indice.ipynb)  Ej: Tensorflow 00Este ejercicio esta pensado para poder asistir en el aprendisaje basico de [Deep Learning](https://es.wikipedia.org/wiki/Aprendizaje_profundo) usando redes neuronales implementadas con Tensorflow y Keras.  Problema a resolverEl caso que vamos a utilizar para aprender es el siguiente:  DescripcionEstamos en una base en la antartida trabajando con un grupo de centificos que estudian como impacta la vaciacion de la temperatura del hambiente en el comportamiento reproductivo de los pinguinos, para esto se disponen de dos equipos de medicion instalados que tenems que instalar en dos zonas distintas, pero el problema es que una mide en Fahrenheit mientras que la otra en grados Celsius.Necesitamos implementar un script que permita convertir de un sistema al otro, pero lamentablemente no tenemos internet ni forma de obtener la formular, y nadie se acuerda como hacerla.  La solucionPara ello pusimos a medir los 2 equipos la misma temperatura con lo que obtuvimos 2 listas que se correlacionan con ambas temperaturas y tenemos que entrenar una red neuronal para que haga la conversion de datos. --- 1. Imporatemos las libreriasImportamos las librerias necesarias en este caso son:*   TensorFlow: Framework que permite crear redes neuronales, entrenarlas y ejeutarlas*   Numpy: Libreria de python para matematicas. pensadas para el uso de vectores, marices, entre muchas cosa mas<jupyter_code>from __future__ import absolute_import, division, print_function
import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)

import numpy as np<jupyter_output><empty_output><jupyter_text>--- 2. Cargar y preparar el dataset Simulamos los valores de las mediciones por medio de las siguientes lineas de codigosdonde **```values_Q```** va a ser un array con 1000 medicones en grados Celsius. y **```values_A```** van a ser las medicones correlacionadas en grados Fahrenheit<jupyter_code>values_Q = np.random.randint(100, size=1000)
values_A = np.array(list(map(lambda x: (x* 1.8 + 32) , values_Q)))<jupyter_output><empty_output><jupyter_text>--- 3. Procesar y analizar los datos de entrenamientoAnalizamos la estructura de los array que tenes de entra y de salida para poder armar la red, para ello usamos el atributo **shape** de los numpy arraycomo podemos observar en este caso ambos tiene una estrucutra de 1000 elementos de un dimension 1 cada elemento<jupyter_code>values_Q.shape
values_A.shape<jupyter_output><empty_output><jupyter_text>--- 4. Crear el modelo (La red neuronal)Generamos un objeto **model** que va a a ser nuestro modelo de redes neutornales  para ello utilizamos la sigueinte linea de codigo usando el metodo **Sequential** de Tensorflow pasandole como parametro un array donde cada elemento del array es una capa, en este caso usamos capas [densas](http://www.deeplearningessentials.science/denseNetwork/) (Unod de los tipos de capaz que se utilizan para implementar redes neuronales)```model = tf.keras.Sequential()```Al momento de armar la red neuronal tenemos que tener muy en cuenta la estructura de los datos de entrada y salida en este caso tenemos que las entradas van a ser a ser de 1 solo valor (la temperatura en grados celsius) y 1 solo valor de salida que va a ser la la temperatura en grados Fahrenheit. Por ende sabemos que la imput layer tiene que recivir 1 elemento y la output layer tiene que devolver 1 elemento1. Por esto vamos a definir una capa densa que reciva un array de dimension una usando el parametro **input_shape=[1]**, y vamos a decir que esta capa tiene una sola neurona usando el parametro **unit=1**  ```tf.keras.layers.Dense(units=1, input_shape=[1])```Luego la definicion de la red queda como se ve a continuacion*Nota: Despues de haber leido todo el notebook, animense a modificar la red, agreguenle capas saquenle, cambien la cantidad de neuronas, etc. y vean como se comporta con los cambios*<jupyter_code>model = tf.keras.Sequential([
  tf.keras.layers.Dense(units=1, input_shape=[1]),
])<jupyter_output><empty_output><jupyter_text>Un cambio interesante que se puede hacer para optimizar el modelo es cambiarla la [funcion de activacion](https://towardsdatascience.com/activation-functions-neural-networks-1cbd9f8d91d6) para que use la funcion relu, para esto  usamos el parametro activation=tf.nn.relu. a contianuacion les dejo el codigo para que luego lo prueben y vean como se optimiza.```model = tf.keras.Sequential([    tf.keras.layers.Dense(units=1, activation=tf.nn.relu, input_shape=[1]),])```*Nota: relu es solo una de varias funciones de activacion que existen. usar una u otra depende de la naturaleza del caso* --- 5. Compilar el modeloUna vez definida la red tenemos que compilarla esto va a validar que todo lo que hicimos esta bien y va a generar internamente lass estructuras necesarias para poder tener disponible la red lista para entrenar, en este caso vamos a usar la funcion de optimizacion Adam con el parametro **optimizer=tf.keras.optimizers.Adam(0.1)** y el metodo **loss=mean_squared_error** - **Loss function**: Una forma de medir qué tan lejos están las predicciones del resultado deseado.- **Optimizer function**: Una forma de ajustar los valores internos para reducir la pérdida.<jupyter_code>model.compile(loss='mean_squared_error',
              optimizer=tf.keras.optimizers.Adam(0.1))<jupyter_output><empty_output><jupyter_text>--- 6. Entrenar el modeloUna vez creada nuestra red, netemos que entrenarla para ello usamos el metodo **fit** del modelso pasandole como primer parametro el array de entrada **value_Q**, como segundo parametro el array de salida **values_A**, la cantidad de  30 ciclos de entrenamiento usando el parametro **epochs=30** y en este caso le vamos a pedir tener una salida para ir viendo como va el entrenamiento<jupyter_code>history = model.fit(values_Q, values_A, epochs=30, verbose=1)<jupyter_output><empty_output><jupyter_text>--- 7. Analizar los resultados del entrenamientoEste paso no es necesario pero vamos a usar matplotlib para graficar el loss del modelso durante el entrenamiento en relacion a los ciclos de entrenamientos*Nota: En este caso si los resultados no son satisfactorios volvermos a analizar los datos, re formularo la red y volvermos a entrenarla*<jupyter_code>%matplotlib inline
import matplotlib.pyplot as plt
plt.xlabel('Epoch Number')
plt.ylabel("Loss Magnitude")
plt.plot(history.history['loss'])<jupyter_output><empty_output><jupyter_text>--- 8. Predecir los datos Una vez tenemos el  modelos entrenado podemos proceder a hacer predicciones por medio del metodo **predict** del modelo.Tenganen cuenta que el modelo recive array entonces como parametro si queremos convertir 32 grados celsius no le pasamos el **32** como parametro sino que un array con el 32 seria asi **[32]**```model.predict([32])```<jupyter_code>model.predict([32])<jupyter_output><empty_output><jupyter_text>--- 9. Juguemos con el modelo...Por utlimo y solo para probar el modelso vamos a simular datos y correr el modelso para ver que tanto error tiene en 10 predicciones<jupyter_code>for y in np.random.randint(100, size=10):
  y = int(y)
  value_q = np.array([y], dtype="float32")
  prediction = model.predict(value_q)
  print("Prediccion: {0:0>6.2f}, Valor_real: {1:0>6.2f}, Error: {2:0>6.2f}".format(
      prediction[0][0], (y* 1.8 + 32), abs(prediction[0][0] - (y* 1.8 + 32)))
  )<jupyter_output><empty_output><jupyter_text>--- ConclusionComo pueden ver este modelo resuelve lo necesario pero no tiene resultados excelentes, ya que presenta un error, prueben volver a repetir desde el [paso 6](6.-Entrenar-el-modelo) en adelante y vean como va mejorando a medida que se entrena mas, con 2 veces anda bien.Por otro lado prueben con la optimizacion que esta sugerida en el [paso 4](4.-Crear-el-modelo-(La-red-neuronal)), para ver como con menos enntrenamiento obtiene mejores resultados. --- EjercicioVos todos los dias vas a comer al buffer de la empresa que venden solo 3 productos (Hamburguesa, Papas Fritas y Gaseosa). Al llegar te toman el pedido y directamente te dan el monto total de la compra.Luego de varios dias, te pones a pensar cuanto costara cada producto y solo tenes los ticket que tiene la cantidad de cada producto y el monto total de la compra.Para poder averiguar el monto total de la compra tenes que entrenar un modelos capaz de recibir las cantidades de los 3 productos y que te devuelva el valor total de la compra. con este modelso podes averiguar el monto unitario de cada producto.**Te animas a hacerlo?** Datos de los ticket<jupyter_code>pedidos = [
    [4, 4, 0], [1, 1, 0], [3, 0, 1], [1, 2, 1], [3, 2, 4], [3, 0, 1], [2, 4, 3],
    [3, 0, 1], [3, 2, 4], [0, 1, 1], [3, 0, 2], [4, 4, 0], [1, 3, 1], [4, 1, 0],
    [2, 2, 1], [2, 4, 3], [0, 2, 1], [1, 2, 2], [3, 1, 4], [2, 4, 2], [4, 2, 3],
    [4, 3, 0], [4, 4, 1], [3, 1, 4], [1, 3, 1], [1, 1, 4], [1, 0, 3], [1, 1, 3],
    [2, 1, 4], [3, 2, 3], [4, 3, 4], [3, 4, 2], [2, 3, 2], [3, 1, 0], [2, 3, 3],
    [2, 2, 2], [1, 3, 1]
]
totales = [
    80., 20., 48., 28., 67., 48., 59., 48., 67., 8., 51., 80., 33., 65.,
    43., 59., 13., 31., 62., 56., 79., 75., 83., 62., 33., 32., 24., 29.,
    47., 64., 87., 71., 51., 50., 54., 46., 33.
]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09024864422388212, 'fraction_numerical': 0.030901463214980048, 'mean_word_length': 4.856201318154584, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 44, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '375675', 'license': 'MIT', 'n_tokens_mistral': 3480, 'n_tokens_neox': 3214, 'n_words': 1364, 'path': 'notebooks/02_Machine_Learning/00_Introduccion_tensorflow_y_keras.ipynb', 'repo_name': 'ElDwarf/DS_and_ML_Docs', 'size': '9773'}